@things-factory/auth-ui 10.0.8 → 10.0.10
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/components/role-privilege-editor.js +21 -1
- package/dist-client/components/role-privilege-editor.js.map +1 -1
- package/dist-client/pages/domain/domain-management.js +122 -23
- package/dist-client/pages/domain/domain-management.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/translations/en.json +8 -3
- package/translations/ja.json +8 -3
- package/translations/ko.json +5 -0
- package/translations/ms.json +8 -3
- package/translations/zh.json +8 -3
|
@@ -102,6 +102,22 @@ let RolePrivilegeEditor = class RolePrivilegeEditor extends localize(i18next)(Li
|
|
|
102
102
|
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
+
/* 코드가 더 이상 요구하지 않는 권한 — 부여해도 아무 일이 없으므로 눈에 구별되어야 한다.
|
|
106
|
+
감추지는 않는다. 이미 역할에 붙어 있을 수 있고, 그것을 보고 떼는 것이 관리자의 일이다. */
|
|
107
|
+
li[deprecated] label {
|
|
108
|
+
opacity: 0.55;
|
|
109
|
+
text-decoration: line-through;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
li[deprecated] small {
|
|
113
|
+
display: block;
|
|
114
|
+
margin-left: 1.6em;
|
|
115
|
+
color: var(--md-sys-color-error);
|
|
116
|
+
font-size: 0.8em;
|
|
117
|
+
text-decoration: none;
|
|
118
|
+
opacity: 0.9;
|
|
119
|
+
}
|
|
120
|
+
|
|
105
121
|
#checkAll,
|
|
106
122
|
[for='checkAll'] {
|
|
107
123
|
margin-bottom: var(--spacing-medium);
|
|
@@ -183,7 +199,7 @@ let RolePrivilegeEditor = class RolePrivilegeEditor extends localize(i18next)(Li
|
|
|
183
199
|
${groupedPrivileges[category].map(
|
|
184
200
|
/* privilege : {id, name, category, description} */
|
|
185
201
|
privilege => html `
|
|
186
|
-
<li>
|
|
202
|
+
<li ?deprecated=${privilege.deprecated}>
|
|
187
203
|
<input
|
|
188
204
|
type="checkbox"
|
|
189
205
|
id="${privilege.id}"
|
|
@@ -191,6 +207,9 @@ let RolePrivilegeEditor = class RolePrivilegeEditor extends localize(i18next)(Li
|
|
|
191
207
|
.data-privilege=${privilege}
|
|
192
208
|
/>
|
|
193
209
|
<label for="${privilege.id}">${privilege.description}</label>
|
|
210
|
+
${privilege.deprecated
|
|
211
|
+
? html `<small>${String(i18next.t('text.privilege no longer declared'))}</small>`
|
|
212
|
+
: ''}
|
|
194
213
|
</li>
|
|
195
214
|
`)}
|
|
196
215
|
</div>
|
|
@@ -286,6 +305,7 @@ let RolePrivilegeEditor = class RolePrivilegeEditor extends localize(i18next)(Li
|
|
|
286
305
|
name
|
|
287
306
|
category
|
|
288
307
|
description
|
|
308
|
+
deprecated
|
|
289
309
|
}
|
|
290
310
|
total
|
|
291
311
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"role-privilege-editor.js","sourceRoot":"","sources":["../../client/components/role-privilege-editor.ts"],"names":[],"mappings":";AAAA,OAAO,GAAG,MAAM,aAAa,CAAA;AAC7B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAElE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AACrD,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAA;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AAGvD,IAAM,mBAAmB,GAAzB,MAAM,mBAAoB,SAAQ,QAAQ,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC;IAA/D;;QAsI6B,kBAAa,GAAU,EAAE,CAAA;QAG3C,eAAU,GAA0C,EAAE,CAAA;QACtD,UAAK,GAA0E,EAAE,CAAA;IAkN5F,CAAC;aA3VQ,WAAM,GAAG;QACd,qBAAqB;QACrB,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA+HF;KACF,AAlIY,CAkIZ;IASD,MAAM;QACJ,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,IAAI,EAAE,CAAA;QAC9C,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,EAAE,CAAA;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAA;QAE9B,+BAA+B;QAC/B,MAAM,iBAAiB,GAAG,aAAa,CAAC,MAAM,CAC5C,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE;YACjB,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,IAAI,OAAO,CAAA;YAC9C,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACnB,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAA;YACpB,CAAC;YACD,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;YAC7B,OAAO,GAAG,CAAA;QACZ,CAAC,EACD,EAA2B,CAC5B,CAAA;QAED,iCAAiC;QACjC,MAAM,gBAAgB,GAAG,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,IAAI,EAAE,CAAA;QAE9D,4DAA4D;QAC5D,gBAAgB,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;YAClC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;QAC1E,CAAC,CAAC,CAAA;QAEF,OAAO,IAAI,CAAA;oBACK,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;;mBAEhC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAA,QAAQ,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,SAAS,CAAC;;oBAE/D,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC;;;uDAGF,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;;;;;UAKpE,gBAAgB,CAAC,GAAG,CACpB,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAA;;4CAEkB,QAAQ;;kBAElC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,GAAG;QAC/B,mDAAmD;QACnD,SAAS,CAAC,EAAE,CAAC,IAAI,CAAA;;;;8BAIL,SAAS,CAAC,EAAE;mCACP,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;0CAC7C,SAAS;;oCAEf,SAAS,CAAC,EAAE,KAAK,SAAS,CAAC,WAAW;;mBAEvD,CACF;;;WAGN,CACF;;;;qCAI4B,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;qCACtD,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE;aAChD,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC;;;KAG/C,CAAA;IACH,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,IAAI,CAAC,aAAa,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAA;IACnD,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,OAAO;QACnB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAClD,CAAC;IACH,CAAC;IAED,QAAQ,CAAC,OAAO;QACd,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,qCAAqC,CAAC,CAAC,CAAC,OAAO,CACzF,QAAQ,CAAC,EAAE,CAAC,CAAE,QAA6B,CAAC,OAAO,GAAG,OAAO,CAAC,CAC/D,CAAA;IACH,CAAC;IAED,UAAU,CAAC,CAAC;QACV,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACjC,CAAC;IAED,KAAK,CAAC,MAAM;QACV,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAA;QACxC,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,6CAA6C,CAAC,CAAC,CAAC,GAAG,CAChH,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,gBAAgB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,0BAA0B;SACjE,CAAA;QAED,MAAM,KAAK,GAAG,EAAE,GAAG,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,CAAA;QAE1D,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC;gBACnC,QAAQ,EAAE,GAAG,CAAA;;;;;;;;;;;;SAYZ;gBACD,SAAS,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE;gBACtC,OAAO,EAAE,UAAU,EAAE;aACtB,CAAC,CAAA;YAEF,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;gBACrB,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,aAAa,CAAC,CAAC,CAAA;gBACxD,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,gCAAgC,CAAC,CAAC,CAAA;YAC7D,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,IACE,MAAM,QAAQ,CAAC,IAAI,CAAC;YAClB,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC;YACrC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,+BAA+B,EAAE,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC;YAChF,aAAa,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,EAAE;YACnD,YAAY,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,EAAE;SACnD,CAAC,EACF,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC;gBACnC,QAAQ,EAAE,GAAG,CAAA;;;;SAIZ;gBACD,SAAS,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE;gBAC/B,OAAO,EAAE,UAAU,EAAE;aACtB,CAAC,CAAA;YAEF,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;gBACrB,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,aAAa,CAAC,CAAC,CAAA;gBAExD,MAAM,QAAQ,CAAC,IAAI,CAAC;oBAClB,IAAI,EAAE,SAAS;oBACf,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC;oBAClC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,6BAA6B,EAAE,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC;oBAC9E,aAAa,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,EAAE;iBACrD,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,eAAe;QACnB,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;YAClC,KAAK,EAAE,GAAG,CAAA;;;;;;;;;;;;OAYT;SACF,CAAC,CAAA;QAEF,OAAO,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAA;IACvC,CAAC;IAED,KAAK,CAAC,qBAAqB,CAAC,IAAI;QAC9B,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;YAClC,KAAK,EAAE,GAAG,CAAA;;;;;;;;;;;;;;;OAeT;YACD,SAAS,EAAE,EAAE,IAAI,EAAE;YACnB,OAAO,EAAE,UAAU,EAAE;SACtB,CAAC,CAAA;QAEF,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAA;QAChD,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAA;IACxC,CAAC;IAED,SAAS,CAAC,OAAO;QACf,QAAQ,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;IACrG,CAAC;;AAtN2B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;iDAAU;AACV;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;;0DAA0B;AACxB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;0DAAmB;AAErC;IAAR,KAAK,EAAE;;uDAAuD;AACtD;IAAR,KAAK,EAAE;;kDAAkF;AA1ItF,mBAAmB;IADxB,aAAa,CAAC,uBAAuB,CAAC;GACjC,mBAAmB,CA4VxB","sourcesContent":["import gql from 'graphql-tag'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport { client, gqlContext } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { OxPrompt } from '@operato/popup/ox-prompt.js'\nimport { ButtonContainerStyles } from '@operato/styles'\n\n@customElement('role-privilege-editor')\nclass RolePrivilegeEditor extends localize(i18next)(LitElement) {\n static styles = [\n ButtonContainerStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n\n border: 1px solid var(--md-sys-color-primary);\n font: normal 15px var(--theme-font);\n }\n\n div {\n margin: var(--spacing-medium);\n }\n\n div[users] {\n margin: 0;\n background-color: var(--md-sys-color-surface-variant);\n }\n\n div[titler] {\n color: var(--md-sys-color-secondary);\n font: bold 1.2em var(--theme-font);\n text-transform: capitalize;\n }\n\n ul {\n flex: 1;\n color: var(--md-sys-color-secondary);\n background-color: var(--md-sys-color-surface-variant);\n overflow: auto;\n display: grid;\n grid-template-columns: 1fr 1fr;\n margin-block-start: 0;\n margin-block-end: 0;\n padding: var(--spacing-medium);\n list-style: none;\n border: 1px dashed rgba(0, 0, 0, 0.1);\n border-width: 1px 0;\n }\n\n .category-group {\n display: contents;\n }\n\n .category-title {\n font-weight: bold;\n font-size: 0.9em;\n color: var(--md-sys-color-primary);\n text-transform: uppercase;\n opacity: 0.7;\n align-self: stretch;\n position: sticky;\n top: 0;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n text-align: right;\n }\n\n .category-privileges {\n display: contents;\n }\n\n @media screen and (min-width: 640px) {\n ul {\n grid-template-columns: minmax(200px, auto) 1fr 1fr;\n gap: 0;\n }\n\n .category-title {\n grid-column: 1;\n padding-right: var(--spacing-medium);\n }\n\n li {\n grid-column: auto;\n }\n }\n\n input[type='checkbox'] {\n display: inline;\n }\n\n li {\n padding: var(--spacing-small);\n border-bottom: 1px solid rgba(0, 0, 0, 0.1);\n }\n\n #checkAll,\n [for='checkAll'] {\n margin-bottom: var(--spacing-medium);\n padding-bottom: var(--spacing-small);\n font-weight: bold;\n }\n\n md-elevated-button {\n margin: 5px;\n background-color: var(--md-sys-color-surface-variant);\n }\n\n md-outlined-button {\n background-color: var(--md-sys-color-surface-variant);\n }\n\n @media screen and (max-width: 639px) {\n ul {\n grid-template-columns: 1fr;\n }\n\n .category-group {\n display: block;\n margin-top: var(--spacing-medium);\n }\n\n .category-group:first-child {\n margin-top: 0;\n }\n\n .category-title {\n position: static;\n margin-bottom: var(--spacing-small);\n }\n\n .category-privileges {\n display: grid;\n grid-template-columns: 1fr;\n }\n }\n `\n ]\n\n @property({ type: Object }) role: any\n @property({ type: Array }) allPrivileges: any[] = []\n @property({ type: Object }) updateRoleObj: any\n\n @state() privileges: { id: string; description: string }[] = []\n @state() users: { /* id: string; username: string; */ name: string; email: string }[] = []\n\n render() {\n const allPrivileges = this.allPrivileges || []\n const privileges = this.privileges || []\n const users = this.users || []\n\n // Group privileges by category\n const groupedPrivileges = allPrivileges.reduce(\n (acc, privilege) => {\n const category = privilege.category || 'Other'\n if (!acc[category]) {\n acc[category] = []\n }\n acc[category].push(privilege)\n return acc\n },\n {} as Record<string, any[]>\n )\n\n // Sort categories alphabetically\n const sortedCategories = Object.keys(groupedPrivileges).sort()\n\n // Sort privileges within each category by name (descending)\n sortedCategories.forEach(category => {\n groupedPrivileges[category].sort((a, b) => b.name.localeCompare(a.name))\n })\n\n return html`\n <div titler>${String(i18next.t('label.user'))}</div>\n\n <div users>${users.map(user => html`<div>${user.name} (${user.email})</div>`)}</div>\n\n <div titler>${String(i18next.t('field.privileges'))}</div>\n\n <div>\n <input id=\"checkAll\" type=\"checkbox\" @change=${e => this.oncheckAll(e)} />\n <label for=\"checkAll\">Check all</label>\n </div>\n\n <ul privileges>\n ${sortedCategories.map(\n category => html`\n <div class=\"category-group\">\n <div class=\"category-title\">${category}</div>\n <div class=\"category-privileges\">\n ${groupedPrivileges[category].map(\n /* privilege : {id, name, category, description} */\n privilege => html`\n <li>\n <input\n type=\"checkbox\"\n id=\"${privilege.id}\"\n .checked=${privileges.map(p => p.id).indexOf(privilege.id) > -1}\n .data-privilege=${privilege}\n />\n <label for=\"${privilege.id}\">${privilege.description}</label>\n </li>\n `\n )}\n </div>\n </div>\n `\n )}\n </ul>\n\n <div class=\"button-container\">\n <md-elevated-button @click=${e => this.onSave()}>${String(i18next.t('button.save'))}</md-elevated-button>\n <md-elevated-button @click=${e => this.onDeleteRole()} danger\n >${String(i18next.t('button.delete role'))}</md-elevated-button\n >\n </div>\n `\n }\n\n async firstUpdated() {\n this.allPrivileges = await this.fetchPrivileges()\n }\n\n async updated(changes) {\n if (changes.has('role')) {\n await this.fetchPrivilegesOnRole(this.role.name)\n }\n }\n\n checkAll(checked) {\n Array.from(this.renderRoot.querySelectorAll('ul[privileges] input[type=checkbox]')).forEach(\n checkbox => ((checkbox as HTMLInputElement).checked = checked)\n )\n }\n\n oncheckAll(e) {\n this.checkAll(e.target.checked)\n }\n\n async onSave() {\n const updateRoleObj = this.updateRoleObj\n const privileges = Array.from(this.renderRoot.querySelectorAll('ul[privileges] input[type=checkbox]:checked')).map(\n e => ({ id: e['data-privilege'].id }) // ObjectRef 타입에 맞게 id만 전송\n )\n\n const patch = { ...updateRoleObj, privileges: privileges }\n\n if (this.role) {\n const response = await client.mutate({\n mutation: gql`\n mutation ($id: String!, $patch: RolePatch!) {\n updateRole(id: $id, patch: $patch) {\n id\n name\n description\n privileges {\n id\n description\n }\n }\n }\n `,\n variables: { id: this.role.id, patch },\n context: gqlContext()\n })\n\n if (!response.errors) {\n await this.dispatchEvent(new CustomEvent('fetch-roles'))\n this.showToast(i18next.t('text.data_updated_successfully'))\n }\n }\n }\n\n async onDeleteRole() {\n if (\n await OxPrompt.open({\n title: i18next.t('text.are_you_sure'),\n text: i18next.t('text.are_you_sure_to_delete_x', { x: i18next.t('label.role') }),\n confirmButton: { text: i18next.t('button.delete') },\n cancelButton: { text: i18next.t('button.cancel') }\n })\n ) {\n const response = await client.mutate({\n mutation: gql`\n mutation ($id: String!) {\n deleteRole(id: $id)\n }\n `,\n variables: { id: this.role.id },\n context: gqlContext()\n })\n\n if (!response.errors) {\n await this.dispatchEvent(new CustomEvent('fetch-roles'))\n\n await OxPrompt.open({\n type: 'success',\n title: i18next.t('text.completed'),\n text: i18next.t('text.x_deleted_successfully', { x: i18next.t('label.role') }),\n confirmButton: { text: i18next.t('button.confirm') }\n })\n }\n }\n }\n\n async fetchPrivileges() {\n const response = await client.query({\n query: gql`\n query privileges {\n privileges {\n items {\n id\n name\n category\n description\n }\n total\n }\n }\n `\n })\n\n return response.data.privileges.items\n }\n\n async fetchPrivilegesOnRole(name) {\n const response = await client.query({\n query: gql`\n query ($name: String!) {\n role(name: $name) {\n id\n name\n privileges {\n id\n description\n }\n users {\n name\n email\n }\n }\n }\n `,\n variables: { name },\n context: gqlContext()\n })\n\n this.privileges = response.data.role?.privileges\n this.users = response.data.role?.users\n }\n\n showToast(message) {\n document.dispatchEvent(new CustomEvent('notify', { detail: { message, option: { timer: 1000 } } }))\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"role-privilege-editor.js","sourceRoot":"","sources":["../../client/components/role-privilege-editor.ts"],"names":[],"mappings":"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","sourcesContent":["import gql from 'graphql-tag'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport { client, gqlContext } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { OxPrompt } from '@operato/popup/ox-prompt.js'\nimport { ButtonContainerStyles } from '@operato/styles'\n\n@customElement('role-privilege-editor')\nclass RolePrivilegeEditor extends localize(i18next)(LitElement) {\n static styles = [\n ButtonContainerStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n\n border: 1px solid var(--md-sys-color-primary);\n font: normal 15px var(--theme-font);\n }\n\n div {\n margin: var(--spacing-medium);\n }\n\n div[users] {\n margin: 0;\n background-color: var(--md-sys-color-surface-variant);\n }\n\n div[titler] {\n color: var(--md-sys-color-secondary);\n font: bold 1.2em var(--theme-font);\n text-transform: capitalize;\n }\n\n ul {\n flex: 1;\n color: var(--md-sys-color-secondary);\n background-color: var(--md-sys-color-surface-variant);\n overflow: auto;\n display: grid;\n grid-template-columns: 1fr 1fr;\n margin-block-start: 0;\n margin-block-end: 0;\n padding: var(--spacing-medium);\n list-style: none;\n border: 1px dashed rgba(0, 0, 0, 0.1);\n border-width: 1px 0;\n }\n\n .category-group {\n display: contents;\n }\n\n .category-title {\n font-weight: bold;\n font-size: 0.9em;\n color: var(--md-sys-color-primary);\n text-transform: uppercase;\n opacity: 0.7;\n align-self: stretch;\n position: sticky;\n top: 0;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n text-align: right;\n }\n\n .category-privileges {\n display: contents;\n }\n\n @media screen and (min-width: 640px) {\n ul {\n grid-template-columns: minmax(200px, auto) 1fr 1fr;\n gap: 0;\n }\n\n .category-title {\n grid-column: 1;\n padding-right: var(--spacing-medium);\n }\n\n li {\n grid-column: auto;\n }\n }\n\n input[type='checkbox'] {\n display: inline;\n }\n\n li {\n padding: var(--spacing-small);\n border-bottom: 1px solid rgba(0, 0, 0, 0.1);\n }\n\n /* 코드가 더 이상 요구하지 않는 권한 — 부여해도 아무 일이 없으므로 눈에 구별되어야 한다.\n 감추지는 않는다. 이미 역할에 붙어 있을 수 있고, 그것을 보고 떼는 것이 관리자의 일이다. */\n li[deprecated] label {\n opacity: 0.55;\n text-decoration: line-through;\n }\n\n li[deprecated] small {\n display: block;\n margin-left: 1.6em;\n color: var(--md-sys-color-error);\n font-size: 0.8em;\n text-decoration: none;\n opacity: 0.9;\n }\n\n #checkAll,\n [for='checkAll'] {\n margin-bottom: var(--spacing-medium);\n padding-bottom: var(--spacing-small);\n font-weight: bold;\n }\n\n md-elevated-button {\n margin: 5px;\n background-color: var(--md-sys-color-surface-variant);\n }\n\n md-outlined-button {\n background-color: var(--md-sys-color-surface-variant);\n }\n\n @media screen and (max-width: 639px) {\n ul {\n grid-template-columns: 1fr;\n }\n\n .category-group {\n display: block;\n margin-top: var(--spacing-medium);\n }\n\n .category-group:first-child {\n margin-top: 0;\n }\n\n .category-title {\n position: static;\n margin-bottom: var(--spacing-small);\n }\n\n .category-privileges {\n display: grid;\n grid-template-columns: 1fr;\n }\n }\n `\n ]\n\n @property({ type: Object }) role: any\n @property({ type: Array }) allPrivileges: any[] = []\n @property({ type: Object }) updateRoleObj: any\n\n @state() privileges: { id: string; description: string }[] = []\n @state() users: { /* id: string; username: string; */ name: string; email: string }[] = []\n\n render() {\n const allPrivileges = this.allPrivileges || []\n const privileges = this.privileges || []\n const users = this.users || []\n\n // Group privileges by category\n const groupedPrivileges = allPrivileges.reduce(\n (acc, privilege) => {\n const category = privilege.category || 'Other'\n if (!acc[category]) {\n acc[category] = []\n }\n acc[category].push(privilege)\n return acc\n },\n {} as Record<string, any[]>\n )\n\n // Sort categories alphabetically\n const sortedCategories = Object.keys(groupedPrivileges).sort()\n\n // Sort privileges within each category by name (descending)\n sortedCategories.forEach(category => {\n groupedPrivileges[category].sort((a, b) => b.name.localeCompare(a.name))\n })\n\n return html`\n <div titler>${String(i18next.t('label.user'))}</div>\n\n <div users>${users.map(user => html`<div>${user.name} (${user.email})</div>`)}</div>\n\n <div titler>${String(i18next.t('field.privileges'))}</div>\n\n <div>\n <input id=\"checkAll\" type=\"checkbox\" @change=${e => this.oncheckAll(e)} />\n <label for=\"checkAll\">Check all</label>\n </div>\n\n <ul privileges>\n ${sortedCategories.map(\n category => html`\n <div class=\"category-group\">\n <div class=\"category-title\">${category}</div>\n <div class=\"category-privileges\">\n ${groupedPrivileges[category].map(\n /* privilege : {id, name, category, description} */\n privilege => html`\n <li ?deprecated=${privilege.deprecated}>\n <input\n type=\"checkbox\"\n id=\"${privilege.id}\"\n .checked=${privileges.map(p => p.id).indexOf(privilege.id) > -1}\n .data-privilege=${privilege}\n />\n <label for=\"${privilege.id}\">${privilege.description}</label>\n ${privilege.deprecated\n ? html`<small>${String(i18next.t('text.privilege no longer declared'))}</small>`\n : ''}\n </li>\n `\n )}\n </div>\n </div>\n `\n )}\n </ul>\n\n <div class=\"button-container\">\n <md-elevated-button @click=${e => this.onSave()}>${String(i18next.t('button.save'))}</md-elevated-button>\n <md-elevated-button @click=${e => this.onDeleteRole()} danger\n >${String(i18next.t('button.delete role'))}</md-elevated-button\n >\n </div>\n `\n }\n\n async firstUpdated() {\n this.allPrivileges = await this.fetchPrivileges()\n }\n\n async updated(changes) {\n if (changes.has('role')) {\n await this.fetchPrivilegesOnRole(this.role.name)\n }\n }\n\n checkAll(checked) {\n Array.from(this.renderRoot.querySelectorAll('ul[privileges] input[type=checkbox]')).forEach(\n checkbox => ((checkbox as HTMLInputElement).checked = checked)\n )\n }\n\n oncheckAll(e) {\n this.checkAll(e.target.checked)\n }\n\n async onSave() {\n const updateRoleObj = this.updateRoleObj\n const privileges = Array.from(this.renderRoot.querySelectorAll('ul[privileges] input[type=checkbox]:checked')).map(\n e => ({ id: e['data-privilege'].id }) // ObjectRef 타입에 맞게 id만 전송\n )\n\n const patch = { ...updateRoleObj, privileges: privileges }\n\n if (this.role) {\n const response = await client.mutate({\n mutation: gql`\n mutation ($id: String!, $patch: RolePatch!) {\n updateRole(id: $id, patch: $patch) {\n id\n name\n description\n privileges {\n id\n description\n }\n }\n }\n `,\n variables: { id: this.role.id, patch },\n context: gqlContext()\n })\n\n if (!response.errors) {\n await this.dispatchEvent(new CustomEvent('fetch-roles'))\n this.showToast(i18next.t('text.data_updated_successfully'))\n }\n }\n }\n\n async onDeleteRole() {\n if (\n await OxPrompt.open({\n title: i18next.t('text.are_you_sure'),\n text: i18next.t('text.are_you_sure_to_delete_x', { x: i18next.t('label.role') }),\n confirmButton: { text: i18next.t('button.delete') },\n cancelButton: { text: i18next.t('button.cancel') }\n })\n ) {\n const response = await client.mutate({\n mutation: gql`\n mutation ($id: String!) {\n deleteRole(id: $id)\n }\n `,\n variables: { id: this.role.id },\n context: gqlContext()\n })\n\n if (!response.errors) {\n await this.dispatchEvent(new CustomEvent('fetch-roles'))\n\n await OxPrompt.open({\n type: 'success',\n title: i18next.t('text.completed'),\n text: i18next.t('text.x_deleted_successfully', { x: i18next.t('label.role') }),\n confirmButton: { text: i18next.t('button.confirm') }\n })\n }\n }\n }\n\n async fetchPrivileges() {\n const response = await client.query({\n query: gql`\n query privileges {\n privileges {\n items {\n id\n name\n category\n description\n deprecated\n }\n total\n }\n }\n `\n })\n\n return response.data.privileges.items\n }\n\n async fetchPrivilegesOnRole(name) {\n const response = await client.query({\n query: gql`\n query ($name: String!) {\n role(name: $name) {\n id\n name\n privileges {\n id\n description\n }\n users {\n name\n email\n }\n }\n }\n `,\n variables: { name },\n context: gqlContext()\n })\n\n this.privileges = response.data.role?.privileges\n this.users = response.data.role?.users\n }\n\n showToast(message) {\n document.dispatchEvent(new CustomEvent('notify', { detail: { message, option: { timer: 1000 } } }))\n }\n}\n"]}
|
|
@@ -12,6 +12,7 @@ import { DataGrist } from '@operato/data-grist/ox-grist.js';
|
|
|
12
12
|
import { client } from '@operato/graphql';
|
|
13
13
|
import { i18next, localize } from '@operato/i18n';
|
|
14
14
|
import { openPopup } from '@operato/layout';
|
|
15
|
+
import { OxPrompt } from '@operato/popup/ox-prompt.js';
|
|
15
16
|
import { PageView } from '@operato/shell';
|
|
16
17
|
import { CommonHeaderStyles, CommonGristStyles, ScrollbarStyles } from '@operato/styles';
|
|
17
18
|
import { isMobileDevice } from '@operato/utils';
|
|
@@ -113,10 +114,12 @@ let DomainManagement = class DomainManagement extends p13n(localize(i18next)(Pag
|
|
|
113
114
|
}
|
|
114
115
|
}
|
|
115
116
|
},
|
|
116
|
-
{
|
|
117
|
+
{
|
|
118
|
+
type: 'string',
|
|
117
119
|
name: 'name',
|
|
118
120
|
header: i18next.t('field.name'),
|
|
119
|
-
record: {
|
|
121
|
+
record: {
|
|
122
|
+
editable: true
|
|
120
123
|
},
|
|
121
124
|
filter: 'search',
|
|
122
125
|
sortable: true,
|
|
@@ -130,10 +133,12 @@ let DomainManagement = class DomainManagement extends p13n(localize(i18next)(Pag
|
|
|
130
133
|
filter: 'search',
|
|
131
134
|
width: 200
|
|
132
135
|
},
|
|
133
|
-
{
|
|
136
|
+
{
|
|
137
|
+
type: 'string',
|
|
134
138
|
name: 'subdomain',
|
|
135
139
|
header: i18next.t('field.subdomain'),
|
|
136
|
-
record: {
|
|
140
|
+
record: {
|
|
141
|
+
editable: true
|
|
137
142
|
},
|
|
138
143
|
filter: 'search',
|
|
139
144
|
width: 200
|
|
@@ -261,34 +266,128 @@ let DomainManagement = class DomainManagement extends p13n(localize(i18next)(Pag
|
|
|
261
266
|
};
|
|
262
267
|
}
|
|
263
268
|
async onUpdateDomains() {
|
|
264
|
-
let
|
|
265
|
-
if (
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
269
|
+
let rawPatches = this.grist.dirtyRecords;
|
|
270
|
+
if (!rawPatches || !rawPatches.length)
|
|
271
|
+
return;
|
|
272
|
+
// 1. 서브도메인 변경 여부 감지 및 최고 단계 안전장치 (URL/북마크 파괴 방지)
|
|
273
|
+
const subdomainChanges = rawPatches.filter(domain => domain.__dirtyfields__?.subdomain);
|
|
274
|
+
if (subdomainChanges.length > 0) {
|
|
275
|
+
for (const domain of subdomainChanges) {
|
|
276
|
+
const oldSub = domain.__dirtyfields__?.subdomain?.before || domain.subdomain;
|
|
277
|
+
const newSub = domain.__dirtyfields__?.subdomain?.after?.trim();
|
|
278
|
+
// 1-1. 'system' 도메인의 서브도메인은 수정 불가
|
|
279
|
+
if (oldSub === 'system' || domain.systemFlag) {
|
|
280
|
+
await OxPrompt.open({
|
|
281
|
+
type: 'error',
|
|
282
|
+
title: i18next.t('title.invalid input', { defaultValue: 'Invalid Input' }),
|
|
283
|
+
text: i18next.t('error.cannot_modify_system_subdomain', {
|
|
284
|
+
defaultValue: "The 'system' subdomain cannot be modified."
|
|
285
|
+
}),
|
|
286
|
+
confirmButton: { text: i18next.t('button.confirm', { defaultValue: 'Confirm' }) }
|
|
287
|
+
});
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
// 1-2. 다른 도메인을 'system'으로 변경하려는 시도 차단
|
|
291
|
+
if (newSub?.toLowerCase() === 'system') {
|
|
292
|
+
await OxPrompt.open({
|
|
293
|
+
type: 'error',
|
|
294
|
+
title: i18next.t('title.invalid input', { defaultValue: 'Invalid Input' }),
|
|
295
|
+
text: i18next.t('error.system_subdomain_reserved', {
|
|
296
|
+
defaultValue: "The 'system' subdomain is reserved and cannot be used."
|
|
297
|
+
}),
|
|
298
|
+
confirmButton: { text: i18next.t('button.confirm', { defaultValue: 'Confirm' }) }
|
|
299
|
+
});
|
|
300
|
+
return;
|
|
277
301
|
}
|
|
278
|
-
|
|
279
|
-
|
|
302
|
+
// 1-3. 빈 서브도메인 검증
|
|
303
|
+
if (!newSub) {
|
|
304
|
+
await OxPrompt.open({
|
|
305
|
+
type: 'error',
|
|
306
|
+
title: i18next.t('title.invalid input', { defaultValue: 'Invalid Input' }),
|
|
307
|
+
text: i18next.t('error.value is empty', { value: i18next.t('field.subdomain'), defaultValue: 'Subdomain cannot be empty.' }),
|
|
308
|
+
confirmButton: { text: i18next.t('button.confirm', { defaultValue: 'Confirm' }) }
|
|
309
|
+
});
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
// 서브도메인 변경 시 전체 URL 경로 변경에 대한 명시적 경고
|
|
314
|
+
const subChangeList = subdomainChanges
|
|
315
|
+
.map(d => {
|
|
316
|
+
const before = d.__dirtyfields__?.subdomain?.before || d.subdomain;
|
|
317
|
+
const after = d.__dirtyfields__?.subdomain?.after;
|
|
318
|
+
return `• ${d.name || d.id}: ${before} ➔ ${after}`;
|
|
319
|
+
})
|
|
320
|
+
.join('\n');
|
|
321
|
+
const confirmed = await OxPrompt.open({
|
|
322
|
+
type: 'warning',
|
|
323
|
+
title: i18next.t('text.are_you_sure', { defaultValue: 'Are you sure?' }),
|
|
324
|
+
text: `${i18next.t('text.subdomain_change_critical_warning', {
|
|
325
|
+
defaultValue: 'Warning: Changing the subdomain will alter the full access URL (/{type}/{subdomain}/...) and may invalidate existing external links, bookmarks, and active user sessions. Please proceed with caution.'
|
|
326
|
+
})}\n\n${subChangeList}`,
|
|
327
|
+
confirmButton: { text: i18next.t('button.save', { defaultValue: 'Save' }) },
|
|
328
|
+
cancelButton: { text: i18next.t('button.cancel', { defaultValue: 'Cancel' }) }
|
|
280
329
|
});
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
330
|
+
if (!confirmed)
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
// 2. 도메인 명칭(name) 변경 시 유효성 검증
|
|
334
|
+
const nameChanges = rawPatches.filter(domain => domain.__dirtyfields__?.name);
|
|
335
|
+
if (nameChanges.length > 0) {
|
|
336
|
+
for (const domain of nameChanges) {
|
|
337
|
+
const newName = domain.__dirtyfields__?.name?.after?.trim();
|
|
338
|
+
if (!newName) {
|
|
339
|
+
await OxPrompt.open({
|
|
340
|
+
type: 'error',
|
|
341
|
+
title: i18next.t('title.invalid input', { defaultValue: 'Invalid Input' }),
|
|
342
|
+
text: i18next.t('error.value is empty', { value: i18next.t('field.name'), defaultValue: 'Domain name cannot be empty.' }),
|
|
343
|
+
confirmButton: { text: i18next.t('button.confirm', { defaultValue: 'Confirm' }) }
|
|
344
|
+
});
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
const patches = rawPatches.map(domain => {
|
|
350
|
+
let patchField = domain.id ? { id: domain.id } : {};
|
|
351
|
+
const dirtyFields = domain.__dirtyfields__;
|
|
352
|
+
for (let key in dirtyFields) {
|
|
353
|
+
if (key == 'ownerUser') {
|
|
354
|
+
const ownerUser = dirtyFields[key].after;
|
|
355
|
+
patchField['owner'] = ownerUser?.id || '';
|
|
356
|
+
}
|
|
357
|
+
else if (key == 'name') {
|
|
358
|
+
patchField[key] = dirtyFields[key].after?.trim();
|
|
359
|
+
}
|
|
360
|
+
else if (key == 'subdomain') {
|
|
361
|
+
patchField[key] = dirtyFields[key].after?.trim();
|
|
362
|
+
}
|
|
363
|
+
else {
|
|
364
|
+
patchField[key] = dirtyFields[key].after;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
return patchField;
|
|
368
|
+
});
|
|
369
|
+
try {
|
|
370
|
+
const response = await client.mutate({
|
|
371
|
+
mutation: gql `
|
|
372
|
+
mutation updateDomains($patches: [DomainPatch!]!) {
|
|
373
|
+
updateDomains(patches: $patches)
|
|
374
|
+
}
|
|
284
375
|
`,
|
|
285
376
|
variables: { patches }
|
|
286
377
|
});
|
|
287
|
-
if (!response.errors) {
|
|
378
|
+
if (!response.errors?.length) {
|
|
288
379
|
this.grist.fetch();
|
|
289
380
|
return this.showToast(i18next.t('text.updated_successfully'));
|
|
290
381
|
}
|
|
291
382
|
}
|
|
383
|
+
catch (err) {
|
|
384
|
+
await OxPrompt.open({
|
|
385
|
+
type: 'error',
|
|
386
|
+
title: i18next.t('text.failed', { defaultValue: 'Failed' }),
|
|
387
|
+
text: err?.message || String(err),
|
|
388
|
+
confirmButton: { text: i18next.t('button.confirm', { defaultValue: 'Confirm' }) }
|
|
389
|
+
});
|
|
390
|
+
}
|
|
292
391
|
}
|
|
293
392
|
async onCreateDomain() {
|
|
294
393
|
openPopup(html `
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"domain-management.js","sourceRoot":"","sources":["../../../client/pages/domain/domain-management.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\n\nimport '@operato/data-grist/ox-grist.js'\nimport '@operato/data-grist/ox-filters-form.js'\nimport '@operato/context/ox-context-page-toolbar.js'\nimport '@operato/attribute/ox-attribute-view.js'\nimport '../../components/create-domain-popup.js'\n\nimport gql from 'graphql-tag'\nimport { css, html } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\nimport { DataGrist } from '@operato/data-grist/ox-grist.js'\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { openPopup } from '@operato/layout'\nimport { PageView } from '@operato/shell'\nimport { CommonHeaderStyles, CommonGristStyles, ScrollbarStyles } from '@operato/styles'\nimport { isMobileDevice } from '@operato/utils'\nimport { p13n } from '@operato/p13n'\nimport { FetchOption } from '@operato/data-grist'\n\n@customElement('domain-management')\nexport class DomainManagement extends p13n(localize(i18next)(PageView)) { static styles = [\n CommonGristStyles,\n CommonHeaderStyles,\n ScrollbarStyles,\n css`\n :host { display: flex;\n flex-direction: column;\n\n overflow: hidden;\n }\n\n ox-grist { overflow-y: auto;\n flex: 1;\n }\n `\n ]\n\n @property({ type: Boolean }) active: boolean = false\n @property({ type: Object }) config: any\n @property({ type: String }) mode: 'CARD' | 'LIST' | 'GRID' = isMobileDevice() ? 'CARD' : 'GRID'\n\n private domainTypes?: string[]\n\n @query('ox-grist') private grist!: DataGrist\n\n get context() { return { title: i18next.t('text.domain management'),\n search: { handler: (search: string) => { this.grist.searchText = search\n },\n value: this.grist?.searchText || ''\n },\n filter: { handler: () => { this.grist.toggleHeadroom()\n }\n },\n actions: [\n { title: i18next.t('button.add'),\n action: this.onCreateDomain.bind(this),\n icon: 'add'\n },\n { title: i18next.t('button.save'),\n action: this.onUpdateDomains.bind(this),\n icon: 'save'\n }\n ],\n toolbar: false\n }\n }\n\n render() { return html`\n <ox-grist\n .mode=${this.mode}\n .config=${this.config}\n .fetchHandler=${this.fetchHandler.bind(this)}\n .personalConfigProvider=${this.getPagePreferenceProvider('ox-grist')!}\n >\n <div slot=\"headroom\" class=\"header\">\n <ox-context-page-toolbar class=\"actions\" .context=${this.context}></ox-context-page-toolbar>\n </div>\n\n <ox-grist-personalizer slot=\"setting\"></ox-grist-personalizer>\n </ox-grist>\n `\n }\n\n async pageInitialized() { this.config = { rows: { appendable: false\n },\n columns: [\n { type: 'gutter', gutterName: 'sequence' },\n { type: 'gutter',\n gutterName: 'button',\n icon: 'assignment',\n title: i18next.t('title.open attributes view'),\n handlers: { click: async (columns, data, column, record, rowIndex) => { const attributeSet = await this.getAttributeSetForDomain()\n\n openPopup(\n html`\n <ox-attribute-view\n .attributeSet=${attributeSet}\n .value=${record.attributes}\n style=\"background-color: white;\"\n ></ox-attribute-view>\n `,\n { backdrop: true,\n size: 'large',\n title: record.name + ' ' + i18next.t('title.attributes')\n }\n )\n }\n }\n },\n { type: 'gutter',\n gutterName: 'button',\n icon: 'domain',\n title: i18next.t('title.move to this domain'),\n handlers: { click: (_columns, _data, _column, record, _rowIndex) => { if (record.id) { const subdomain = record.subdomain\n const extType = record.extType || 'domain'\n location.pathname = `/${extType}/${subdomain}/users`\n }\n }\n }\n },\n { type: 'string',\n name: 'name',\n header: i18next.t('field.name'),\n record: { editable: false\n },\n filter: 'search',\n sortable: true,\n width: 200\n },\n { type: 'string',\n name: 'description',\n header: i18next.t('field.description'),\n record: { editable: true\n },\n filter: 'search',\n width: 200\n },\n { type: 'string',\n name: 'subdomain',\n header: i18next.t('field.subdomain'),\n record: { editable: false\n },\n filter: 'search',\n width: 200\n },\n { type: 'resource-object',\n name: 'parent',\n header: i18next.t('field.parent-domain'),\n record: { editable: true,\n options: { title: i18next.t('text.select domain'),\n queryName: 'domains',\n nameField: 'name',\n descriptionField: 'description',\n select: [\n { name: 'id', hidden: true },\n { name: 'name', header: i18next.t('field.name'), filter: 'search' },\n { name: 'description', header: i18next.t('field.description'), filter: 'search' }\n ],\n list: { fields: ['name', 'description'] }\n }\n },\n width: 140\n },\n { type: 'resource-object',\n name: 'ownerUser',\n header: i18next.t('field.owner-user'),\n record: { editable: true,\n options: { title: i18next.t('title.lookup user'),\n queryName: 'users',\n nameField: 'name',\n descriptionField: 'email',\n select: [\n { name: 'id', hidden: true },\n { name: 'name', header: i18next.t('field.name'), filter: 'search' },\n { name: 'email', header: i18next.t('field.email'), filter: 'search' }\n ],\n filters: [{ name: 'userType', operator: 'eq', value: 'user' }],\n list: { fields: ['name', 'email'] }\n }\n },\n width: 140\n },\n { type: 'select',\n name: 'extType',\n header: i18next.t('field.type'),\n record: { editable: true,\n options: async () => { return ['', ...(await this.getDomainTypes())]\n }\n },\n width: 100\n },\n {\n type: 'select',\n name: 'theme',\n header: i18next.t('field.theme'),\n record: {\n editable: true,\n options: ['', 'ocean-blue', 'forest-green', 'sunset-orange', 'royal-purple', 'cherry-red']\n },\n width: 140\n },\n { type: 'timezone',\n name: 'timezone',\n header: i18next.t('field.timezone'),\n record: { editable: true\n },\n width: 120\n },\n { type: 'attributes',\n name: 'attributes',\n header: i18next.t('field.attributes'),\n record: { editable: true,\n options: async () => { return { objectified: true,\n attributeSet: await this.getAttributeSetForDomain()\n }\n }\n },\n width: 120\n },\n { type: 'datetime',\n name: 'updatedAt',\n header: i18next.t('field.updated_at'),\n width: 180\n }\n ]\n }\n }\n\n async pageUpdated(changes, lifecycle) { if (this.active) { await this.updateComplete\n\n this.grist.fetch()\n }\n }\n\n async fetchHandler({ page, limit, sortings = [], filters = [] }: FetchOption) { const response = await client.query({ query: gql`\n query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) { domains(filters: $filters, pagination: $pagination, sortings: $sortings) { items { id\n name\n description\n subdomain\n parent { id\n name\n }\n ownerUser { id\n name\n email\n }\n extType\n theme\n timezone\n attributes\n updatedAt\n }\n total\n }\n }\n `,\n variables: { filters,\n pagination: { page, limit },\n sortings\n }\n })\n\n return { total: response.data.domains.total || 0,\n records: response.data.domains.items || []\n }\n }\n\n async onUpdateDomains() { let patches = this.grist.dirtyRecords\n\n if (patches && patches.length) { patches = patches.map(domain => { let patchField = domain.id ? { id: domain.id } : {}\n const dirtyFields = domain.__dirtyfields__\n for (let key in dirtyFields) { if (key == 'ownerUser') { const ownerUser = dirtyFields[key].after\n patchField['owner'] = ownerUser.id || ''\n } else { patchField[key] = dirtyFields[key].after\n }\n }\n\n return { ...patchField\n }\n })\n\n const response = await client.mutate({ mutation: gql`\n mutation updateDomains($patches: [DomainPatch!]!) { updateDomains(patches: $patches)\n }\n `,\n variables: { patches }\n })\n\n if (!response.errors) { this.grist.fetch()\n return this.showToast(i18next.t('text.updated_successfully'))\n }\n }\n }\n\n async onCreateDomain() { openPopup(\n html`\n <create-domain-popup\n @fetch-data=${async () => { this.grist.fetch()\n }}\n ></create-domain-popup>\n `,\n { size: 'small',\n title: `${i18next.t('title.create_domain')}`\n }\n )\n }\n\n async getAttributeSetForDomain() { const response = await client.query({ query: gql`\n query { attributeSet: attributeSetByEntity(entity: \"Domain\") { entity\n description\n items { name\n description\n tag\n type\n active\n hidden\n options\n }\n }\n }\n `\n })\n\n return response.data?.attributeSet || {}\n }\n\n async getDomainTypes() { if (!this.domainTypes) { const response = await client.query({ query: gql`\n query { domainTypes\n }\n `\n })\n\n this.domainTypes = response.data?.domainTypes || ['domain']\n }\n\n return this.domainTypes || []\n }\n\n showToast(message) { document.dispatchEvent(new CustomEvent('notify', { detail: { message } }))\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"domain-management.js","sourceRoot":"","sources":["../../../client/pages/domain/domain-management.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\n\nimport '@operato/data-grist/ox-grist.js'\nimport '@operato/data-grist/ox-filters-form.js'\nimport '@operato/context/ox-context-page-toolbar.js'\nimport '@operato/attribute/ox-attribute-view.js'\nimport '../../components/create-domain-popup.js'\n\nimport gql from 'graphql-tag'\nimport { css, html } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\nimport { DataGrist } from '@operato/data-grist/ox-grist.js'\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { openPopup } from '@operato/layout'\nimport { OxPrompt } from '@operato/popup/ox-prompt.js'\nimport { PageView } from '@operato/shell'\nimport { CommonHeaderStyles, CommonGristStyles, ScrollbarStyles } from '@operato/styles'\nimport { isMobileDevice } from '@operato/utils'\nimport { p13n } from '@operato/p13n'\nimport { FetchOption } from '@operato/data-grist'\n\n@customElement('domain-management')\nexport class DomainManagement extends p13n(localize(i18next)(PageView)) { static styles = [\n CommonGristStyles,\n CommonHeaderStyles,\n ScrollbarStyles,\n css`\n :host { display: flex;\n flex-direction: column;\n\n overflow: hidden;\n }\n\n ox-grist { overflow-y: auto;\n flex: 1;\n }\n `\n ]\n\n @property({ type: Boolean }) active: boolean = false\n @property({ type: Object }) config: any\n @property({ type: String }) mode: 'CARD' | 'LIST' | 'GRID' = isMobileDevice() ? 'CARD' : 'GRID'\n\n private domainTypes?: string[]\n\n @query('ox-grist') private grist!: DataGrist\n\n get context() { return { title: i18next.t('text.domain management'),\n search: { handler: (search: string) => { this.grist.searchText = search\n },\n value: this.grist?.searchText || ''\n },\n filter: { handler: () => { this.grist.toggleHeadroom()\n }\n },\n actions: [\n { title: i18next.t('button.add'),\n action: this.onCreateDomain.bind(this),\n icon: 'add'\n },\n { title: i18next.t('button.save'),\n action: this.onUpdateDomains.bind(this),\n icon: 'save'\n }\n ],\n toolbar: false\n }\n }\n\n render() { return html`\n <ox-grist\n .mode=${this.mode}\n .config=${this.config}\n .fetchHandler=${this.fetchHandler.bind(this)}\n .personalConfigProvider=${this.getPagePreferenceProvider('ox-grist')!}\n >\n <div slot=\"headroom\" class=\"header\">\n <ox-context-page-toolbar class=\"actions\" .context=${this.context}></ox-context-page-toolbar>\n </div>\n\n <ox-grist-personalizer slot=\"setting\"></ox-grist-personalizer>\n </ox-grist>\n `\n }\n\n async pageInitialized() { this.config = { rows: { appendable: false\n },\n columns: [\n { type: 'gutter', gutterName: 'sequence' },\n { type: 'gutter',\n gutterName: 'button',\n icon: 'assignment',\n title: i18next.t('title.open attributes view'),\n handlers: { click: async (columns, data, column, record, rowIndex) => { const attributeSet = await this.getAttributeSetForDomain()\n\n openPopup(\n html`\n <ox-attribute-view\n .attributeSet=${attributeSet}\n .value=${record.attributes}\n style=\"background-color: white;\"\n ></ox-attribute-view>\n `,\n { backdrop: true,\n size: 'large',\n title: record.name + ' ' + i18next.t('title.attributes')\n }\n )\n }\n }\n },\n { type: 'gutter',\n gutterName: 'button',\n icon: 'domain',\n title: i18next.t('title.move to this domain'),\n handlers: { click: (_columns, _data, _column, record, _rowIndex) => { if (record.id) { const subdomain = record.subdomain\n const extType = record.extType || 'domain'\n location.pathname = `/${extType}/${subdomain}/users`\n }\n }\n }\n },\n {\n type: 'string',\n name: 'name',\n header: i18next.t('field.name'),\n record: {\n editable: true\n },\n filter: 'search',\n sortable: true,\n width: 200\n },\n { type: 'string',\n name: 'description',\n header: i18next.t('field.description'),\n record: { editable: true\n },\n filter: 'search',\n width: 200\n },\n {\n type: 'string',\n name: 'subdomain',\n header: i18next.t('field.subdomain'),\n record: {\n editable: true\n },\n filter: 'search',\n width: 200\n },\n { type: 'resource-object',\n name: 'parent',\n header: i18next.t('field.parent-domain'),\n record: { editable: true,\n options: { title: i18next.t('text.select domain'),\n queryName: 'domains',\n nameField: 'name',\n descriptionField: 'description',\n select: [\n { name: 'id', hidden: true },\n { name: 'name', header: i18next.t('field.name'), filter: 'search' },\n { name: 'description', header: i18next.t('field.description'), filter: 'search' }\n ],\n list: { fields: ['name', 'description'] }\n }\n },\n width: 140\n },\n { type: 'resource-object',\n name: 'ownerUser',\n header: i18next.t('field.owner-user'),\n record: { editable: true,\n options: { title: i18next.t('title.lookup user'),\n queryName: 'users',\n nameField: 'name',\n descriptionField: 'email',\n select: [\n { name: 'id', hidden: true },\n { name: 'name', header: i18next.t('field.name'), filter: 'search' },\n { name: 'email', header: i18next.t('field.email'), filter: 'search' }\n ],\n filters: [{ name: 'userType', operator: 'eq', value: 'user' }],\n list: { fields: ['name', 'email'] }\n }\n },\n width: 140\n },\n { type: 'select',\n name: 'extType',\n header: i18next.t('field.type'),\n record: { editable: true,\n options: async () => { return ['', ...(await this.getDomainTypes())]\n }\n },\n width: 100\n },\n {\n type: 'select',\n name: 'theme',\n header: i18next.t('field.theme'),\n record: {\n editable: true,\n options: ['', 'ocean-blue', 'forest-green', 'sunset-orange', 'royal-purple', 'cherry-red']\n },\n width: 140\n },\n { type: 'timezone',\n name: 'timezone',\n header: i18next.t('field.timezone'),\n record: { editable: true\n },\n width: 120\n },\n { type: 'attributes',\n name: 'attributes',\n header: i18next.t('field.attributes'),\n record: { editable: true,\n options: async () => { return { objectified: true,\n attributeSet: await this.getAttributeSetForDomain()\n }\n }\n },\n width: 120\n },\n { type: 'datetime',\n name: 'updatedAt',\n header: i18next.t('field.updated_at'),\n width: 180\n }\n ]\n }\n }\n\n async pageUpdated(changes, lifecycle) { if (this.active) { await this.updateComplete\n\n this.grist.fetch()\n }\n }\n\n async fetchHandler({ page, limit, sortings = [], filters = [] }: FetchOption) { const response = await client.query({ query: gql`\n query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) { domains(filters: $filters, pagination: $pagination, sortings: $sortings) { items { id\n name\n description\n subdomain\n parent { id\n name\n }\n ownerUser { id\n name\n email\n }\n extType\n theme\n timezone\n attributes\n updatedAt\n }\n total\n }\n }\n `,\n variables: { filters,\n pagination: { page, limit },\n sortings\n }\n })\n\n return { total: response.data.domains.total || 0,\n records: response.data.domains.items || []\n }\n }\n\n async onUpdateDomains() {\n let rawPatches = this.grist.dirtyRecords\n if (!rawPatches || !rawPatches.length) return\n\n // 1. 서브도메인 변경 여부 감지 및 최고 단계 안전장치 (URL/북마크 파괴 방지)\n const subdomainChanges = rawPatches.filter(domain => domain.__dirtyfields__?.subdomain)\n if (subdomainChanges.length > 0) {\n for (const domain of subdomainChanges) {\n const oldSub = domain.__dirtyfields__?.subdomain?.before || domain.subdomain\n const newSub = domain.__dirtyfields__?.subdomain?.after?.trim()\n\n // 1-1. 'system' 도메인의 서브도메인은 수정 불가\n if (oldSub === 'system' || domain.systemFlag) {\n await OxPrompt.open({\n type: 'error',\n title: i18next.t('title.invalid input', { defaultValue: 'Invalid Input' }),\n text: i18next.t('error.cannot_modify_system_subdomain', {\n defaultValue: \"The 'system' subdomain cannot be modified.\"\n }),\n confirmButton: { text: i18next.t('button.confirm', { defaultValue: 'Confirm' }) }\n })\n return\n }\n\n // 1-2. 다른 도메인을 'system'으로 변경하려는 시도 차단\n if (newSub?.toLowerCase() === 'system') {\n await OxPrompt.open({\n type: 'error',\n title: i18next.t('title.invalid input', { defaultValue: 'Invalid Input' }),\n text: i18next.t('error.system_subdomain_reserved', {\n defaultValue: \"The 'system' subdomain is reserved and cannot be used.\"\n }),\n confirmButton: { text: i18next.t('button.confirm', { defaultValue: 'Confirm' }) }\n })\n return\n }\n\n // 1-3. 빈 서브도메인 검증\n if (!newSub) {\n await OxPrompt.open({\n type: 'error',\n title: i18next.t('title.invalid input', { defaultValue: 'Invalid Input' }),\n text: i18next.t('error.value is empty', { value: i18next.t('field.subdomain'), defaultValue: 'Subdomain cannot be empty.' }),\n confirmButton: { text: i18next.t('button.confirm', { defaultValue: 'Confirm' }) }\n })\n return\n }\n }\n\n // 서브도메인 변경 시 전체 URL 경로 변경에 대한 명시적 경고\n const subChangeList = subdomainChanges\n .map(d => {\n const before = d.__dirtyfields__?.subdomain?.before || d.subdomain\n const after = d.__dirtyfields__?.subdomain?.after\n return `• ${d.name || d.id}: ${before} ➔ ${after}`\n })\n .join('\\n')\n\n const confirmed = await OxPrompt.open({\n type: 'warning',\n title: i18next.t('text.are_you_sure', { defaultValue: 'Are you sure?' }),\n text: `${i18next.t('text.subdomain_change_critical_warning', {\n defaultValue: 'Warning: Changing the subdomain will alter the full access URL (/{type}/{subdomain}/...) and may invalidate existing external links, bookmarks, and active user sessions. Please proceed with caution.'\n })}\\n\\n${subChangeList}`,\n confirmButton: { text: i18next.t('button.save', { defaultValue: 'Save' }) },\n cancelButton: { text: i18next.t('button.cancel', { defaultValue: 'Cancel' }) }\n })\n\n if (!confirmed) return\n }\n\n // 2. 도메인 명칭(name) 변경 시 유효성 검증\n const nameChanges = rawPatches.filter(domain => domain.__dirtyfields__?.name)\n if (nameChanges.length > 0) {\n for (const domain of nameChanges) {\n const newName = domain.__dirtyfields__?.name?.after?.trim()\n if (!newName) {\n await OxPrompt.open({\n type: 'error',\n title: i18next.t('title.invalid input', { defaultValue: 'Invalid Input' }),\n text: i18next.t('error.value is empty', { value: i18next.t('field.name'), defaultValue: 'Domain name cannot be empty.' }),\n confirmButton: { text: i18next.t('button.confirm', { defaultValue: 'Confirm' }) }\n })\n return\n }\n }\n }\n\n const patches = rawPatches.map(domain => {\n let patchField: any = domain.id ? { id: domain.id } : {}\n const dirtyFields = domain.__dirtyfields__\n for (let key in dirtyFields) {\n if (key == 'ownerUser') {\n const ownerUser = dirtyFields[key].after\n patchField['owner'] = ownerUser?.id || ''\n } else if (key == 'name') {\n patchField[key] = dirtyFields[key].after?.trim()\n } else if (key == 'subdomain') {\n patchField[key] = dirtyFields[key].after?.trim()\n } else {\n patchField[key] = dirtyFields[key].after\n }\n }\n return patchField\n })\n\n try {\n const response = await client.mutate({\n mutation: gql`\n mutation updateDomains($patches: [DomainPatch!]!) {\n updateDomains(patches: $patches)\n }\n `,\n variables: { patches }\n })\n\n if (!response.errors?.length) {\n this.grist.fetch()\n return this.showToast(i18next.t('text.updated_successfully'))\n }\n } catch (err: any) {\n await OxPrompt.open({\n type: 'error',\n title: i18next.t('text.failed', { defaultValue: 'Failed' }),\n text: err?.message || String(err),\n confirmButton: { text: i18next.t('button.confirm', { defaultValue: 'Confirm' }) }\n })\n }\n }\n\n async onCreateDomain() { openPopup(\n html`\n <create-domain-popup\n @fetch-data=${async () => { this.grist.fetch()\n }}\n ></create-domain-popup>\n `,\n { size: 'small',\n title: `${i18next.t('title.create_domain')}`\n }\n )\n }\n\n async getAttributeSetForDomain() { const response = await client.query({ query: gql`\n query { attributeSet: attributeSetByEntity(entity: \"Domain\") { entity\n description\n items { name\n description\n tag\n type\n active\n hidden\n options\n }\n }\n }\n `\n })\n\n return response.data?.attributeSet || {}\n }\n\n async getDomainTypes() { if (!this.domainTypes) { const response = await client.query({ query: gql`\n query { domainTypes\n }\n `\n })\n\n this.domainTypes = response.data?.domainTypes || ['domain']\n }\n\n return this.domainTypes || []\n }\n\n showToast(message) { document.dispatchEvent(new CustomEvent('notify', { detail: { message } }))\n }\n}\n"]}
|