searchConfigForm = (tables, views, req) => {
  let fields = [];
  let tbls_noviews = [];
  for (const t of tables) {
    const ok_views = views.filter(
      (v) =>
        v.table_id === t.id && v.viewtemplateObj && v.viewtemplateObj.runMany
    );
    if (ok_views.length === 0) tbls_noviews.push(t.name);
    else
      fields.push({
        name: t.name,
        label: req.__("Result preview for ") + t.name,
        required: false,
        type: "String",
        attributes: { options: ok_views.map((v) => v.name).join() },
      });
  }
  fields.push({
    name: "search_table_description",
    label: req.__("Description header"),
    sublabel: req.__("Use table description instead of name as header"),
    type: "Bool",
  });
  fields.push({
    name: "search_results_decoration",
    label: req.__("Show results in"),
    sublabel: req.__("Show results from each table in this type of element"),
    input_type: "select",
    options: ["Cards", "Tabs"],
  });
  const blurb1 = req.__(
    `Choose views for <a href="/search">search results</a> for each table.<br/>Set to blank to omit table from global search.`
  );
  return new Form({
    action: "/search/config",
    noSubmitButton: true,
    onChange: `saveAndContinue(this)`,
    blurb:
      blurb1 +
      (tbls_noviews.length > 0
        ? `<br/><br/>${req.__(
            "These tables lack suitable views: "
          )}${tbls_noviews.join(", ")}.`
        : ""),
    fields,
  });
}
Search Configuration form
@param {object[]} tables
@param {object[]} views
@param {object} req
@returns {Forms}