ngx-dynamic-entity 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -4140,12 +4140,19 @@ class DynamicFormComponent {
|
|
|
4140
4140
|
*/
|
|
4141
4141
|
isFieldReadonly(field) {
|
|
4142
4142
|
return (this.readonly ||
|
|
4143
|
+
// `permissions.edit` gated the Save button and nothing else, so a role without edit
|
|
4144
|
+
// rights received a fully editable form: it could type into every field, and only
|
|
4145
|
+
// discovered the record was not theirs to change when no Save button appeared. The
|
|
4146
|
+
// permission means the record may not be edited, so the fields say so.
|
|
4147
|
+
!this.permissions.canEdit ||
|
|
4143
4148
|
!!field.readonly ||
|
|
4144
4149
|
this.readOnlyFields.includes(field.id) ||
|
|
4145
4150
|
this.isFieldLocked(field));
|
|
4146
4151
|
}
|
|
4147
4152
|
toggleFieldLock(field) {
|
|
4148
|
-
|
|
4153
|
+
// Unlocking is an edit. Without the permission check a viewer could open the lock on a
|
|
4154
|
+
// critical field, which is the one control that exists to make editing deliberate.
|
|
4155
|
+
if (!field.criticalField || this.readonly || !this.permissions.canEdit)
|
|
4149
4156
|
return;
|
|
4150
4157
|
const next = new Set(this.unlockedFields());
|
|
4151
4158
|
if (next.has(field.id))
|
|
@@ -4854,6 +4861,7 @@ class DynamicRecordFormComponent {
|
|
|
4854
4861
|
sectionSave = new EventEmitter();
|
|
4855
4862
|
dynamicFormComp;
|
|
4856
4863
|
rulesEvaluation = inject(RulesEvaluationService);
|
|
4864
|
+
rbacService = inject(RbacService);
|
|
4857
4865
|
host = inject(ElementRef);
|
|
4858
4866
|
injector = inject(Injector);
|
|
4859
4867
|
currentData = signal({}, ...(ngDevMode ? [{ debugName: "currentData" }] : /* istanbul ignore next */ []));
|
|
@@ -4883,9 +4891,21 @@ class DynamicRecordFormComponent {
|
|
|
4883
4891
|
dismissInfoBanner(fieldId) {
|
|
4884
4892
|
this.dismissed.set(new Set(this.dismissed()).add(fieldId));
|
|
4885
4893
|
}
|
|
4894
|
+
/**
|
|
4895
|
+
* Whether the current roles may edit this record.
|
|
4896
|
+
*
|
|
4897
|
+
* `userRoles` was declared as an input here and then read by nothing at all — this
|
|
4898
|
+
* component computed no permissions of any kind, so the record view was fully editable
|
|
4899
|
+
* for every role while the plain form at least hid its Save button. Cached on the same
|
|
4900
|
+
* terms as the sibling component: it depends only on `config` and `userRoles`.
|
|
4901
|
+
*/
|
|
4902
|
+
permissionsCache = null;
|
|
4903
|
+
get permissions() {
|
|
4904
|
+
return (this.permissionsCache ??= this.rbacService.getPermissions(this.config, this.userRoles));
|
|
4905
|
+
}
|
|
4886
4906
|
/** True when nothing in the record may be edited. */
|
|
4887
4907
|
get recordReadOnly() {
|
|
4888
|
-
return this.readonly || this.isReadOnly;
|
|
4908
|
+
return this.readonly || this.isReadOnly || !this.permissions.canEdit;
|
|
4889
4909
|
}
|
|
4890
4910
|
// ─── Inline array-row editing ───────────────────────────────────────────────
|
|
4891
4911
|
/**
|
|
@@ -5097,6 +5117,11 @@ class DynamicRecordFormComponent {
|
|
|
5097
5117
|
* after the first keystroke.
|
|
5098
5118
|
*/
|
|
5099
5119
|
ngOnChanges(changes) {
|
|
5120
|
+
// Permissions depend on these two and nothing else; a stale cache would keep a record
|
|
5121
|
+
// editable after a role switch.
|
|
5122
|
+
if (changes['config'] || changes['userRoles']) {
|
|
5123
|
+
this.permissionsCache = null;
|
|
5124
|
+
}
|
|
5100
5125
|
if (changes['initialData'] || changes['config']) {
|
|
5101
5126
|
this.originalBaseline.set({ ...(this.initialData ?? {}) });
|
|
5102
5127
|
this.currentData.set({ ...(this.initialData ?? {}) });
|