@things-factory/auth-ui 10.1.221 → 10.1.225

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.
@@ -56,7 +56,6 @@ export declare class RolePrivilegePage extends RolePrivilegePage_base {
56
56
  private showUnheldTasks;
57
57
  /** null until asked for; [] when this person may not read templates (`roleTemplates` asks user:mutation). */
58
58
  private templates;
59
- private templateId;
60
59
  private gap;
61
60
  /**
62
61
  * 부모 도메인의 역할은 여기서 못 고친다 — `updateRole` 의 범위가 `domain.id` 하나다.
@@ -147,10 +146,11 @@ export declare class RolePrivilegePage extends RolePrivilegePage_base {
147
146
  private editTask;
148
147
  private renderTask;
149
148
  /**
150
- * **The role against a template the administrator picks** (ADR-0139 decision 11) — whatever the role is called.
149
+ * **The role against its base template** (ADR-0139 decision 11; ADR-0075 decision 1, amended 2026-10-26).
151
150
  *
152
- * The template of the role's name is picked to begin with; a role named in the site's own words (경영지원, 인사급여)
153
- * has no such pair, and the administrator picks one. The role is never renamed to make a pair: an approval line
151
+ * A role keeps one base template (`Role.templateId`), whatever the role is called — a role named in the site's own
152
+ * words (경영지원, 인사급여) is given its base here, once, and the role list counts what it lacks from then on.
153
+ * Picking saves the base at once and touches no privilege. The role is never renamed to make a pair: an approval line
154
154
  * holds the role. What the role holds beyond the template is shown as wider, not wrong — the site may have widened it
155
155
  * on purpose — and nothing takes it away. What it lacks can be added; adding is the same top-up the template button
156
156
  * on the role list runs (`createRoleFromTemplate` onto this role's name).
@@ -160,7 +160,9 @@ export declare class RolePrivilegePage extends RolePrivilegePage_base {
160
160
  /** A privilege in words — the sentence the privileges view draws, or its module and axis when there is none. */
161
161
  private sentenceOf;
162
162
  private fetchTemplates;
163
- private pickTemplate;
163
+ /** Saves the role's base template - `''` bases it on none. The privileges stay as they are. */
164
+ private setBaseTemplate;
165
+ private readGap;
164
166
  /** Adds what the role lacks against the picked template — after showing what it adds. */
165
167
  private addMissing;
166
168
  /**
@@ -70,7 +70,6 @@ let RolePrivilegePage = class RolePrivilegePage extends localize(i18next)(PageVi
70
70
  this.showUnheldTasks = false;
71
71
  /** null until asked for; [] when this person may not read templates (`roleTemplates` asks user:mutation). */
72
72
  this.templates = null;
73
- this.templateId = '';
74
73
  this.gap = null;
75
74
  }
