@things-factory/auth-ui 10.1.258 → 10.1.260
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.
- package/dist-client/pages/appliance/home.d.ts +0 -1
- package/dist-client/pages/appliance/home.js +5 -6
- package/dist-client/pages/appliance/home.js.map +1 -1
- package/dist-client/pages/application/applications.d.ts +0 -1
- package/dist-client/pages/application/applications.js +5 -6
- package/dist-client/pages/application/applications.js.map +1 -1
- package/dist-client/pages/audit/audit-page.d.ts +15 -14
- package/dist-client/pages/audit/audit-page.js +107 -139
- package/dist-client/pages/audit/audit-page.js.map +1 -1
- package/dist-client/pages/auth-provider/auth-provider-management.d.ts +9 -4
- package/dist-client/pages/auth-provider/auth-provider-management.js +29 -13
- package/dist-client/pages/auth-provider/auth-provider-management.js.map +1 -1
- package/dist-client/pages/domain-owner/domain-owner-management.js +2 -2
- package/dist-client/pages/domain-owner/domain-owner-management.js.map +1 -1
- package/dist-client/pages/list-address.test.d.ts +1 -0
- package/dist-client/pages/list-address.test.js +51 -0
- package/dist-client/pages/list-address.test.js.map +1 -0
- package/dist-client/pages/role/role-inheritance-shown.test.js +7 -6
- package/dist-client/pages/role/role-inheritance-shown.test.js.map +1 -1
- package/dist-client/pages/role/role-list-page.d.ts +20 -27
- package/dist-client/pages/role/role-list-page.js +49 -136
- package/dist-client/pages/role/role-list-page.js.map +1 -1
- package/dist-client/pages/user/user-list-page.d.ts +0 -1
- package/dist-client/pages/user/user-list-page.js +5 -6
- package/dist-client/pages/user/user-list-page.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-client/utils/audit-words.d.ts +28 -0
- package/dist-client/utils/audit-words.js +36 -0
- package/dist-client/utils/audit-words.js.map +1 -1
- package/dist-client/utils/audit-words.test.js +33 -1
- package/dist-client/utils/audit-words.test.js.map +1 -1
- package/dist-client/utils/role-scope.d.ts +15 -0
- package/dist-client/utils/role-scope.js +13 -0
- package/dist-client/utils/role-scope.js.map +1 -0
- package/dist-client/utils/role-scope.test.d.ts +1 -0
- package/dist-client/utils/role-scope.test.js +18 -0
- package/dist-client/utils/role-scope.test.js.map +1 -0
- package/package.json +8 -7
- package/translations/en.json +1 -1
- package/translations/es.json +1 -1
- package/translations/ja.json +1 -1
- package/translations/ko.json +1 -1
- package/translations/ms.json +1 -1
- package/translations/zh.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"role-inheritance-shown.test.js","sourceRoot":"","sources":["../../../client/pages/role/role-inheritance-shown.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAA;AACjC,OAAO,IAAI,MAAM,MAAM,CAAA;AAEvB;;;;GAIG;AAEH,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,mBAAmB,CAAC,EAAE,OAAO,CAAC,CAAA;AAC/E,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAA;AAEjF,MAAM,
|
|
1
|
+
{"version":3,"file":"role-inheritance-shown.test.js","sourceRoot":"","sources":["../../../client/pages/role/role-inheritance-shown.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAA;AACjC,OAAO,IAAI,MAAM,MAAM,CAAA;AAEvB;;;;GAIG;AAEH,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,mBAAmB,CAAC,EAAE,OAAO,CAAC,CAAA;AAC/E,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAA;AAEjF,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,wBAAwB,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAA;AAC3G,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAA;AAErG,QAAQ,CAAC,0CAA0C,EAAE,GAAG,EAAE;IACxD,EAAE,CAAC,kFAAkF,EAAE,GAAG,EAAE;QAC1F,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,6EAA6E,CAAC,CAAA;IACrG,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,mHAAmH;QACnH,MAAM,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,gDAAgD,CAAC,CAAA;QAC7E,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;QAC9D,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,gEAAgE,CAAC,CAAA;IACxF,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,wCAAwC,CAAC,CAAA;QACrE,MAAM,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,wGAAwG,CAAC,CAAA;QACrI,MAAM,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,uEAAuE,CAAC,CAAA;QACpG,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;IAC9D,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,qFAAqF,CAAC,CAAA;IACjH,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA","sourcesContent":["import { readFileSync } from 'fs'\nimport path from 'path'\n\n/**\n * A domain that inherits from nowhere shows nothing about inheritance - no 「우리 역할 · 상속 · 전체」\n * buttons, no line about where roles come from, no source column (the user, 2026-10-28). The page\n * needs a DOM, so the test reads its source with comments stripped.\n */\n\nconst source = readFileSync(path.join(__dirname, 'role-list-page.ts'), 'utf-8')\nconst code = source.replace(/\\/\\*[\\s\\S]*?\\*\\//g, '').replace(/^\\s*\\/\\/.*$/gm, '')\n\nconst initialized = code.slice(code.indexOf('async pageInitialized('), code.indexOf('async fetchHandler('))\nconst counting = code.slice(code.indexOf('async countHandler('), code.indexOf('private renderNote('))\n\ndescribe('the role list in a domain with no parent', () => {\n it('★ inherits only when the profile names a parent - not knowing is not having none', () => {\n expect(code).toMatch(/private hasParent\\(\\): boolean \\{\\s*return this\\.parentDomain !== null\\s*\\}/)\n })\n\n it('★ draws no scope chips, and so no lineage line', () => {\n /* The chips are the grid's `inherited` filter (FOOTER-BUTTON-REVIEW G09): owned but not drawn without a parent. */\n expect(initialized).toMatch(/name: 'inherited',[\\s\\S]*?hidden: !inheriting,/)\n expect(code.match(/this\\.renderLineage\\(\\)/g)).toHaveLength(1)\n expect(code).toMatch(/\\$\\{this\\.hasParent\\(\\) \\? this\\.renderLineage\\(\\) : nothing\\}/)\n })\n\n it('★ leaves the source column and its list detail out', () => {\n expect(initialized).toMatch(/const inheriting = this\\.hasParent\\(\\)/)\n expect(initialized).toMatch(/details: inheriting \\? \\['privilegeCount', 'userCount', 'source'\\] : \\['privilegeCount', 'userCount'\\]/)\n expect(initialized).toMatch(/\\.\\.\\.\\(inheriting\\s*\\?\\s*\\[\\s*\\{\\s*type: 'string',\\s*name: 'source',/)\n expect(initialized.match(/name: 'source'/g)).toHaveLength(1)\n })\n\n it('counts the scopes only where there are scopes to count', () => {\n expect(counting).toMatch(/^async countHandler\\([^)]*\\) \\{\\s*if \\(!this\\.hasParent\\(\\)\\) \\{\\s*return \\{\\}\\s*\\}/)\n })\n})\n"]}
|
|
@@ -52,16 +52,6 @@ export declare class RoleListPage extends RoleListPageBase {
|
|
|
52
52
|
* 셋을 가르는 이유는 화면이 「모른다」와 「없다」를 다르게 그려야 하기 때문이다.
|
|
53
53
|
*/
|
|
54
54
|
private parentDomain;
|
|
55
|
-
private scope;
|
|
56
|
-
/**
|
|
57
|
-
* 묶음마다 몇 건인가.
|
|
58
|
-
*
|
|
59
|
-
* 수를 함께 적는 이유는 **상속이 있다는 사실 자체가 보이게** 하는 것이다. 기본값을 「우리
|
|
60
|
-
* 역할」로 좁혀 놓으면, 수가 없으면 상속 9건이 존재하는지조차 모른다.
|
|
61
|
-
*
|
|
62
|
-
* `undefined` 는 「아직 못 셌다」다 — 0 으로 메우면 「없다」와 같아 보인다.
|
|
63
|
-
*/
|
|
64
|
-
private counts;
|
|
65
55
|
private grist;
|
|
66
56
|
/**
|
|
67
57
|
* 저장과 삭제를 **툴바**에 둔다.
|
|
@@ -90,20 +80,19 @@ export declare class RoleListPage extends RoleListPageBase {
|
|
|
90
80
|
handler: () => void;
|
|
91
81
|
};
|
|
92
82
|
actions: {
|
|
83
|
+
icon: string;
|
|
84
|
+
emphasis: {
|
|
85
|
+
raised: boolean;
|
|
86
|
+
outlined: boolean;
|
|
87
|
+
dense: boolean;
|
|
88
|
+
danger: boolean;
|
|
89
|
+
};
|
|
90
|
+
id: string;
|
|
93
91
|
title: string;
|
|
94
92
|
action: () => Promise<void>;
|
|
95
93
|
}[];
|
|
96
94
|
};
|
|
97
95
|
render(): import("lit-html").TemplateResult<1>;
|
|
98
|
-
/**
|
|
99
|
-
* 세 묶음.
|
|
100
|
-
*
|
|
101
|
-
* **수를 함께 적는 것이 이 부품의 이유다.** 기본값을 「우리 역할」로 좁혀 두면 처음 화면이
|
|
102
|
-
* 깨끗한 대신 **상속 9건이 있다는 사실이 사라진다.** 수가 그것을 되돌려 놓는다.
|
|
103
|
-
*
|
|
104
|
-
* 아직 못 센 묶음은 수를 **안 그린다** — 0 으로 메우면 「없다」와 같아 보인다.
|
|
105
|
-
*/
|
|
106
|
-
private renderScopes;
|
|
107
96
|
/**
|
|
108
97
|
* 어디에서 물려받나 — **어느 도메인인지**를 적는다. 그 역할을 고치러 가야 할 곳이다.
|
|
109
98
|
*
|
|
@@ -121,15 +110,20 @@ export declare class RoleListPage extends RoleListPageBase {
|
|
|
121
110
|
* 「없다」로 접지 않는다.
|
|
122
111
|
*/
|
|
123
112
|
private hasParent;
|
|
124
|
-
private onScope;
|
|
125
113
|
/**
|
|
126
|
-
* 세 묶음의
|
|
114
|
+
* 세 묶음의 건수 — the grid's `countHandler`, beside each chip of the `inherited` filter.
|
|
127
115
|
*
|
|
128
116
|
* 세 번 묻는다. 한 번에 셋을 세는 질의가 서버에 없고, 각각 `total` 만 받으므로 가볍다
|
|
129
|
-
* (UX 실측 158·566·684 bytes).
|
|
130
|
-
* 없는 것이 낫다.
|
|
131
|
-
*/
|
|
132
|
-
|
|
117
|
+
* (UX 실측 158·566·684 bytes). 실패한 묶음은 **수를 안 그린다** — 틀린 수를 그리는 것보다
|
|
118
|
+
* 없는 것이 낫다. A domain with no parent has no 묶음 to count.
|
|
119
|
+
*/
|
|
120
|
+
countHandler(_option: FetchOption): Promise<{
|
|
121
|
+
inherited?: undefined;
|
|
122
|
+
} | {
|
|
123
|
+
inherited: {
|
|
124
|
+
[x: string]: any;
|
|
125
|
+
};
|
|
126
|
+
}>;
|
|
133
127
|
/**
|
|
134
128
|
* 목록 위에 겹쳐 그린다 — 격자를 떼면 다시 읽을 길이 없어진다.
|
|
135
129
|
*
|
|
@@ -154,7 +148,6 @@ export declare class RoleListPage extends RoleListPageBase {
|
|
|
154
148
|
*/
|
|
155
149
|
private sourceCell;
|
|
156
150
|
pageInitialized(): Promise<void>;
|
|
157
|
-
pageUpdated(_changes: any, _lifecycle: any): Promise<void>;
|
|
158
151
|
/**
|
|
159
152
|
* 역할을 가져온다 — **권한 행은 받지 않는다.**
|
|
160
153
|
*
|
|
@@ -172,7 +165,7 @@ export declare class RoleListPage extends RoleListPageBase {
|
|
|
172
165
|
* `inherited` 는 화면이 고른 묶음을 그대로 넘긴다. 기본값이 「우리 역할」이라 처음 화면에
|
|
173
166
|
* 못 고치는 행이 안 깔린다.
|
|
174
167
|
*/
|
|
175
|
-
fetchHandler({ filters, page, limit, sortings }: FetchOption): Promise<{
|
|
168
|
+
fetchHandler({ filters: asked, page, limit, sortings }: FetchOption): Promise<{
|
|
176
169
|
records: any;
|
|
177
170
|
total: any;
|
|
178
171
|
}>;
|
|
@@ -8,15 +8,16 @@ import gql from 'graphql-tag';
|
|
|
8
8
|
import { css, html, nothing } from 'lit';
|
|
9
9
|
import { customElement, property, query, state } from 'lit/decorators.js';
|
|
10
10
|
import { client, gqlContext } from '@operato/graphql';
|
|
11
|
-
import { openPopup } from '@operato/layout';
|
|
11
|
+
import { notify, openPopup } from '@operato/layout';
|
|
12
12
|
import { OxPrompt } from '@operato/popup/ox-prompt.js';
|
|
13
13
|
import { i18next, localize } from '@operato/i18n';
|
|
14
14
|
import { p13n } from '@operato/p13n';
|
|
15
15
|
import { InheritedValueType, navigate, PageView } from '@operato/shell';
|
|
16
|
-
import { CommonGristStyles, CommonHeaderStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles';
|
|
16
|
+
import { CommonButtonStyles, CommonGristStyles, CommonHeaderStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles';
|
|
17
17
|
import { isMobileDevice } from '@operato/utils';
|
|
18
18
|
import { getDomain } from '@things-factory/auth-base/dist-client';
|
|
19
19
|
import { standsInheritedRefusal } from '../../utils/inherited-name-refusal.js';
|
|
20
|
+
import { roleQueryOf } from '../../utils/role-scope.js';
|
|
20
21
|
/**
|
|
21
22
|
* 역할 목록 — **보이는 것과 고칠 수 있는 것을 가른다.**
|
|
22
23
|
*
|
|
@@ -69,25 +70,6 @@ let RoleListPage = class RoleListPage extends RoleListPageBase {
|
|
|
69
70
|
* 셋을 가르는 이유는 화면이 「모른다」와 「없다」를 다르게 그려야 하기 때문이다.
|
|
70
71
|
*/
|
|
71
72
|
this.parentDomain = undefined;
|
|
72
|
-
/*
|
|
73
|
-
* **어느 묶음을 보고 있나 — 기본값은 「우리 역할」이다.**
|
|
74
|
-
*
|
|
75
|
-
* 전에는 `Include` 로 열었다. 그러면 처음 화면에 **못 고치는 행 9개가 앞에 깔린다**
|
|
76
|
-
* (UX 실측: miratek 2 · system 9). `None` 으로 열면 처음 화면이 2행이고 **그 2행이 전부
|
|
77
|
-
* 고칠 수 있는 행**이다.
|
|
78
|
-
*
|
|
79
|
-
* 세 묶음은 서버에 이미 있다(`InheritedValueType`). 새로 만들 것이 없다.
|
|
80
|
-
*/
|
|
81
|
-
this.scope = InheritedValueType.None;
|
|
82
|
-
/**
|
|
83
|
-
* 묶음마다 몇 건인가.
|
|
84
|
-
*
|
|
85
|
-
* 수를 함께 적는 이유는 **상속이 있다는 사실 자체가 보이게** 하는 것이다. 기본값을 「우리
|
|
86
|
-
* 역할」로 좁혀 놓으면, 수가 없으면 상속 9건이 존재하는지조차 모른다.
|
|
87
|
-
*
|
|
88
|
-
* `undefined` 는 「아직 못 셌다」다 — 0 으로 메우면 「없다」와 같아 보인다.
|
|
89
|
-
*/
|
|
90
|
-
this.counts = {};
|
|
91
73
|
}
|
|
92
74
|
static { this.styles = [
|
|
93
75
|
/* The frame owns the page shell; the grist is the content it sizes (ADR-0060 decision 8). */
|
|
@@ -103,17 +85,6 @@ let RoleListPage = class RoleListPage extends RoleListPageBase {
|
|
|
103
85
|
}
|
|
104
86
|
|
|
105
87
|
|
|
106
|
-
/*
|
|
107
|
-
── 세 묶음 ────────────────────────────────────────────────────────────
|
|
108
|
-
고른 것은 면으로 말한다. 글자색만 바꾸면 야간에 안 보인다.
|
|
109
|
-
*/
|
|
110
|
-
[scopes] {
|
|
111
|
-
display: flex;
|
|
112
|
-
align-items: center;
|
|
113
|
-
gap: 4px;
|
|
114
|
-
flex-wrap: wrap;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
88
|
/*
|
|
118
89
|
어디에서 물려받나 — 단추가 아니라 **사실을 적은 글**이다. 그래서 알약도 테두리도 없다.
|
|
119
90
|
고르는 것과 읽는 것이 같은 모양이면 눌러 보게 된다.
|
|
@@ -126,40 +97,6 @@ let RoleListPage = class RoleListPage extends RoleListPageBase {
|
|
|
126
97
|
color: var(--md-sys-color-on-surface-variant);
|
|
127
98
|
}
|
|
128
99
|
|
|
129
|
-
button[scope] {
|
|
130
|
-
display: inline-flex;
|
|
131
|
-
align-items: baseline;
|
|
132
|
-
gap: 5px;
|
|
133
|
-
padding: 5px 12px;
|
|
134
|
-
font: var(--label-font, inherit);
|
|
135
|
-
font-size: 0.82rem;
|
|
136
|
-
color: var(--md-sys-color-on-surface-variant);
|
|
137
|
-
background-color: transparent;
|
|
138
|
-
border: 1px solid var(--md-sys-color-outline-variant);
|
|
139
|
-
border-radius: var(--md-sys-shape-corner-full, 999px);
|
|
140
|
-
cursor: pointer;
|
|
141
|
-
white-space: nowrap;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
button[scope]:hover {
|
|
145
|
-
background-color: var(--md-sys-color-surface-variant);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
button[scope][active] {
|
|
149
|
-
color: var(--md-sys-color-on-secondary-container);
|
|
150
|
-
background-color: var(--md-sys-color-secondary-container);
|
|
151
|
-
border-color: var(--md-sys-color-secondary-container);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
button[scope] [count] {
|
|
155
|
-
font-size: 0.78rem;
|
|
156
|
-
color: var(--md-sys-color-outline);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
button[scope][active] [count] {
|
|
160
|
-
color: var(--md-sys-color-on-secondary-container);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
100
|
/*
|
|
164
101
|
* 새 역할 단추 — **옆에 선 것들을 따라간다.**
|
|
165
102
|
*
|
|
@@ -233,8 +170,9 @@ let RoleListPage = class RoleListPage extends RoleListPageBase {
|
|
|
233
170
|
}
|
|
234
171
|
},
|
|
235
172
|
actions: [
|
|
236
|
-
|
|
237
|
-
{ title: i18next.t('button.delete'), action: this.onDeleteGrid.bind(this) }
|
|
173
|
+
/* Roles start in 「역할 추가」 above the list; here the rows are renamed and deleted. 저장 is the main action. */
|
|
174
|
+
{ id: 'delete', title: i18next.t('button.delete'), action: this.onDeleteGrid.bind(this), ...CommonButtonStyles.delete },
|
|
175
|
+
{ id: 'save', title: i18next.t('button.save'), action: this.onSaveGrid.bind(this), ...CommonButtonStyles.save }
|
|
238
176
|
]
|
|
239
177
|
};
|
|
240
178
|
}
|
|
@@ -245,14 +183,15 @@ let RoleListPage = class RoleListPage extends RoleListPageBase {
|
|
|
245
183
|
.mode=${this.mode}
|
|
246
184
|
.config=${this.config}
|
|
247
185
|
.fetchHandler=${this.fetchHandler.bind(this)}
|
|
186
|
+
.countHandler=${this.countHandler.bind(this)}
|
|
248
187
|
.personalConfigProvider=${this.getPagePreferenceProvider('ox-grist')}
|
|
188
|
+
?url-params-sensitive=${this.active}
|
|
249
189
|
>
|
|
250
190
|
<div slot="headroom" class="header">
|
|
251
191
|
<div class="filters">
|
|
252
|
-
${this.renderScopes()}
|
|
253
|
-
|
|
254
192
|
<!-- 찾기는 제목 줄이 갖는다(context.search). 폼이 자기 검색칸을 또 그리면 둘이 된다. -->
|
|
255
193
|
<ox-filters-form without-search></ox-filters-form>
|
|
194
|
+
${this.hasParent() ? this.renderLineage() : nothing}
|
|
256
195
|
|
|
257
196
|
<!--
|
|
258
197
|
여기 ox-record-creator 가 있었다 — 목록에 빈 줄을 만들고 이름을 치게 하는
|
|
@@ -270,35 +209,6 @@ let RoleListPage = class RoleListPage extends RoleListPageBase {
|
|
|
270
209
|
${this.renderNote()}
|
|
271
210
|
`;
|
|
272
211
|
}
|
|
273
|
-
/**
|
|
274
|
-
* 세 묶음.
|
|
275
|
-
*
|
|
276
|
-
* **수를 함께 적는 것이 이 부품의 이유다.** 기본값을 「우리 역할」로 좁혀 두면 처음 화면이
|
|
277
|
-
* 깨끗한 대신 **상속 9건이 있다는 사실이 사라진다.** 수가 그것을 되돌려 놓는다.
|
|
278
|
-
*
|
|
279
|
-
* 아직 못 센 묶음은 수를 **안 그린다** — 0 으로 메우면 「없다」와 같아 보인다.
|
|
280
|
-
*/
|
|
281
|
-
renderScopes() {
|
|
282
|
-
if (!this.hasParent()) {
|
|
283
|
-
return nothing;
|
|
284
|
-
}
|
|
285
|
-
const scopes = [
|
|
286
|
-
[InheritedValueType.None, 'label.ours'],
|
|
287
|
-
[InheritedValueType.Only, 'label.inherited'],
|
|
288
|
-
[InheritedValueType.Include, 'label.all']
|
|
289
|
-
];
|
|
290
|
-
return html `
|
|
291
|
-
<div scopes>
|
|
292
|
-
${scopes.map(([scope, key]) => html `
|
|
293
|
-
<button scope ?active=${this.scope === scope} @click=${() => this.onScope(scope)}>
|
|
294
|
-
${i18next.t(key)}
|
|
295
|
-
${this.counts[scope] === undefined ? nothing : html `<span count>${this.counts[scope]}</span>`}
|
|
296
|
-
</button>
|
|
297
|
-
`)}
|
|
298
|
-
${this.renderLineage()}
|
|
299
|
-
</div>
|
|
300
|
-
`;
|
|
301
|
-
}
|
|
302
212
|
/**
|
|
303
213
|
* 어디에서 물려받나 — **어느 도메인인지**를 적는다. 그 역할을 고치러 가야 할 곳이다.
|
|
304
214
|
*
|
|
@@ -321,21 +231,17 @@ let RoleListPage = class RoleListPage extends RoleListPageBase {
|
|
|
321
231
|
hasParent() {
|
|
322
232
|
return this.parentDomain !== null;
|
|
323
233
|
}
|
|
324
|
-
onScope(scope) {
|
|
325
|
-
if (this.scope === scope) {
|
|
326
|
-
return;
|
|
327
|
-
}
|
|
328
|
-
this.scope = scope;
|
|
329
|
-
this.grist.fetch();
|
|
330
|
-
}
|
|
331
234
|
/**
|
|
332
|
-
* 세 묶음의
|
|
235
|
+
* 세 묶음의 건수 — the grid's `countHandler`, beside each chip of the `inherited` filter.
|
|
333
236
|
*
|
|
334
237
|
* 세 번 묻는다. 한 번에 셋을 세는 질의가 서버에 없고, 각각 `total` 만 받으므로 가볍다
|
|
335
|
-
* (UX 실측 158·566·684 bytes).
|
|
336
|
-
* 없는 것이 낫다.
|
|
238
|
+
* (UX 실측 158·566·684 bytes). 실패한 묶음은 **수를 안 그린다** — 틀린 수를 그리는 것보다
|
|
239
|
+
* 없는 것이 낫다. A domain with no parent has no 묶음 to count.
|
|
337
240
|
*/
|
|
338
|
-
async
|
|
241
|
+
async countHandler(_option) {
|
|
242
|
+
if (!this.hasParent()) {
|
|
243
|
+
return {};
|
|
244
|
+
}
|
|
339
245
|
const scopes = [InheritedValueType.None, InheritedValueType.Only, InheritedValueType.Include];
|
|
340
246
|
const counted = await Promise.all(scopes.map(async (scope) => {
|
|
341
247
|
const response = await client.query({
|
|
@@ -346,16 +252,14 @@ let RoleListPage = class RoleListPage extends RoleListPageBase {
|
|
|
346
252
|
}
|
|
347
253
|
}
|
|
348
254
|
`,
|
|
349
|
-
variables: { inherited: scope }
|
|
255
|
+
variables: { inherited: scope },
|
|
256
|
+
fetchPolicy: 'no-cache'
|
|
350
257
|
});
|
|
351
258
|
return [scope, response.errors?.length ? undefined : response.data?.roles?.total];
|
|
352
259
|
}));
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
}
|
|
357
|
-
return counts;
|
|
358
|
-
}, {});
|
|
260
|
+
return {
|
|
261
|
+
inherited: counted.reduce((counts, [scope, total]) => (total === undefined ? counts : { ...counts, [scope]: total }), {})
|
|
262
|
+
};
|
|
359
263
|
}
|
|
360
264
|
/**
|
|
361
265
|
* 목록 위에 겹쳐 그린다 — 격자를 떼면 다시 읽을 길이 없어진다.
|
|
@@ -424,9 +328,6 @@ let RoleListPage = class RoleListPage extends RoleListPageBase {
|
|
|
424
328
|
* 안 적는다. 「모른다」를 「없다」로 접지 않는다.
|
|
425
329
|
*/
|
|
426
330
|
this.parentDomain = mine && 'parent' in mine ? mine.parent : undefined;
|
|
427
|
-
if (this.hasParent()) {
|
|
428
|
-
this.countScopes();
|
|
429
|
-
}
|
|
430
331
|
const inheriting = this.hasParent();
|
|
431
332
|
this.config = {
|
|
432
333
|
/*
|
|
@@ -445,6 +346,29 @@ let RoleListPage = class RoleListPage extends RoleListPageBase {
|
|
|
445
346
|
},
|
|
446
347
|
columns: [
|
|
447
348
|
{ type: 'gutter', gutterName: 'sequence', fixed: true },
|
|
349
|
+
{
|
|
350
|
+
/*
|
|
351
|
+
* 세 묶음 — no column shows it, so a hidden one carries the filter: chips with each 묶음's count, 「우리 역할」 by
|
|
352
|
+
* default. A domain that inherits nothing draws no chips (`hidden`), as it draws no lineage or source column.
|
|
353
|
+
*/
|
|
354
|
+
type: 'string',
|
|
355
|
+
name: 'inherited',
|
|
356
|
+
header: i18next.t('field.source'),
|
|
357
|
+
hidden: true,
|
|
358
|
+
record: { editable: false },
|
|
359
|
+
filter: {
|
|
360
|
+
type: 'select-buttons',
|
|
361
|
+
operator: 'eq',
|
|
362
|
+
label: '',
|
|
363
|
+
value: InheritedValueType.None,
|
|
364
|
+
hidden: !inheriting,
|
|
365
|
+
options: [
|
|
366
|
+
{ value: InheritedValueType.None, display: i18next.t('label.ours') },
|
|
367
|
+
{ value: InheritedValueType.Only, display: i18next.t('label.inherited') },
|
|
368
|
+
{ value: InheritedValueType.Include, display: i18next.t('label.all') }
|
|
369
|
+
]
|
|
370
|
+
}
|
|
371
|
+
},
|
|
448
372
|
/* 지우기가 고른 행에 닿는다 — 고르는 칸이 없으면 「삭제」는 무엇을 지우는지 말할 수 없다. */
|
|
449
373
|
{ type: 'gutter', gutterName: 'row-selector', multiple: true, fixed: true },
|
|
450
374
|
{
|
|
@@ -601,12 +525,7 @@ let RoleListPage = class RoleListPage extends RoleListPageBase {
|
|
|
601
525
|
sorters: [{ name: 'name' }]
|
|
602
526
|
};
|
|
603
527
|
}
|
|
604
|
-
|
|
605
|
-
if (this.active) {
|
|
606
|
-
await this.updateComplete;
|
|
607
|
-
this.grist.fetch();
|
|
608
|
-
}
|
|
609
|
-
}
|
|
528
|
+
/* No read on activation here: the list is bound to the address and reads itself whenever the page becomes active. */
|
|
610
529
|
/**
|
|
611
530
|
* 역할을 가져온다 — **권한 행은 받지 않는다.**
|
|
612
531
|
*
|
|
@@ -624,7 +543,8 @@ let RoleListPage = class RoleListPage extends RoleListPageBase {
|
|
|
624
543
|
* `inherited` 는 화면이 고른 묶음을 그대로 넘긴다. 기본값이 「우리 역할」이라 처음 화면에
|
|
625
544
|
* 못 고치는 행이 안 깔린다.
|
|
626
545
|
*/
|
|
627
|
-
async fetchHandler({ filters = [], page, limit, sortings = [] }) {
|
|
546
|
+
async fetchHandler({ filters: asked = [], page, limit, sortings = [] }) {
|
|
547
|
+
const { filters, inherited } = roleQueryOf(asked);
|
|
628
548
|
this.fetchState = 'loading';
|
|
629
549
|
this.filtered = filters.length > 0;
|
|
630
550
|
try {
|
|
@@ -673,7 +593,7 @@ let RoleListPage = class RoleListPage extends RoleListPageBase {
|
|
|
673
593
|
filters,
|
|
674
594
|
pagination: { page, limit },
|
|
675
595
|
sortings: sortings.length ? sortings : [{ name: 'name' }],
|
|
676
|
-
inherited:
|
|
596
|
+
inherited: inherited
|
|
677
597
|
}
|
|
678
598
|
})).data.responses;
|
|
679
599
|
this.total = response.total;
|
|
@@ -703,6 +623,7 @@ let RoleListPage = class RoleListPage extends RoleListPageBase {
|
|
|
703
623
|
async onSaveGrid() {
|
|
704
624
|
const dirty = this.grist.dirtyRecords;
|
|
705
625
|
if (!dirty?.length) {
|
|
626
|
+
notify({ level: 'info', message: i18next.t('text.nothing-to-save') });
|
|
706
627
|
return;
|
|
707
628
|
}
|
|
708
629
|
const patches = dirty.map((record) => {
|
|
@@ -984,14 +905,6 @@ __decorate([
|
|
|
984
905
|
state(),
|
|
985
906
|
__metadata("design:type", Object)
|
|
986
907
|
], RoleListPage.prototype, "parentDomain", void 0);
|
|
987
|
-
__decorate([
|
|
988
|
-
state(),
|
|
989
|
-
__metadata("design:type", String)
|
|
990
|
-
], RoleListPage.prototype, "scope", void 0);
|
|
991
|
-
__decorate([
|
|
992
|
-
state(),
|
|
993
|
-
__metadata("design:type", Object)
|
|
994
|
-
], RoleListPage.prototype, "counts", void 0);
|
|
995
908
|
__decorate([
|
|
996
909
|
query('ox-grist'),
|
|
997
910
|
__metadata("design:type", Function)
|