From 5d68e153c35918330ea64ed077f0aab734284fe6 Mon Sep 17 00:00:00 2001 From: Yurii Date: Mon, 16 Feb 2026 11:54:33 +0200 Subject: [PATCH 1/6] select native fix for new chrome --- frontend/less/espo/elements/form.less | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontend/less/espo/elements/form.less b/frontend/less/espo/elements/form.less index d086a0e455..ac368726e8 100644 --- a/frontend/less/espo/elements/form.less +++ b/frontend/less/espo/elements/form.less @@ -590,6 +590,9 @@ select.form-control.native-select { appearance: base-select; } + // Otherwise, the picker displayed in a wrong place. + display: inline-flex; + &:open { border-color: var(--input-border-focus); outline: 0; From 9536146226f4eb5008d41daed87aa7d23bab5382 Mon Sep 17 00:00:00 2001 From: Yurii Date: Mon, 16 Feb 2026 12:07:09 +0200 Subject: [PATCH 2/6] role ui: true on change --- client/src/views/role/record/edit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/views/role/record/edit.js b/client/src/views/role/record/edit.js index ddcd2cdbb1..b30b5fdd2f 100644 --- a/client/src/views/role/record/edit.js +++ b/client/src/views/role/record/edit.js @@ -56,7 +56,7 @@ class RoleEditRecordView extends EditRecordView { this.listenTo(view, 'change', () => { const data = this.fetch(); - this.model.set(data); + this.model.setMultiple(data, {ui: true}); }); }); } From 970c37d92105cb71e7dd3ccbebab46860f5f1357 Mon Sep 17 00:00:00 2001 From: Yurii Date: Mon, 16 Feb 2026 12:42:20 +0200 Subject: [PATCH 3/6] role table ui fixes --- client/src/views/role/record/table.js | 70 ++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 6 deletions(-) diff --git a/client/src/views/role/record/table.js b/client/src/views/role/record/table.js index 997f8b0204..0ba5d8975f 100644 --- a/client/src/views/role/record/table.js +++ b/client/src/views/role/record/table.js @@ -115,6 +115,22 @@ class RoleRecordTableView extends View { */ acl + /** + * @private + * @type {({ + * list: { + * level: string|false, + * name: string, + * action: string, + * levelList: string[]|null, + * }[], + * name: string, + * type: 'boolean'|'record', + * access: 'not-set'|'enabled'|'disabled', + * }|false)[]} + */ + tableDataList + /** * @private * @type { @@ -126,6 +142,7 @@ class RoleRecordTableView extends View { * action: 'read'|'edit', * value: 'yes'|'no', * name: string, + * levelList: string[]|null, * }[], * }[], * }[] @@ -143,7 +160,7 @@ class RoleRecordTableView extends View { data.fieldActionList = this.fieldActionList; data.fieldLevelList = this.fieldLevelList; - data.tableDataList = this.getTableDataList(); + data.tableDataList = this.tableDataList; data.fieldTableDataList = this.fieldTableDataList; let hasFieldLevelData = false; @@ -375,7 +392,7 @@ class RoleRecordTableView extends View { const promises = []; - this.getTableDataList().forEach(scopeItem => { + this.tableDataList.forEach(scopeItem => { if (!scopeItem) { return; } @@ -529,7 +546,7 @@ class RoleRecordTableView extends View { if (actionItem.action === 'read') { this.listenTo(this.formModel, `change:${scope}-${field}-read`, (m, value) => { - this.controlFieldEditSelect(scope, field, value, true); + this.controlFieldEditSelect(scope, field, value); }); } }); @@ -538,7 +555,7 @@ class RoleRecordTableView extends View { const readLevel = this.formModel.attributes[`${scope}-${field}-read`]; if (readLevel) { - this.controlFieldEditSelect(scope, field, readLevel); + this.controlFieldEditSelect(scope, field, readLevel, true); } } @@ -564,6 +581,7 @@ class RoleRecordTableView extends View { } this.setupScopeList(); + this.tableDataList = this.getTableDataList(); this.setupFieldTableDataList(); } @@ -679,6 +697,7 @@ class RoleRecordTableView extends View { name: `${scope}-${field}-${action}`, action: action, value: scopeData[field][action] || 'yes', + levelList: [...this.fieldLevelList], }) }); @@ -826,7 +845,7 @@ class RoleRecordTableView extends View { const options = this.fieldLevelList .filter(item => this.levelList.indexOf(item) >= this.levelList.indexOf(limitValue)); - if (!dontChange) { + if (!dontChange && this.hasFieldAction(scope, field, 'edit')) { this.formModel.set(attribute, value); } @@ -861,7 +880,7 @@ class RoleRecordTableView extends View { const options = this.getLevelList(scope, action) .filter(item => this.levelList.indexOf(item) >= this.levelList.indexOf(limitValue)); - if (!dontChange) { + if (!dontChange && this.hasAction(scope, action)) { setTimeout(() => this.formModel.set(attribute, value), 0); } @@ -874,6 +893,43 @@ class RoleRecordTableView extends View { } } + /** + * @private + * @param {string} scope + * @param {string} action + * @return {boolean} + */ + hasAction(scope, action) { + if (this.tableDataList === false) { + return false; + } + + return !!this.tableDataList + ?.find(it => it.name === scope) + ?.list + .find(it => it.action === action) + ?.levelList + ?.length; + } + + /** + * @private + * @param {string} scope + * @param {string} field + * @param {string} action + * @return {boolean} + */ + hasFieldAction(scope, field, action) { + return !!this.fieldTableDataList + ?.find(it => it.name === scope) + ?.list + ?.find(it => it.name === field) + ?.list + .find(it => it.action === action) + ?.levelList + ?.length; + } + /** * @private * @param {string} scope @@ -908,11 +964,13 @@ class RoleRecordTableView extends View { name: `${scope}-${field}-read`, action: 'read', value: 'no', + levelList: [...this.fieldLevelList], }, { name: `${scope}-${field}-edit`, action: 'edit', value: 'no', + levelList: [...this.fieldLevelList], }, ] }; From 299709f3ee605701c23073c3df5b4b42db149fb8 Mon Sep 17 00:00:00 2001 From: Yurii Date: Mon, 16 Feb 2026 13:51:56 +0200 Subject: [PATCH 4/6] code style params --- .idea/codeStyles/Project.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index a4c63b2952..ebbc52ff2b 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -7,6 +7,7 @@