From bd8260d139f90c39416fcb0489d3638fa4fa2210 Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Sat, 4 Nov 2023 11:45:59 +0200 Subject: [PATCH] frontend populate defaults all fields --- .../Espo/Resources/metadata/fields/array.json | 3 +- .../metadata/fields/autoincrement.json | 3 +- .../Resources/metadata/fields/barcode.json | 3 +- .../Espo/Resources/metadata/fields/bool.json | 3 +- .../Resources/metadata/fields/checklist.json | 3 +- .../Espo/Resources/metadata/fields/date.json | 3 +- .../Resources/metadata/fields/datetime.json | 3 +- .../metadata/fields/datetimeOptional.json | 3 +- .../Espo/Resources/metadata/fields/email.json | 3 +- .../Resources/metadata/fields/multiEnum.json | 3 +- .../Resources/metadata/fields/number.json | 3 +- .../Espo/Resources/metadata/fields/phone.json | 3 +- .../Espo/Resources/metadata/fields/text.json | 3 +- .../Espo/Resources/metadata/fields/url.json | 3 +- .../metadata/fields/urlMultiple.json | 3 +- .../Resources/metadata/fields/varchar.json | 3 +- .../Resources/metadata/fields/wysiwyg.json | 3 +- .../src/helpers/model/defaults-populator.js | 87 ++++++++++++++++++- client/src/model.js | 13 +++ client/src/views/record/base.js | 3 +- schema/metadata/fields.json | 3 + 21 files changed, 138 insertions(+), 19 deletions(-) diff --git a/application/Espo/Resources/metadata/fields/array.json b/application/Espo/Resources/metadata/fields/array.json index ecfb25c765..2ee293f348 100644 --- a/application/Espo/Resources/metadata/fields/array.json +++ b/application/Espo/Resources/metadata/fields/array.json @@ -97,5 +97,6 @@ "update", "add", "remove" - ] + ], + "default": [] } diff --git a/application/Espo/Resources/metadata/fields/autoincrement.json b/application/Espo/Resources/metadata/fields/autoincrement.json index 2d2dd9cbfb..f2381b2243 100644 --- a/application/Espo/Resources/metadata/fields/autoincrement.json +++ b/application/Espo/Resources/metadata/fields/autoincrement.json @@ -9,5 +9,6 @@ }, "hookClassName": "Espo\\Tools\\FieldManager\\Hooks\\AutoincrementType", "textFilter": true, - "readOnly": true + "readOnly": true, + "default": null } diff --git a/application/Espo/Resources/metadata/fields/barcode.json b/application/Espo/Resources/metadata/fields/barcode.json index b28c523175..40422dbb0a 100644 --- a/application/Espo/Resources/metadata/fields/barcode.json +++ b/application/Espo/Resources/metadata/fields/barcode.json @@ -54,5 +54,6 @@ "type": "varchar", "len": 255 }, - "validatorClassName": "Espo\\Classes\\FieldValidators\\VarcharType" + "validatorClassName": "Espo\\Classes\\FieldValidators\\VarcharType", + "default": null } diff --git a/application/Espo/Resources/metadata/fields/bool.json b/application/Espo/Resources/metadata/fields/bool.json index 069cb3e722..0ec9e60f33 100644 --- a/application/Espo/Resources/metadata/fields/bool.json +++ b/application/Espo/Resources/metadata/fields/bool.json @@ -20,5 +20,6 @@ "filter": true, "fieldDefs": { "notNull": true - } + }, + "default": false } diff --git a/application/Espo/Resources/metadata/fields/checklist.json b/application/Espo/Resources/metadata/fields/checklist.json index 0949d4faa3..17d4472b49 100644 --- a/application/Espo/Resources/metadata/fields/checklist.json +++ b/application/Espo/Resources/metadata/fields/checklist.json @@ -73,5 +73,6 @@ }, "translatedOptions": true, "dynamicLogicOptions": true, - "personalData": true + "personalData": true, + "default": [] } diff --git a/application/Espo/Resources/metadata/fields/date.json b/application/Espo/Resources/metadata/fields/date.json index d57d0c2d83..4a6678498e 100644 --- a/application/Espo/Resources/metadata/fields/date.json +++ b/application/Espo/Resources/metadata/fields/date.json @@ -79,5 +79,6 @@ }, "personalData": true, "valueFactoryClassName": "Espo\\Core\\Field\\Date\\DateFactory", - "attributeExtractorClassName": "Espo\\Core\\Field\\Date\\DateAttributeExtractor" + "attributeExtractorClassName": "Espo\\Core\\Field\\Date\\DateAttributeExtractor", + "default": null } diff --git a/application/Espo/Resources/metadata/fields/datetime.json b/application/Espo/Resources/metadata/fields/datetime.json index 3ac885779c..37563ce62b 100644 --- a/application/Espo/Resources/metadata/fields/datetime.json +++ b/application/Espo/Resources/metadata/fields/datetime.json @@ -93,5 +93,6 @@ }, "personalData": true, "valueFactoryClassName": "Espo\\Core\\Field\\DateTime\\DateTimeFactory", - "attributeExtractorClassName": "Espo\\Core\\Field\\DateTime\\DateTimeAttributeExtractor" + "attributeExtractorClassName": "Espo\\Core\\Field\\DateTime\\DateTimeAttributeExtractor", + "default": null } diff --git a/application/Espo/Resources/metadata/fields/datetimeOptional.json b/application/Espo/Resources/metadata/fields/datetimeOptional.json index 4666b32720..1047ad4d0a 100644 --- a/application/Espo/Resources/metadata/fields/datetimeOptional.json +++ b/application/Espo/Resources/metadata/fields/datetimeOptional.json @@ -101,5 +101,6 @@ "view": "views/fields/datetime-optional", "personalData": true, "valueFactoryClassName": "Espo\\Core\\Field\\DateTimeOptional\\DateTimeOptionalFactory", - "attributeExtractorClassName": "Espo\\Core\\Field\\DateTimeOptional\\DateTimeOptionalAttributeExtractor" + "attributeExtractorClassName": "Espo\\Core\\Field\\DateTimeOptional\\DateTimeOptionalAttributeExtractor", + "default": null } diff --git a/application/Espo/Resources/metadata/fields/email.json b/application/Espo/Resources/metadata/fields/email.json index fa8a088740..5fd24e0450 100644 --- a/application/Espo/Resources/metadata/fields/email.json +++ b/application/Espo/Resources/metadata/fields/email.json @@ -57,5 +57,6 @@ "textFilter": true, "personalData": true, "valueFactoryClassName": "Espo\\Core\\Field\\EmailAddress\\EmailAddressGroupFactory", - "attributeExtractorClassName": "Espo\\Core\\Field\\EmailAddress\\EmailAddressGroupAttributeExtractor" + "attributeExtractorClassName": "Espo\\Core\\Field\\EmailAddress\\EmailAddressGroupAttributeExtractor", + "default": null } diff --git a/application/Espo/Resources/metadata/fields/multiEnum.json b/application/Espo/Resources/metadata/fields/multiEnum.json index e11c14d151..534af7ea40 100644 --- a/application/Espo/Resources/metadata/fields/multiEnum.json +++ b/application/Espo/Resources/metadata/fields/multiEnum.json @@ -105,5 +105,6 @@ "update", "add", "remove" - ] + ], + "default": [] } diff --git a/application/Espo/Resources/metadata/fields/number.json b/application/Espo/Resources/metadata/fields/number.json index ea5549a89e..3e2551d44c 100644 --- a/application/Espo/Resources/metadata/fields/number.json +++ b/application/Espo/Resources/metadata/fields/number.json @@ -36,5 +36,6 @@ }, "hookClassName": "Espo\\Tools\\FieldManager\\Hooks\\NumberType", "textFilter": true, - "readOnly": true + "readOnly": true, + "default": null } diff --git a/application/Espo/Resources/metadata/fields/phone.json b/application/Espo/Resources/metadata/fields/phone.json index 659a74c290..88c3bc9ef5 100644 --- a/application/Espo/Resources/metadata/fields/phone.json +++ b/application/Espo/Resources/metadata/fields/phone.json @@ -76,5 +76,6 @@ "textFilter": true, "personalData": true, "valueFactoryClassName": "Espo\\Core\\Field\\PhoneNumber\\PhoneNumberGroupFactory", - "attributeExtractorClassName": "Espo\\Core\\Field\\PhoneNumber\\PhoneNumberGroupAttributeExtractor" + "attributeExtractorClassName": "Espo\\Core\\Field\\PhoneNumber\\PhoneNumberGroupAttributeExtractor", + "default": null } diff --git a/application/Espo/Resources/metadata/fields/text.json b/application/Espo/Resources/metadata/fields/text.json index 34f1bfe3cf..c16919a3d6 100644 --- a/application/Espo/Resources/metadata/fields/text.json +++ b/application/Espo/Resources/metadata/fields/text.json @@ -63,5 +63,6 @@ "personalData": true, "textFilter": true, "textFilterForeign": true, - "fullTextSearch": true + "fullTextSearch": true, + "default": null } diff --git a/application/Espo/Resources/metadata/fields/url.json b/application/Espo/Resources/metadata/fields/url.json index 986a9ed5a4..9d4f81df4c 100644 --- a/application/Espo/Resources/metadata/fields/url.json +++ b/application/Espo/Resources/metadata/fields/url.json @@ -49,5 +49,6 @@ "fieldDefs": { "type": "varchar" }, - "personalData": true + "personalData": true, + "default": null } diff --git a/application/Espo/Resources/metadata/fields/urlMultiple.json b/application/Espo/Resources/metadata/fields/urlMultiple.json index be68d74f67..23bcf003f9 100644 --- a/application/Espo/Resources/metadata/fields/urlMultiple.json +++ b/application/Espo/Resources/metadata/fields/urlMultiple.json @@ -54,5 +54,6 @@ "update", "add", "remove" - ] + ], + "default": [] } diff --git a/application/Espo/Resources/metadata/fields/varchar.json b/application/Espo/Resources/metadata/fields/varchar.json index 4e00e25d07..7cc0f2ea8a 100644 --- a/application/Espo/Resources/metadata/fields/varchar.json +++ b/application/Espo/Resources/metadata/fields/varchar.json @@ -71,5 +71,6 @@ "textFilter": true, "textFilterForeign": true, "dynamicLogicOptions": true, - "fullTextSearch": true + "fullTextSearch": true, + "default": null } diff --git a/application/Espo/Resources/metadata/fields/wysiwyg.json b/application/Espo/Resources/metadata/fields/wysiwyg.json index 95db25a875..8e47a1f9bb 100644 --- a/application/Espo/Resources/metadata/fields/wysiwyg.json +++ b/application/Espo/Resources/metadata/fields/wysiwyg.json @@ -56,5 +56,6 @@ "textFilter": true, "fullTextSearch": true, "duplicatorClassName": "Espo\\Classes\\FieldDuplicators\\Wysiwyg", - "validatorClassName": "Espo\\Classes\\FieldValidators\\TextType" + "validatorClassName": "Espo\\Classes\\FieldValidators\\TextType", + "default": null } diff --git a/client/src/helpers/model/defaults-populator.js b/client/src/helpers/model/defaults-populator.js index adf8bb79f8..d4e5181f05 100644 --- a/client/src/helpers/model/defaults-populator.js +++ b/client/src/helpers/model/defaults-populator.js @@ -36,12 +36,14 @@ class DefaultsPopulator { * @param {module:models/preferences} preferences * @param {module:acl-manager} acl * @param {module:models/settings} config + * @param {module:metadata} metadata */ - constructor(user, preferences, acl, config) { + constructor(user, preferences, acl, config, metadata) { this.user = user; this.preferences = preferences; this.acl = acl; this.config = config; + this.metadata = metadata; } /** @@ -62,6 +64,8 @@ class DefaultsPopulator { this.prepareForPortal(model, defaultHash); } + this.prepareFields(model, defaultHash); + for (const attr in defaultHash) { if (model.has(attr)) { delete defaultHash[attr]; @@ -215,6 +219,87 @@ class DefaultsPopulator { } } } + + /** + * @param {module:model} model + * @param {Object.} defaultHash + * @private + */ + prepareFields(model, defaultHash) { + const set = (attribute, value) => { + if ( + attribute in defaultHash || + model.has(attribute) + ) { + return; + } + + defaultHash[attribute] = value; + }; + + model.getFieldList().forEach(field => { + const type = model.getFieldType(field); + + if (!type) { + return; + } + + /** @type {{default?: *}} */ + const defs = this.metadata.get(`fields.${type}`) || {}; + + if ('default' in defs) { + set(field, defs.default); + + return; + } + + if ( + type === 'link' || + type === 'linkOne' || + type === 'file' || + type === 'image' + ) { + set(field + 'Id', null); + set(field + 'Name', null); + + return; + } + + if (type === 'linkParent') { + set(field + 'Id', null); + set(field + 'Name', null); + set(field + 'Type', null); + + return; + } + + if ( + type === 'linkMultiple' || + type === 'attachmentMultiple' + ) { + set(field + 'Ids', []); + set(field + 'Names', {}); + + return; + } + + if (type === 'enum') { + /** @type {string[]} */ + const options = model.getFieldParam(field, 'options') || []; + let value = options[0] || ''; + value = value !== '' ? value : null; + + set(field, value); + + return; + } + + if (type === 'currency') { + set(field, null); + set(field + 'Currency', null); + } + }); + } } export default DefaultsPopulator; diff --git a/client/src/model.js b/client/src/model.js index 9c883dee94..b826dcb177 100644 --- a/client/src/model.js +++ b/client/src/model.js @@ -831,6 +831,19 @@ class Model { setRelate(data); } + /** + * Get a field list. + * + * @return {string[]} + */ + getFieldList() { + if (!this.defs || !this.defs.fields) { + return []; + } + + return Object.keys(this.defs.fields); + } + /** * Get a field type. * diff --git a/client/src/views/record/base.js b/client/src/views/record/base.js index ffdabf468f..78a1c438d7 100644 --- a/client/src/views/record/base.js +++ b/client/src/views/record/base.js @@ -1287,7 +1287,8 @@ class BaseRecordView extends View { this.getUser(), this.getPreferences(), this.getAcl(), - this.getConfig() + this.getConfig(), + this.getMetadata() ); populator.populate(this.model); diff --git a/schema/metadata/fields.json b/schema/metadata/fields.json index 5f92a0038b..627637e68a 100644 --- a/schema/metadata/fields.json +++ b/schema/metadata/fields.json @@ -121,6 +121,9 @@ }, "description": "Columns used in full-text search." }, + "default": { + "description": "A default value. Used when populating defaults for a new record in frontend. Usually to be set to null." + }, "valueFactoryClassName": { "type": "string", "description": "A factory that creates value-objects for this field. A value-object can be obtained by calling getValueObject method on an Entity. Should implement Espo\\ORM\\Value\\ValueFactory."