76
75
  static { this.styles = [
@@ -915,10 +914,11 @@ let RolePrivilegePage = class RolePrivilegePage extends localize(i18next)(PageVi
915
914
  `;
916
915
  }
917
916
  /**
918
- * **The role against a template the administrator picks** (ADR-0139 decision 11) — whatever the role is called.
917
+ * **The role against its base template** (ADR-0139 decision 11; ADR-0075 decision 1, amended 2026-10-26).
919
918
  *
920
- * The template of the role's name is picked to begin with; a role named in the site's own words (경영지원, 인사급여)
921
- * has no such pair, and the administrator picks one. The role is never renamed to make a pair: an approval line
919
+ * A role keeps one base template (`Role.templateId`), whatever the role is called — a role named in the site's own
920
+ * words (경영지원, 인사급여) is given its base here, once, and the role list counts what it lacks from then on.
921
+ * Picking saves the base at once and touches no privilege. The role is never renamed to make a pair: an approval line
922
922
  * holds the role. What the role holds beyond the template is shown as wider, not wrong — the site may have widened it
923
923
  * on purpose — and nothing takes it away. What it lacks can be added; adding is the same top-up the template button
924
924
  * on the role list runs (`createRoleFromTemplate` onto this role's name).
@@ -930,14 +930,17 @@ let RolePrivilegePage = class RolePrivilegePage extends localize(i18next)(PageVi
930
930
  if (!this.templates.length) {
931
931
  return html `<div review><div empty>${i18next.t('text.no template to compare with')}</div></div>`;
932
932
  }
933
- const template = this.templates.find(one => one.id === this.templateId);
933
+ const baseId = this.subject?.templateId || '';
934
+ const template = this.templates.find(one => one.id === baseId);
934
935
  const gap = this.gap;
935
936
  return html `
936
937
  <div review>
937
- <select @change=${(event) => this.pickTemplate(event.target.value)}>
938
- <option value="" ?selected=${!this.templateId}>${i18next.t('text.pick a template to compare with')}</option>
939
- ${this.templates.map(one => html `<option value=${one.id} ?selected=${one.id === this.templateId}>${one.name}</option>`)}
938
+ <select ?disabled=${this.inherited || this.saving} @change=${(event) => this.setBaseTemplate(event.target.value)}>
939
+ <option value="" ?selected=${!baseId}>${i18next.t('text.no base template')}</option>
940
+ ${this.templates.map(one => html `<option value=${one.id} ?selected=${one.id === baseId}>${one.name}</option>`)}
941
+ ${baseId && !template ? html `<option value=${baseId} selected>${baseId}</option>` : nothing}
940
942
  </select>
943
+ ${baseId && !template ? html `<div note attention>${i18next.t('text.base template not in this installation')}</div>` : nothing}
941
944
  ${this.dirty ? html `<div stale>${i18next.t('text.counted from the saved privileges')}</div>` : nothing}
942
945
  ${template?.definitionErrors.length
943
946
  ? html `<div note attention>${i18next.t('text.template cannot be applied because', { list: template.definitionErrors.join(' · ') })}</div>`
@@ -990,21 +993,44 @@ let RolePrivilegePage = class RolePrivilegePage extends localize(i18next)(PageVi
990
993
  /* Reading templates asks the same door creating a role does; without it there is nothing to compare with. */
991
994
  const templates = response.errors?.length ? [] : response.data?.roleTemplates || [];
992
995
  this.templates = templates;
993
- const paired = templates.find(one => one.name === this.subject?.name);
994
- await this.pickTemplate(paired?.id || '');
996
+ await this.readGap();
995
997
  }
996
- async pickTemplate(templateId) {
997
- this.templateId = templateId;
998
+ /** Saves the role's base template - `''` bases it on none. The privileges stay as they are. */
999
+ async setBaseTemplate(templateId) {
1000
+ if (this.inherited || this.saving)
1001
+ return;
1002
+ const response = await client.mutate({
1003
+ mutation: gql `
1004
+ mutation ($id: String!, $patch: RolePatch!) {
1005
+ updateRole(id: $id, patch: $patch) {
1006
+ id
1007
+ templateId
1008
+ }
1009
+ }
1010
+ `,
1011
+ variables: { id: this.subject.id, patch: { templateId: templateId || null } },
1012
+ context: gqlContext()
1013
+ });
1014
+ if (response.errors?.length) {
1015
+ document.dispatchEvent(new CustomEvent('notify', { detail: { level: 'error', message: response.errors[0]?.message } }));
1016
+ this.requestUpdate();
1017
+ return;
1018
+ }
1019
+ this.subject = { ...this.subject, templateId: response.data?.updateRole?.templateId || null };
1020
+ await this.readGap();
1021
+ }
1022
+ async readGap() {
998
1023
  this.gap = null;
999
- if (!templateId)
1024
+ const baseId = this.subject?.templateId;
1025
+ if (!baseId)
1000
1026
  return;
1001
1027
  const response = await client.query({
1002
1028
  query: gql `
1003
- query ($filters: [Filter!], $templateId: String) {
1029
+ query ($filters: [Filter!]) {
1004
1030
  roles(filters: $filters) {
1005
1031
  items {
1006
1032
  id
1007
- templateGap(templateId: $templateId) {
1033
+ templateGap {
1008
1034
  templateId
1009
1035
  templateName
1010
1036
  missing { ${GRANT_FIELDS} }
@@ -1016,14 +1042,14 @@ let RolePrivilegePage = class RolePrivilegePage extends localize(i18next)(PageVi
1016
1042
  }
1017
1043
  }
1018
1044
  `,
1019
- variables: { filters: [{ name: 'id', operator: 'eq', value: this.subject.id }], templateId },
1045
+ variables: { filters: [{ name: 'id', operator: 'eq', value: this.subject.id }] },
1020
1046
  context: gqlContext()
1021
1047
  });
1022
1048
  if (response.errors?.length) {
1023
1049
  document.dispatchEvent(new CustomEvent('notify', { detail: { level: 'error', message: response.errors[0]?.message } }));
1024
1050
  return;
1025
1051
  }
1026
- if (this.templateId === templateId)
1052
+ if (this.subject?.templateId === baseId)
1027
1053
  this.gap = response.data?.roles?.items?.[0]?.templateGap || null;
1028
1054
  }
1029
1055
  /** Adds what the role lacks against the picked template — after showing what it adds. */
@@ -1058,7 +1084,7 @@ let RolePrivilegePage = class RolePrivilegePage extends localize(i18next)(PageVi
1058
1084
  }
1059
1085
  document.dispatchEvent(new CustomEvent('notify', { detail: { message: i18next.t('text.data_updated_successfully') } }));
1060
1086
  await this.fetch();
1061
- await this.pickTemplate(gap.templateId);
1087
+ await this.readGap();
1062
1088
  }
1063
1089
  /**
1064
1090
  * 한 줄 — 문장과 [떼기].
@@ -1300,6 +1326,7 @@ let RolePrivilegePage = class RolePrivilegePage extends localize(i18next)(PageVi
1300
1326
  id
1301
1327
  name
1302
1328
  description
1329
+ templateId
1303
1330
  domain {
1304
1331
  id
1305
1332
  name
@@ -1524,10 +1551,6 @@ __decorate([
1524
1551
  state(),
1525
1552
  __metadata("design:type", Object)
1526
1553
  ], RolePrivilegePage.prototype, "templates", void 0);
1527
- __decorate([
1528
- state(),
1529
- __metadata("design:type", String)
1530
- ], RolePrivilegePage.prototype, "templateId", void 0);
1531
1554
  __decorate([
1532
1555
  state(),
1533
1556
  __metadata("design:type", Object)