From 1c5b55120600965c720d116a9570d0d154616893 Mon Sep 17 00:00:00 2001 From: jingrow Date: Sat, 24 Jan 2026 04:26:58 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0form=5Fbuilder=E5=8F=B3?= =?UTF-8?q?=E8=BE=B9=E6=A0=8F=E7=BC=BA=E5=B0=91=E7=9A=84=E5=B1=9E=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/core/features/form_builder/store.js | 108 +++++++++++++----- .../src/core/features/form_builder/utils.js | 2 + 2 files changed, 80 insertions(+), 30 deletions(-) diff --git a/apps/jingrow/frontend/src/core/features/form_builder/store.js b/apps/jingrow/frontend/src/core/features/form_builder/store.js index b77c383..c2cf3a0 100644 --- a/apps/jingrow/frontend/src/core/features/form_builder/store.js +++ b/apps/jingrow/frontend/src/core/features/form_builder/store.js @@ -83,46 +83,94 @@ export const RESTRICTED_FIELDS = [ ]; // Default PageField properties for the properties panel +// Order follows jingrow's PageField.field_order export const DEFAULT_PAGEFIELD_PROPERTIES = [ + // Label and Type section { fieldname: "label", label: t("Label"), fieldtype: "Data" }, - { fieldname: "fieldname", label: t("Fieldname"), fieldtype: "Data", read_only: 1 }, { fieldname: "fieldtype", label: t("Field Type"), fieldtype: "Select", options: ALL_FIELDTYPES.join("\n") }, - { fieldname: "options", label: t("Options"), fieldtype: "Small Text" }, + { fieldname: "fieldname", label: t("Fieldname"), fieldtype: "Data" }, + { fieldname: "precision", label: t("Precision"), fieldtype: "Select", options: "\n0\n1\n2\n3\n4\n5\n6\n7\n8\n9", depends_on: "eval:in_list(['Float', 'Currency', 'Percent'], pg.fieldtype)" }, + { fieldname: "length", label: t("Length"), fieldtype: "Int", depends_on: "eval:in_list(['Data', 'Link', 'Dynamic Link', 'Password', 'Select', 'Read Only', 'Attach', 'Attach Image', 'Int'], pg.fieldtype)" }, + { fieldname: "non_negative", label: t("Non Negative"), fieldtype: "Check", depends_on: "eval:in_list(['Int', 'Float', 'Currency'], pg.fieldtype)" }, + { fieldname: "hide_days", label: t("Hide Days"), fieldtype: "Check", depends_on: "eval:pg.fieldtype=='Duration'" }, + { fieldname: "hide_seconds", label: t("Hide Seconds"), fieldtype: "Check", depends_on: "eval:pg.fieldtype=='Duration'" }, { fieldname: "reqd", label: t("Mandatory"), fieldtype: "Check" }, - { fieldname: "default", label: t("Default"), fieldtype: "Data" }, - { fieldname: "read_only", label: t("Read Only"), fieldtype: "Check" }, - { fieldname: "hidden", label: t("Hidden"), fieldtype: "Check" }, - { fieldname: "unique", label: t("Unique"), fieldtype: "Check" }, - { fieldname: "in_list_view", label: t("In List View"), fieldtype: "Check" }, - { fieldname: "in_standard_filter", label: t("In Standard Filter"), fieldtype: "Check" }, - { fieldname: "in_global_search", label: t("In Global Search"), fieldtype: "Check" }, - { fieldname: "bold", label: t("Bold"), fieldtype: "Check" }, - { fieldname: "collapsible", label: t("Collapsible"), fieldtype: "Check", depends_on: "eval:doc.fieldtype=='Section Break'" }, - { fieldname: "collapsible_depends_on", label: t("Collapsible Depends On"), fieldtype: "Data", depends_on: "eval:doc.collapsible" }, - { fieldname: "depends_on", label: t("Depends On"), fieldtype: "Data" }, - { fieldname: "mandatory_depends_on", label: t("Mandatory Depends On"), fieldtype: "Data" }, - { fieldname: "read_only_depends_on", label: t("Read Only Depends On"), fieldtype: "Data" }, - { fieldname: "description", label: t("Description"), fieldtype: "Small Text" }, - { fieldname: "allow_on_submit", label: t("Allow on Submit"), fieldtype: "Check" }, - { fieldname: "translatable", label: t("Translatable"), fieldtype: "Check" }, - { fieldname: "fetch_from", label: t("Fetch From"), fieldtype: "Data" }, + { fieldname: "is_virtual", label: t("Virtual"), fieldtype: "Check" }, + { fieldname: "search_index", label: t("Index"), fieldtype: "Check" }, + + // Column Break + { fieldname: "column_break_18", fieldtype: "Column Break" }, + + { fieldname: "options", label: t("Options"), fieldtype: "Small Text" }, + { fieldname: "sort_options", label: t("Sort Options"), fieldtype: "Check", depends_on: "eval:pg.fieldtype=='Select'" }, + { fieldname: "show_dashboard", label: t("Show Dashboard"), fieldtype: "Check", depends_on: "eval:pg.fieldtype=='Tab Break'" }, + { fieldname: "link_filters", label: t("Link Filters"), fieldtype: "Code", options: "JSON", depends_on: "eval:pg.fieldtype=='Link'" }, + + // Defaults Section + { fieldname: "defaults_section", fieldtype: "Section Break", label: t("Defaults") }, + { fieldname: "default", label: t("Default"), fieldtype: "Small Text" }, + { fieldname: "column_break_6", fieldtype: "Column Break" }, + { fieldname: "fetch_from", label: t("Fetch From"), fieldtype: "Small Text" }, { fieldname: "fetch_if_empty", label: t("Fetch If Empty"), fieldtype: "Check" }, - { fieldname: "ignore_user_permissions", label: t("Ignore User Permissions"), fieldtype: "Check" }, - { fieldname: "ignore_xss_filter", label: t("Ignore XSS Filter"), fieldtype: "Check" }, + + // Visibility Section + { fieldname: "visibility_section", fieldtype: "Section Break", label: t("Visibility") }, + { fieldname: "hidden", label: t("Hidden"), fieldtype: "Check" }, + { fieldname: "show_on_timeline", label: t("Show on Timeline"), fieldtype: "Check", depends_on: "eval:doc.hidden" }, + { fieldname: "bold", label: t("Bold"), fieldtype: "Check" }, + { fieldname: "allow_in_quick_entry", label: t("Allow in Quick Entry"), fieldtype: "Check" }, + { fieldname: "translatable", label: t("Translatable"), fieldtype: "Check", depends_on: "eval:['Data', 'Select', 'Text', 'Small Text', 'Text Editor'].includes(pg.fieldtype)" }, { fieldname: "print_hide", label: t("Print Hide"), fieldtype: "Check" }, - { fieldname: "print_hide_if_no_value", label: t("Print Hide If No Value"), fieldtype: "Check" }, + { fieldname: "print_hide_if_no_value", label: t("Print Hide If No Value"), fieldtype: "Check", depends_on: "eval:['Int', 'Float', 'Currency', 'Percent'].indexOf(pg.fieldtype)!==-1" }, { fieldname: "report_hide", label: t("Report Hide"), fieldtype: "Check" }, + { fieldname: "column_break_28", fieldtype: "Column Break" }, + { fieldname: "depends_on", label: t("Display Depends On (JS)"), fieldtype: "Code", options: "JS" }, + { fieldname: "collapsible", label: t("Collapsible"), fieldtype: "Check", depends_on: "eval:pg.fieldtype=='Section Break'" }, + { fieldname: "collapsible_depends_on", label: t("Collapsible Depends On (JS)"), fieldtype: "Code", options: "JS", depends_on: "eval:doc.collapsible" }, + { fieldname: "hide_border", label: t("Hide Border"), fieldtype: "Check", depends_on: "eval:pg.fieldtype=='Section Break'" }, + + // List / Search Settings Section + { fieldname: "list__search_settings_section", fieldtype: "Section Break", label: t("List / Search Settings") }, + { fieldname: "in_list_view", label: t("In List View"), fieldtype: "Check" }, + { fieldname: "in_standard_filter", label: t("In List Filter"), fieldtype: "Check" }, + { fieldname: "in_preview", label: t("In Preview"), fieldtype: "Check", depends_on: "eval:!in_list(['Table', 'Table MultiSelect'], pg.fieldtype)" }, + { fieldname: "column_break_35", fieldtype: "Column Break" }, + { fieldname: "in_filter", label: t("In Filter"), fieldtype: "Check" }, + { fieldname: "in_global_search", label: t("In Global Search"), fieldtype: "Check", depends_on: "eval:['Data', 'Select', 'Table', 'Text', 'Text Editor', 'Link', 'Small Text', 'Long Text', 'Read Only', 'Heading', 'Dynamic Link'].indexOf(pg.fieldtype)!==-1" }, + + // Permissions Section + { fieldname: "permissions", fieldtype: "Section Break", label: t("Permissions") }, + { fieldname: "read_only", label: t("Read Only"), fieldtype: "Check" }, + { fieldname: "allow_on_submit", label: t("Allow on Submit"), fieldtype: "Check" }, + { fieldname: "ignore_user_permissions", label: t("Ignore User Permissions"), fieldtype: "Check" }, + { fieldname: "allow_bulk_edit", label: t("Allow Bulk Edit"), fieldtype: "Check", depends_on: "eval:pg.fieldtype=='Table'" }, + { fieldname: "make_attachment_public", label: t("Make Attachment Public (by default)"), fieldtype: "Check", depends_on: "eval:['Attach', 'Attach Image'].includes(pg.fieldtype)" }, + { fieldname: "column_break_13", fieldtype: "Column Break" }, { fieldname: "permlevel", label: t("Permission Level"), fieldtype: "Int" }, + { fieldname: "ignore_xss_filter", label: t("Ignore XSS Filter"), fieldtype: "Check" }, + + // Constraints Section + { fieldname: "constraints_section", fieldtype: "Section Break", label: t("Constraints") }, + { fieldname: "unique", label: t("Unique"), fieldtype: "Check" }, + { fieldname: "no_copy", label: t("No Copy"), fieldtype: "Check" }, + { fieldname: "set_only_once", label: t("Set Only Once"), fieldtype: "Check" }, + { fieldname: "remember_last_selected_value", label: t("Remember Last Selected Value"), fieldtype: "Check", depends_on: "eval:pg.fieldtype=='Link'" }, + { fieldname: "column_break_38", fieldtype: "Column Break" }, + { fieldname: "mandatory_depends_on", label: t("Mandatory Depends On (JS)"), fieldtype: "Code", options: "JS" }, + { fieldname: "read_only_depends_on", label: t("Read Only Depends On (JS)"), fieldtype: "Code", options: "JS" }, + + // Display Section + { fieldname: "display", fieldtype: "Section Break", label: t("Display") }, + { fieldname: "print_width", label: t("Print Width"), fieldtype: "Data" }, { fieldname: "width", label: t("Width"), fieldtype: "Data" }, - { fieldname: "columns", label: t("Columns"), fieldtype: "Int" }, - { fieldname: "precision", label: t("Precision"), fieldtype: "Data" }, - { fieldname: "length", label: t("Length"), fieldtype: "Int" }, - { fieldname: "non_negative", label: t("Non Negative"), fieldtype: "Check" }, - { fieldname: "hide_border", label: t("Hide Border"), fieldtype: "Check" }, - { fieldname: "hide_days", label: t("Hide Days"), fieldtype: "Check" }, - { fieldname: "hide_seconds", label: t("Hide Seconds"), fieldtype: "Check" }, { fieldname: "max_height", label: t("Max Height"), fieldtype: "Data" }, - { fieldname: "link_filters", label: t("Link Filters"), fieldtype: "Code", depends_on: "eval:doc.fieldtype=='Link'" }, + { fieldname: "columns", label: t("Columns"), fieldtype: "Int" }, + { fieldname: "column_break_22", fieldtype: "Column Break" }, + { fieldname: "description", label: t("Description"), fieldtype: "Small Text" }, + { fieldname: "documentation_url", label: t("Documentation URL"), fieldtype: "Data", options: "URL", depends_on: "eval:!in_list(['Tab Break', 'Section Break', 'Column Break', 'Button', 'HTML'], pg.fieldtype)" }, + { fieldname: "placeholder", label: t("Placeholder"), fieldtype: "Data" }, + { fieldname: "oldfieldname", label: t("Old Fieldname"), fieldtype: "Data", hidden: 1 }, + { fieldname: "oldfieldtype", label: t("Old Fieldtype"), fieldtype: "Data", hidden: 1 }, ]; export const useFormBuilderStore = defineStore("form-builder-store", () => { diff --git a/apps/jingrow/frontend/src/core/features/form_builder/utils.js b/apps/jingrow/frontend/src/core/features/form_builder/utils.js index c931a3f..bf3c81b 100644 --- a/apps/jingrow/frontend/src/core/features/form_builder/utils.js +++ b/apps/jingrow/frontend/src/core/features/form_builder/utils.js @@ -160,6 +160,8 @@ export function evaluateDependsOnValue(expression, pg) { } else if (expression.substr(0, 5) === "eval:") { try { const doc = pg; + // Define in_list function for eval context + const in_list = (list, value) => list && list.includes(value); // Simple evaluation for common patterns out = eval(expression.substr(5)); } catch (e) {