@things-factory/auth-ui 10.1.259 → 10.1.261

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.
Files changed (44) hide show
  1. package/dist-client/pages/appliance/home.d.ts +0 -1
  2. package/dist-client/pages/appliance/home.js +5 -6
  3. package/dist-client/pages/appliance/home.js.map +1 -1
  4. package/dist-client/pages/application/applications.d.ts +0 -1
  5. package/dist-client/pages/application/applications.js +5 -6
  6. package/dist-client/pages/application/applications.js.map +1 -1
  7. package/dist-client/pages/audit/audit-page.d.ts +15 -14
  8. package/dist-client/pages/audit/audit-page.js +107 -139
  9. package/dist-client/pages/audit/audit-page.js.map +1 -1
  10. package/dist-client/pages/auth-provider/auth-provider-management.d.ts +9 -4
  11. package/dist-client/pages/auth-provider/auth-provider-management.js +29 -13
  12. package/dist-client/pages/auth-provider/auth-provider-management.js.map +1 -1
  13. package/dist-client/pages/domain-owner/domain-owner-management.js +2 -2
  14. package/dist-client/pages/domain-owner/domain-owner-management.js.map +1 -1
  15. package/dist-client/pages/list-address.test.d.ts +1 -0
  16. package/dist-client/pages/list-address.test.js +51 -0
  17. package/dist-client/pages/list-address.test.js.map +1 -0
  18. package/dist-client/pages/role/role-inheritance-shown.test.js +7 -6
  19. package/dist-client/pages/role/role-inheritance-shown.test.js.map +1 -1
  20. package/dist-client/pages/role/role-list-page.d.ts +20 -27
  21. package/dist-client/pages/role/role-list-page.js +49 -136
  22. package/dist-client/pages/role/role-list-page.js.map +1 -1
  23. package/dist-client/pages/user/user-list-page.d.ts +0 -1
  24. package/dist-client/pages/user/user-list-page.js +5 -6
  25. package/dist-client/pages/user/user-list-page.js.map +1 -1
  26. package/dist-client/tsconfig.tsbuildinfo +1 -1
  27. package/dist-client/utils/audit-words.d.ts +28 -0
  28. package/dist-client/utils/audit-words.js +36 -0
  29. package/dist-client/utils/audit-words.js.map +1 -1
  30. package/dist-client/utils/audit-words.test.js +33 -1
  31. package/dist-client/utils/audit-words.test.js.map +1 -1
  32. package/dist-client/utils/role-scope.d.ts +15 -0
  33. package/dist-client/utils/role-scope.js +13 -0
  34. package/dist-client/utils/role-scope.js.map +1 -0
  35. package/dist-client/utils/role-scope.test.d.ts +1 -0
  36. package/dist-client/utils/role-scope.test.js +18 -0
  37. package/dist-client/utils/role-scope.test.js.map +1 -0
  38. package/package.json +8 -7
  39. package/translations/en.json +1 -1
  40. package/translations/es.json +1 -1
  41. package/translations/ja.json +1 -1
  42. package/translations/ko.json +1 -1
  43. package/translations/ms.json +1 -1
  44. package/translations/zh.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"audit-page.js","sourceRoot":"","sources":["../../../client/pages/audit/audit-page.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@operato/data-grist'\nimport '@operato/input/ox-input-select-buttons.js'\n\nimport gql from 'graphql-tag'\nimport { css, html, nothing } from 'lit'\nimport type { CSSResultGroup } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\nimport { keyed } from 'lit/directives/keyed.js'\n\nimport { client, QueryController } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { formatWhen } from '@operato/utils/when.js'\nimport { p13n } from '@operato/p13n'\nimport { PageView } from '@operato/shell'\nimport { ButtonStyles, CommonGristStyles, CommonHeaderStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles'\nimport { isMobileDevice } from '@operato/utils'\n\nimport type { DataGrist, FetchOption } from '@operato/data-grist'\n\nimport { statusRenderer } from '../../components/user-status-renderer.js'\nimport { doorWords, lastDays, recordWords } from '../../utils/audit-words.js'\n\n/**\n * 감사 기록 (ADR-0141 §6.1) - who did what in this domain, read three ways: by person, by privilege,\n * and the requests one by one. A person's or a privilege's numbers open the requests behind them.\n *\n * Reading only. The audit has no door that changes a row (§4-6), so this screen has no action.\n */\n\ntype View = 'people' | 'doors' | 'records'\ntype Outcome = '' | 'denied' | 'error' | 'failed'\n\nconst PERIODS = [7, 30, 90]\nconst VIEWS: View[] = ['people', 'doors', 'records']\nconst OUTCOMES: Outcome[] = ['', 'denied', 'error', 'failed']\n\nconst AuditPageBase = p13n(localize(i18next)(PageView))\n\nfunction dateInputValue(date: Date) {\n const pad = (n: number) => String(n).padStart(2, '0')\n return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`\n}\n\n@customElement('audit-page')\nexport class AuditPage extends AuditPageBase {\n static styles: CSSResultGroup = [\n WorkSurfacePageStyles,\n ScrollbarStyles,\n CommonGristStyles,\n CommonHeaderStyles,\n ButtonStyles,\n css`\n .filters {\n flex-wrap: wrap;\n }\n\n [group] {\n display: flex;\n align-items: center;\n gap: var(--spacing-tiny, 2px);\n }\n\n input[type='date'] {\n height: var(--context-action-height, 28px);\n box-sizing: border-box;\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: var(--md-sys-shape-corner-small, 4px);\n background: var(--md-sys-color-surface-container-lowest);\n color: var(--md-sys-color-on-surface);\n font: inherit;\n font-size: var(--ui-t-body, 13px);\n padding: 0 var(--spacing-small, 4px);\n }\n\n [narrowed] {\n display: flex;\n align-items: center;\n gap: var(--spacing-small, 4px);\n font-size: var(--ui-t-body, 13px);\n color: var(--md-sys-color-on-surface);\n }\n\n [health] {\n margin-left: auto;\n font-size: var(--ui-t-body, 13px);\n color: var(--ui-crit, var(--md-sys-color-error));\n }\n `\n ]\n\n @property({ type: String }) mode: 'CARD' | 'GRID' | 'LIST' = isMobileDevice() ? 'LIST' : 'GRID'\n\n @state() private view: View = 'people'\n @state() private days: number | null = 30\n @state() private from: Date = lastDays(30).from\n @state() private to: Date = new Date()\n @state() private actor?: { id: string; name: string }\n @state() private door?: string\n @state() private outcome: Outcome = ''\n /** How many records each outcome chip would show under the other conditions, counted by the records' own door. */\n\n /*\n * The outcome chips' numbers - the records' own door asked for its total once per outcome, under the period, the\n * person and the privilege narrowed to, in one request. The chips keep their numbers while new ones are read.\n */\n private outcomes = new QueryController(\n this,\n gql`\n query (${OUTCOMES.map((_, at) => `$f${at}: AuditRecordFilter!`).join(', ')}) {\n ${OUTCOMES.map((_, at) => `c${at}: auditRecords(filter: $f${at}) { total }`).join('\\n')}\n }\n `,\n {\n variables: () => {\n if (this.view !== 'records') return undefined\n const filter = { from: this.from.toISOString(), to: this.to.toISOString(), actorId: this.actor?.id, door: this.door }\n return Object.fromEntries(OUTCOMES.map((outcome, at) => [`f${at}`, { ...filter, outcome: outcome || undefined, page: 1, limit: 1 }]))\n },\n keepPrevious: true\n }\n )\n\n private auditHealth = new QueryController(this, gql`{ auditHealth { failures since } }`)\n\n private get outcomeCounts(): Map<string, number> {\n const data = this.outcomes.data\n return new Map(OUTCOMES.map((outcome, at) => [outcome || 'all', data?.[`c${at}`]?.total ?? 0]))\n }\n\n private get health(): { failures: number; since: string } | 'unknown' | undefined {\n if (this.auditHealth.data?.auditHealth) return this.auditHealth.data.auditHealth\n return this.auditHealth.error || this.auditHealth.data ? 'unknown' : undefined\n }\n\n @query('ox-grist') private grist!: DataGrist\n\n get context() {\n return {\n title: i18next.t('audit.title'),\n help: 'auth/audit',\n filter: {\n handler: () => this.grist.toggleHeadroom()\n }\n }\n }\n\n render() {\n return html`${keyed(\n this.view,\n html`<ox-grist class=\"page-fill\" .mode=${this.mode} .config=${this.configOf(this.view)} .fetchHandler=${this.fetchHandler.bind(this)}>\n <div slot=\"headroom\" class=\"header\">\n <div class=\"filters\">${this.renderControls()}</div>\n </div>\n </ox-grist>`\n )}`\n }\n\n private renderControls() {\n const t = i18next.t.bind(i18next)\n /* One of each is always chosen: a press on the chosen chip leaves it chosen. */\n const choose = (e: CustomEvent, chosen: string | undefined, pick: (value: string) => void) => {\n if (e.detail) pick(e.detail)\n else (e.target as any).value = chosen\n }\n\n return html`\n <ox-input-select-buttons\n .options=${VIEWS.map(view => ({ value: view, display: t(`audit.view.${view}`) }))}\n .value=${this.view}\n @change=${(e: CustomEvent) => choose(e, this.view, view => this.show(view as View))}\n ></ox-input-select-buttons>\n\n <div group>\n <ox-input-select-buttons\n .options=${PERIODS.map(days => ({ value: String(days), display: t('audit.period.days', { count: days }) }))}\n .value=${this.days ? String(this.days) : undefined}\n @change=${(e: CustomEvent) => choose(e, this.days ? String(this.days) : undefined, days => this.lastDays(Number(days)))}\n ></ox-input-select-buttons>\n <input type=\"date\" aria-label=${t('audit.period.from')} .value=${dateInputValue(this.from)} @change=${(e: Event) => this.pick('from', e)} />\n <span>~</span>\n <input type=\"date\" aria-label=${t('audit.period.to')} .value=${dateInputValue(this.to)} @change=${(e: Event) => this.pick('to', e)} />\n </div>\n\n ${this.view === 'records'\n ? html`<ox-input-select-buttons\n .options=${OUTCOMES.map(outcome => ({\n value: outcome || 'all',\n display: t(outcome ? `audit.outcome.${outcome}` : 'audit.outcome.all'),\n count: this.outcomeCounts.get(outcome || 'all') ?? 0\n }))}\n .value=${this.outcome || 'all'}\n @change=${(e: CustomEvent) => choose(e, this.outcome || 'all', outcome => this.narrow({ outcome: (outcome === 'all' ? '' : outcome) as Outcome }))}\n ></ox-input-select-buttons>`\n : nothing}\n ${this.view === 'records' && this.actor\n ? html`<span narrowed>${this.actor.name}<button quiet small @click=${() => this.narrow({ actor: undefined })}>${t('audit.button.all-people')}</button></span>`\n : nothing}\n ${this.view === 'records' && this.door\n ? html`<span narrowed>${doorWords(t, this.door)}<button quiet small @click=${() => this.narrow({ door: undefined })}>${t('audit.button.all-privileges')}</button></span>`\n : nothing}\n ${this.renderHealth()}\n `\n }\n\n /* Only what is wrong is said: failures, or that they could not be counted. Never a 0 for \"unknown\". */\n private renderHealth() {\n const health = this.health\n if (health === 'unknown') return html`<span health>${i18next.t('audit.health.unknown')}</span>`\n if (!health?.failures) return nothing\n return html`<span health>${i18next.t('audit.health.failures', { count: health.failures, since: formatWhen(health.since, { lang: i18next.language, style: 'datetime' }) ?? '' })}</span>`\n }\n\n private show(view: View) {\n this.view = view\n }\n\n private lastDays(days: number) {\n const { from, to } = lastDays(days)\n this.days = days\n this.from = from\n this.to = to\n this.grist?.fetch()\n }\n\n private pick(which: 'from' | 'to', event: Event) {\n const value = (event.target as HTMLInputElement).value\n if (!value) return\n const [year, month, day] = value.split('-').map(Number)\n this[which] = which === 'from' ? new Date(year, month - 1, day, 0, 0, 0) : new Date(year, month - 1, day, 23, 59, 59, 999)\n this.days = null\n this.grist?.fetch()\n }\n\n private narrow(change: { actor?: { id: string; name: string }; door?: string; outcome?: Outcome }) {\n Object.assign(this, change)\n if (this.view !== 'records') this.view = 'records'\n else this.grist?.fetch()\n }\n\n async pageUpdated(_changes: any, _lifecycle: any) {\n if (this.active) {\n await this.updateComplete\n this.grist?.fetch()\n }\n }\n\n private configOf(view: View) {\n const t = i18next.t.bind(i18next)\n const number = (name: string, header: string, click?: (record: any) => void) => ({\n type: 'integer',\n name,\n header,\n record: { align: 'right', editable: false },\n width: 90,\n ...(click ? { handlers: { click: (_c: any, _d: any, _col: any, record: any) => record && click(record) } } : {})\n })\n\n if (view === 'people') {\n const person = (record: any) => ({ id: record.id, name: record.name || record.email })\n return {\n rows: { appendable: false, selectable: false },\n pagination: { infinite: true },\n columns: [\n { type: 'gutter', gutterName: 'sequence' },\n {\n type: 'string',\n name: 'name',\n header: t('field.name'),\n record: { editable: false },\n width: 140,\n handlers: { click: (_c: any, _d: any, _col: any, record: any) => record && this.narrow({ actor: person(record), door: undefined, outcome: '' }) }\n },\n { type: 'string', name: 'email', header: t('field.email'), record: { editable: false }, width: 200 },\n { type: 'string', name: 'roles', header: t('field.roles'), record: { editable: false }, width: 200 },\n { type: 'string', name: 'status', header: t('field.status'), record: { editable: false, align: 'center', renderer: statusRenderer(() => 0) }, width: 80 },\n { type: 'datetime', name: 'lastCheckinAt', header: t('audit.field.last-checkin'), record: { editable: false }, width: 160 },\n number('checkins', t('audit.field.checkins')),\n number('failedSignins', t('audit.field.failed-signins'), record => this.narrow({ actor: person(record), door: undefined, outcome: 'failed' })),\n number('granted', t('audit.field.granted'), record => this.narrow({ actor: person(record), door: undefined, outcome: '' })),\n number('denied', t('audit.field.denied'), record => this.narrow({ actor: person(record), door: undefined, outcome: 'denied' }))\n ]\n }\n }\n\n if (view === 'doors') {\n return {\n rows: { appendable: false, selectable: false },\n pagination: { infinite: true },\n columns: [\n { type: 'gutter', gutterName: 'sequence' },\n {\n type: 'string',\n name: 'doorWords',\n header: t('audit.field.privilege'),\n record: { editable: false },\n width: 240,\n handlers: { click: (_c: any, _d: any, _col: any, record: any) => record && this.narrow({ door: record.door, actor: undefined, outcome: '' }) }\n },\n number('people', t('audit.field.people')),\n number('granted', t('audit.field.granted'), record => this.narrow({ door: record.door, actor: undefined, outcome: '' })),\n number('denied', t('audit.field.denied'), record => this.narrow({ door: record.door, actor: undefined, outcome: 'denied' }))\n ]\n }\n }\n\n return {\n rows: { appendable: false, selectable: false },\n pagination: { pages: [50, 100, 200] },\n columns: [\n { type: 'gutter', gutterName: 'sequence' },\n { type: 'datetime', name: 'createdAt', header: t('audit.field.time'), record: { editable: false }, width: 160 },\n { type: 'string', name: 'actorName', header: t('audit.field.actor'), record: { editable: false }, width: 120 },\n { type: 'string', name: 'operation', header: t('audit.field.request'), record: { editable: false }, width: 200 },\n { type: 'string', name: 'what', header: t('audit.field.actions'), record: { editable: false }, width: 360 },\n { type: 'string', name: 'ip', header: t('audit.field.address'), record: { editable: false }, width: 120 },\n { type: 'integer', name: 'durationMs', header: t('audit.field.duration'), record: { editable: false, align: 'right' }, width: 80 }\n ]\n }\n }\n\n async fetchHandler({ page, limit }: FetchOption) {\n const t = i18next.t.bind(i18next)\n const period = { from: this.from.toISOString(), to: this.to.toISOString() }\n\n if (this.view === 'people') {\n const response = await client.query({\n query: gql`\n query ($from: DateTimeISO!, $to: DateTimeISO!) {\n auditPeople(from: $from, to: $to) {\n user {\n id\n name\n email\n status\n }\n roles\n lastCheckinAt\n checkins\n failedSignins\n granted\n denied\n }\n }\n `,\n variables: period,\n fetchPolicy: 'no-cache'\n })\n const people = response.data?.auditPeople || []\n const records = people\n .map((one: any) => ({\n ...one,\n id: one.user.id,\n name: one.user.name,\n email: one.user.email,\n roles: one.roles.join(', '),\n status: one.user.status\n }))\n .sort((a: any, b: any) => String(b.lastCheckinAt || '').localeCompare(String(a.lastCheckinAt || '')))\n return { total: records.length, records }\n }\n\n if (this.view === 'doors') {\n const response = await client.query({\n query: gql`\n query ($from: DateTimeISO!, $to: DateTimeISO!) {\n auditDoors(from: $from, to: $to) {\n door\n people\n granted\n denied\n }\n }\n `,\n variables: period,\n fetchPolicy: 'no-cache'\n })\n /* The doors used come first; the rest keep the server's order. */\n const used = (one: any) => one.granted + one.denied\n const records = (response.data?.auditDoors || [])\n .map((one: any) => ({ ...one, doorWords: doorWords(t, one.door) }))\n .sort((a: any, b: any) => used(b) - used(a))\n return { total: records.length, records }\n }\n\n const response = await client.query({\n query: gql`\n query ($filter: AuditRecordFilter!) {\n auditRecords(filter: $filter) {\n items {\n request {\n id\n createdAt\n actor {\n id\n name\n email\n }\n ip\n channel\n operationType\n operationName\n fields\n route\n durationMs\n }\n actions {\n kind\n door\n decision\n outcome\n code\n count\n objectId\n detail\n }\n }\n total\n }\n }\n `,\n variables: {\n filter: {\n ...period,\n actorId: this.actor?.id,\n door: this.door,\n outcome: this.outcome || undefined,\n page,\n limit\n }\n },\n fetchPolicy: 'no-cache'\n })\n\n const list = response.data?.auditRecords\n return {\n total: list?.total || 0,\n records: (list?.items || []).map(({ request, actions }: any) => ({\n id: request.id,\n createdAt: request.createdAt,\n actorName: request.actor?.name || request.actor?.email || '',\n what: recordWords(t, actions),\n operation: request.channel === 'graphql' ? [request.operationType, request.fields || request.operationName].filter(Boolean).join(' ') : request.route || '',\n ip: request.ip,\n durationMs: request.durationMs\n }))\n }\n }\n}\n"]}
1
+ {"version":3,"file":"audit-page.js","sourceRoot":"","sources":["../../../client/pages/audit/audit-page.ts"],"names":[],"mappings":";AAAA,OAAO,4BAA4B,CAAA;AACnC,OAAO,qBAAqB,CAAA;AAC5B,OAAO,2CAA2C,CAAA;AAElD,OAAO,GAAG,MAAM,aAAa,CAAA;AAC7B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AAExC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AACzE,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAE/C,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAC1D,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AAC7H,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAI/C,OAAO,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAA;AACzE,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAgB,SAAS,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AAanH,MAAM,OAAO,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;AAC3B,MAAM,KAAK,GAAW,CAAC,QAAQ,EAAE,OAAO,EAAE,SAAS,CAAC,CAAA;AACpD,MAAM,QAAQ,GAAc,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAA;AAE7D,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAA;AAGhD,IAAM,SAAS,GAAf,MAAM,SAAU,SAAQ,aAAa;IAArC;;QA4BuB,SAAI,GAA6B,cAAc,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAA;QAE/F;;;;;WAKG;QACc,SAAI,GAAS,QAAQ,CAAA;QACrB,UAAK,GAAiB,EAAE,CAAA;QAEjC,gBAAW,GAAG,IAAI,eAAe,CAAC,IAAI,EAAE,GAAG,CAAA,oCAAoC,CAAC,CAAA;IA4V1F,CAAC;aAlYQ,WAAM,GAAmB;QAC9B,qBAAqB;QACrB,eAAe;QACf,iBAAiB;QACjB,kBAAkB;QAClB,YAAY;QACZ,GAAG,CAAA;;;;;;;;;;;;;;;;;;KAkBF;KACF,AAzBY,CAyBZ;IAeD,IAAY,MAAM;QAChB,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,WAAW;YAAE,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,CAAA;QAChF,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAA;IAChF,CAAC;IAID,IAAI,OAAO;QACT,OAAO;YACL,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC;YAC/B,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE;gBACN,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE;aAC3C;SACF,CAAA;IACH,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAA,GAAG,KAAK,CACjB,IAAI,CAAC,IAAI,EACT,IAAI,CAAA;;gBAEM,IAAI,CAAC,IAAI;kBACP,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;wBAClB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;wBAC5B,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;gCACpB,IAAI,CAAC,MAAM;;;iCAGV,IAAI,CAAC,cAAc,EAAE;;kBAEpC,CACb,EAAE,CAAA;IACL,CAAC;IAEO,cAAc;QACpB,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACjC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAEhD,OAAO,IAAI,CAAA;;mBAEI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,cAAc,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;iBACxE,IAAI,CAAC,IAAI;kBACR,CAAC,CAAc,EAAE,EAAE;YAC3B,4EAA4E;YAC5E,IAAI,CAAC,CAAC,MAAM;gBAAE,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,MAAc,CAAA;;gBACpC,CAAC,CAAC,MAAc,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,CAAA;QAC1C,CAAC;;;;;QAKD,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK;YAChC,CAAC,CAAC,IAAI,CAAA,kBAAkB,KAAK,CAAC,IAAI,8BAA8B,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,IAAI,CAAC,CAAC,yBAAyB,CAAC,kBAAkB;YACzJ,CAAC,CAAC,OAAO;QACT,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI;YAC/B,CAAC,CAAC,IAAI,CAAA,kBAAkB,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,8BAA8B,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,IAAI,CAAC,CAAC,6BAA6B,CAAC,kBAAkB;YACpK,CAAC,CAAC,OAAO;QACT,IAAI,CAAC,YAAY,EAAE;KACtB,CAAA;IACH,CAAC;IAED,uGAAuG;IAC/F,YAAY;QAClB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;QAC1B,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,IAAI,CAAA,gBAAgB,OAAO,CAAC,CAAC,CAAC,sBAAsB,CAAC,SAAS,CAAA;QAC/F,IAAI,CAAC,MAAM,EAAE,QAAQ;YAAE,OAAO,OAAO,CAAA;QACrC,OAAO,IAAI,CAAA,gBAAgB,OAAO,CAAC,CAAC,CAAC,uBAAuB,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAA;IAC1L,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,MAAM,CAAC,MAAkF;QACrG,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC5B,IAAI,CAAC,IAAI,GAAG,SAAS,CAAA;YACrB,MAAM,IAAI,CAAC,cAAc,CAAA;QAC3B,CAAC;QACD,MAAM,MAAM,GAA4B,EAAE,GAAG,MAAM,EAAE,GAAG,CAAC,SAAS,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAA;QAC3H,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACjC,MAAM,OAAO,GAAG;YACd,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,GAAe,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACrF,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;SACjH,CAAA;QACD,IAAI,CAAC,KAAK,EAAE,aAAa,CAAC,IAAI,WAAW,CAAC,qBAAqB,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,CAAC,CAAC,CAAA;IACjJ,CAAC;IAED;;;;OAIG;IACK,aAAa,CAAC,IAAU;QAC9B,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACjC,MAAM,YAAY,GAAG,CAAC,IAAY,EAAE,MAAc,EAAE,MAA+B,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA;QAC7K,OAAO;YACL,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,oBAAoB,CAAC,EAAE;gBAC5C,IAAI,EAAE,gBAAgB;gBACtB,QAAQ,EAAE,IAAI;gBACd,KAAK,EAAE,EAAE;gBACT,KAAK,EAAE,MAAM,CAAC,kBAAkB,CAAC;gBACjC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,mBAAmB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;aAC1G,CAAC;YACF,YAAY,CAAC,QAAQ,EAAE,CAAC,CAAC,oBAAoB,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;YACtF,YAAY,CAAC,SAAS,EAAE,CAAC,CAAC,oBAAoB,CAAC,EAAE;gBAC/C,IAAI,EAAE,gBAAgB;gBACtB,QAAQ,EAAE,IAAI;gBACd,KAAK,EAAE,EAAE;gBACT,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,IAAI,KAAK,SAAS;gBAC1B,OAAO,EAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,IAAI,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,iBAAiB,OAAO,EAAE,CAAC,CAAC,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC;aACxI,CAAC;YACF,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC,mBAAmB,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;YAC/F,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,uBAAuB,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;SACnG,CAAA;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,YAAY,CAAC,EAAE,OAAO,GAAG,EAAE,EAAe;QAC9C,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;YAAE,OAAO,EAAE,CAAA;QACtC,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,YAAY,CAAC,OAAO,CAAC,CAAA;QACvD,MAAM,MAAM,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,WAAW,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,CAAA;QAC3F,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;YAClC,KAAK,EAAE,GAAG,CAAA;iBACC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,sBAAsB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;YACtE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,4BAA4B,EAAE,aAAa,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;;OAE1F;YACD,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YACzI,WAAW,EAAE,UAAU;SACxB,CAAC,CAAA;QACF,IAAI,QAAQ,CAAC,MAAM,EAAE,MAAM;YAAE,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;QACrD,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,OAAO,IAAI,KAAK,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAClI,CAAC;IAEO,QAAQ,CAAC,IAAU;QACzB,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACjC,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,MAAc,EAAE,KAA6B,EAAE,EAAE,CAAC,CAAC;YAC/E,IAAI,EAAE,SAAS;YACf,IAAI;YACJ,MAAM;YACN,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE;YAC3C,KAAK,EAAE,EAAE;YACT,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,EAAO,EAAE,EAAO,EAAE,IAAS,EAAE,MAAW,EAAE,EAAE,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACjH,CAAC,CAAA;QAEF,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtB,MAAM,MAAM,GAAG,CAAC,MAAW,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC,CAAA;YACtF,OAAO;gBACL,IAAI,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE;gBAC9C,UAAU,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC9B,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE;oBAC1C;wBACE,IAAI,EAAE,QAAQ;wBACd,IAAI,EAAE,MAAM;wBACZ,MAAM,EAAE,CAAC,CAAC,YAAY,CAAC;wBACvB,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE;wBAC3B,KAAK,EAAE,GAAG;wBACV,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,EAAO,EAAE,EAAO,EAAE,IAAS,EAAE,MAAW,EAAE,EAAE,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,EAAE;qBAClJ;oBACD,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE;oBACpG,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE;oBACpG,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,cAAc,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;oBACzJ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,CAAC,CAAC,0BAA0B,CAAC,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE;oBAC3H,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,sBAAsB,CAAC,CAAC;oBAC7C,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,4BAA4B,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;oBAC9I,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;oBAC3H,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;oBAC/H,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;iBAC5B;aACF,CAAA;QACH,CAAC;QAED,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YACrB,OAAO;gBACL,IAAI,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE;gBAC9C,UAAU,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC9B,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE;oBAC1C;wBACE,IAAI,EAAE,QAAQ;wBACd,IAAI,EAAE,WAAW;wBACjB,MAAM,EAAE,CAAC,CAAC,uBAAuB,CAAC;wBAClC,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE;wBAC3B,KAAK,EAAE,GAAG;wBACV,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,EAAO,EAAE,EAAO,EAAE,IAAS,EAAE,MAAW,EAAE,EAAE,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,EAAE;qBAC/I;oBACD,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,oBAAoB,CAAC,CAAC;oBACzC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;oBACxH,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;oBAC5H,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;iBAC5B;aACF,CAAA;QACH,CAAC;QAED,OAAO;YACL,IAAI,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE;YAC9C,UAAU,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE;YACrC,OAAO,EAAE;gBACP,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE;gBAC1C,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC,kBAAkB,CAAC,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE;gBAC/G,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE;gBAC9G,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC,qBAAqB,CAAC,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE;gBAChH,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,qBAAqB,CAAC,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE;gBAC3G,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,qBAAqB,CAAC,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE;gBACzG,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC,CAAC,sBAAsB,CAAC,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;gBAClI,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;aAC5B;SACF,CAAA;IACH,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,GAAG,EAAE,EAAe;QAC3D,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACjC,IAAI,CAAC,KAAK,GAAG,OAAuB,CAAA;QACpC,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,YAAY,CAAC,OAAO,CAAC,CAAA;QAChE,MAAM,MAAM,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,WAAW,EAAE,EAAE,CAAA;QAEjE,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC3B,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;gBAClC,KAAK,EAAE,GAAG,CAAA;;;;;;;;;;;;;;;;;SAiBT;gBACD,SAAS,EAAE,MAAM;gBACjB,WAAW,EAAE,UAAU;aACxB,CAAC,CAAA;YACF,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,WAAW,IAAI,EAAE,CAAA;YAC/C,MAAM,OAAO,GAAG,MAAM;iBACnB,GAAG,CAAC,CAAC,GAAQ,EAAE,EAAE,CAAC,CAAC;gBAClB,GAAG,GAAG;gBACN,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE;gBACf,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI;gBACnB,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK;gBACrB,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;gBAC3B,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM;aACxB,CAAC,CAAC;iBACF,IAAI,CAAC,CAAC,CAAM,EAAE,CAAM,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;YACvG,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,CAAA;QAC3C,CAAC;QAED,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC1B,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;gBAClC,KAAK,EAAE,GAAG,CAAA;;;;;;;;;SAST;gBACD,SAAS,EAAE,MAAM;gBACjB,WAAW,EAAE,UAAU;aACxB,CAAC,CAAA;YACF,kEAAkE;YAClE,MAAM,IAAI,GAAG,CAAC,GAAQ,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,GAAG,GAAG,CAAC,MAAM,CAAA;YACnD,MAAM,OAAO,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,UAAU,IAAI,EAAE,CAAC;iBAC9C,GAAG,CAAC,CAAC,GAAQ,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;iBAClE,IAAI,CAAC,CAAC,CAAM,EAAE,CAAM,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;YAC9C,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,CAAA;QAC3C,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;YAClC,KAAK,EAAE,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAkCT;YACD,SAAS,EAAE;gBACT,MAAM,EAAE;oBACN,GAAG,MAAM;oBACT,OAAO,EAAE,KAAK,EAAE,EAAE;oBAClB,IAAI;oBACJ,OAAO,EAAE,OAAO,IAAI,SAAS;oBAC7B,IAAI;oBACJ,KAAK;iBACN;aACF;YACD,WAAW,EAAE,UAAU;SACxB,CAAC,CAAA;QAEF,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;QACxC,OAAO;YACL,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;YACvB,OAAO,EAAE,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAO,EAAE,EAAE,CAAC,CAAC;gBAC/D,EAAE,EAAE,OAAO,CAAC,EAAE;gBACd,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,SAAS,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE;gBAC5D,IAAI,EAAE,WAAW,CAAC,CAAC,EAAE,OAAO,CAAC;gBAC7B,SAAS,EAAE,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE;gBAC3J,EAAE,EAAE,OAAO,CAAC,EAAE;gBACd,UAAU,EAAE,OAAO,CAAC,UAAU;aAC/B,CAAC,CAAC;SACJ,CAAA;IACH,CAAC;;AAtW2B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;uCAAoE;AAQ9E;IAAhB,KAAK,EAAE;;uCAA8B;AACrB;IAAhB,KAAK,EAAE;;wCAAiC;AASd;IAA1B,KAAK,CAAC,UAAU,CAAC;;wCAA0B;AA9CjC,SAAS;IADrB,aAAa,CAAC,YAAY,CAAC;GACf,SAAS,CAmYrB","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@operato/data-grist'\nimport '@operato/input/ox-input-select-buttons.js'\n\nimport gql from 'graphql-tag'\nimport { css, html, nothing } from 'lit'\nimport type { CSSResultGroup } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\nimport { keyed } from 'lit/directives/keyed.js'\n\nimport { client, QueryController } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { formatWhen } from '@operato/utils/when.js'\nimport { p13n } from '@operato/p13n'\nimport { PageView } from '@operato/shell'\nimport { ButtonStyles, CommonGristStyles, CommonHeaderStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles'\nimport { isMobileDevice } from '@operato/utils'\n\nimport type { DataGrist, FetchOption } from '@operato/data-grist'\n\nimport { statusRenderer } from '../../components/user-status-renderer.js'\nimport { AUDIT_DEFAULT_DAYS, auditQueryOf, AuditOutcome, doorWords, recordWords } from '../../utils/audit-words.js'\n\n/**\n * 감사 기록 (ADR-0141 §6.1) - who did what in this domain, read three ways: by person, by privilege,\n * and the requests one by one. A person's or a privilege's numbers open the requests behind them.\n *\n * Reading only. The audit has no door that changes a row (§4-6), so this screen has no action.\n */\n\ntype View = 'people' | 'doors' | 'records'\ntype Outcome = AuditOutcome\ntype GridFilter = { name: string; operator: string; value: any }\n\nconst PERIODS = [7, 30, 90]\nconst VIEWS: View[] = ['people', 'doors', 'records']\nconst OUTCOMES: Outcome[] = ['', 'denied', 'error', 'failed']\n\nconst AuditPageBase = p13n(localize(i18next)(PageView))\n\n@customElement('audit-page')\nexport class AuditPage extends AuditPageBase {\n static styles: CSSResultGroup = [\n WorkSurfacePageStyles,\n ScrollbarStyles,\n CommonGristStyles,\n CommonHeaderStyles,\n ButtonStyles,\n css`\n .filters {\n flex-wrap: wrap;\n }\n\n [narrowed] {\n display: flex;\n align-items: center;\n gap: var(--spacing-small, 4px);\n font-size: var(--ui-t-body, 13px);\n color: var(--md-sys-color-on-surface);\n }\n\n [health] {\n margin-left: auto;\n font-size: var(--ui-t-body, 13px);\n color: var(--ui-crit, var(--md-sys-color-error));\n }\n `\n ]\n\n @property({ type: String }) mode: 'CARD' | 'GRID' | 'LIST' = isMobileDevice() ? 'LIST' : 'GRID'\n\n /*\n * The view is page state: it switches the whole list - its columns and its query - not a condition of one list.\n * The conditions - the period, the person and the privilege narrowed to, the outcome - are the grid's own filters,\n * kept in the address (FOOTER-BUTTON-REVIEW G09), and every view declares the same ones, so a period chosen on one\n * view holds on the others. `asked` is what the grid last read with; the narrowed person and privilege are said from it.\n */\n @state() private view: View = 'people'\n @state() private asked: GridFilter[] = []\n\n private auditHealth = new QueryController(this, gql`{ auditHealth { failures since } }`)\n\n private get health(): { failures: number; since: string } | 'unknown' | undefined {\n if (this.auditHealth.data?.auditHealth) return this.auditHealth.data.auditHealth\n return this.auditHealth.error || this.auditHealth.data ? 'unknown' : undefined\n }\n\n @query('ox-grist') private grist!: DataGrist\n\n get context() {\n return {\n title: i18next.t('audit.title'),\n help: 'auth/audit',\n filter: {\n handler: () => this.grist.toggleHeadroom()\n }\n }\n }\n\n render() {\n return html`${keyed(\n this.view,\n html`<ox-grist\n class=\"page-fill\"\n .mode=${this.mode}\n .config=${this.configOf(this.view)}\n .fetchHandler=${this.fetchHandler.bind(this)}\n .countHandler=${this.countHandler.bind(this)}\n ?url-params-sensitive=${this.active}\n >\n <div slot=\"headroom\" class=\"header\">\n <div class=\"filters\">${this.renderControls()}</div>\n </div>\n </ox-grist>`\n )}`\n }\n\n private renderControls() {\n const t = i18next.t.bind(i18next)\n const { actor, door } = auditQueryOf(this.asked)\n\n return html`\n <ox-input-select-buttons\n .options=${VIEWS.map(view => ({ value: view, display: t(`audit.view.${view}`) }))}\n .value=${this.view}\n @change=${(e: CustomEvent) => {\n /* One view is always shown: a press on the chosen chip leaves it chosen. */\n if (e.detail) this.view = e.detail as View\n else (e.target as any).value = this.view\n }}\n ></ox-input-select-buttons>\n\n <ox-filters-form without-search></ox-filters-form>\n\n ${this.view === 'records' && actor\n ? html`<span narrowed>${actor.name}<button quiet small @click=${() => this.narrow({ actor: undefined })}>${t('audit.button.all-people')}</button></span>`\n : nothing}\n ${this.view === 'records' && door\n ? html`<span narrowed>${doorWords(t, door)}<button quiet small @click=${() => this.narrow({ door: undefined })}>${t('audit.button.all-privileges')}</button></span>`\n : nothing}\n ${this.renderHealth()}\n `\n }\n\n /* Only what is wrong is said: failures, or that they could not be counted. Never a 0 for \"unknown\". */\n private renderHealth() {\n const health = this.health\n if (health === 'unknown') return html`<span health>${i18next.t('audit.health.unknown')}</span>`\n if (!health?.failures) return nothing\n return html`<span health>${i18next.t('audit.health.failures', { count: health.failures, since: formatWhen(health.since, { lang: i18next.language, style: 'datetime' }) ?? '' })}</span>`\n }\n\n /**\n * Narrow the records to a person, a privilege or an outcome - from a number on the people or privileges view, or the\n * 「모든 사람」·「모든 권한」 buttons. It shows the records and sets those of the grid's filters it names, keeping the\n * others (the period among them); the grid writes them to the address and reads again.\n */\n private async narrow(change: { actor?: { id: string; name: string }; door?: string; outcome?: Outcome }) {\n if (this.view !== 'records') {\n this.view = 'records'\n await this.updateComplete\n }\n const values: Record<string, unknown> = { ...change, ...('outcome' in change ? { outcome: change.outcome || 'all' } : {}) }\n const names = Object.keys(values)\n const filters = [\n ...(this.grist?.filters || []).filter((one: GridFilter) => !names.includes(one.name)),\n ...names.filter(name => values[name] !== undefined).map(name => ({ name, operator: 'eq', value: values[name] }))\n ]\n this.grist?.dispatchEvent(new CustomEvent('fetch-params-change', { bubbles: true, composed: true, detail: { filters, from: 'audit-narrow' } }))\n }\n\n /*\n * The conditions every view declares - hidden columns, since no column shows them. The day window and the dates are\n * drawn on every view; the outcome only on the records; the person and the privilege are said beside the filters\n * (`narrowed`) and set from the numbers, never typed.\n */\n private filterColumns(view: View) {\n const t = i18next.t.bind(i18next)\n const hiddenColumn = (name: string, header: string, filter: Record<string, unknown>) => ({ type: 'string', name, header, hidden: true, record: { editable: false }, filter })\n return [\n hiddenColumn('days', t('audit.period.range'), {\n type: 'select-buttons',\n operator: 'eq',\n label: '',\n value: String(AUDIT_DEFAULT_DAYS),\n options: PERIODS.map(days => ({ value: String(days), display: t('audit.period.days', { count: days }) }))\n }),\n hiddenColumn('period', t('audit.period.range'), { type: 'date', operator: 'between' }),\n hiddenColumn('outcome', t('audit.view.records'), {\n type: 'select-buttons',\n operator: 'eq',\n label: '',\n value: 'all',\n hidden: view !== 'records',\n options: OUTCOMES.map(outcome => ({ value: outcome || 'all', display: t(outcome ? `audit.outcome.${outcome}` : 'audit.outcome.all') }))\n }),\n hiddenColumn('actor', t('audit.field.actor'), { type: 'string', operator: 'eq', hidden: true }),\n hiddenColumn('door', t('audit.field.privilege'), { type: 'string', operator: 'eq', hidden: true })\n ]\n }\n\n /*\n * The outcome chips' numbers on the records view - the records' own door asked for its total once per outcome, under\n * the period, the person and the privilege narrowed to, in one request.\n */\n async countHandler({ filters = [] }: FetchOption) {\n if (this.view !== 'records') return {}\n const { from, to, actor, door } = auditQueryOf(filters)\n const filter = { from: from.toISOString(), to: to.toISOString(), actorId: actor?.id, door }\n const response = await client.query({\n query: gql`\n query (${OUTCOMES.map((_, at) => `$f${at}: AuditRecordFilter!`).join(', ')}) {\n ${OUTCOMES.map((_, at) => `c${at}: auditRecords(filter: $f${at}) { total }`).join('\\n')}\n }\n `,\n variables: Object.fromEntries(OUTCOMES.map((outcome, at) => [`f${at}`, { ...filter, outcome: outcome || undefined, page: 1, limit: 1 }])),\n fetchPolicy: 'no-cache'\n })\n if (response.errors?.length) throw response.errors[0]\n return { outcome: Object.fromEntries(OUTCOMES.map((outcome, at) => [outcome || 'all', response.data?.[`c${at}`]?.total ?? 0])) }\n }\n\n private configOf(view: View) {\n const t = i18next.t.bind(i18next)\n const number = (name: string, header: string, click?: (record: any) => void) => ({\n type: 'integer',\n name,\n header,\n record: { align: 'right', editable: false },\n width: 90,\n ...(click ? { handlers: { click: (_c: any, _d: any, _col: any, record: any) => record && click(record) } } : {})\n })\n\n if (view === 'people') {\n const person = (record: any) => ({ id: record.id, name: record.name || record.email })\n return {\n rows: { appendable: false, selectable: false },\n pagination: { infinite: true },\n columns: [\n { type: 'gutter', gutterName: 'sequence' },\n {\n type: 'string',\n name: 'name',\n header: t('field.name'),\n record: { editable: false },\n width: 140,\n handlers: { click: (_c: any, _d: any, _col: any, record: any) => record && this.narrow({ actor: person(record), door: undefined, outcome: '' }) }\n },\n { type: 'string', name: 'email', header: t('field.email'), record: { editable: false }, width: 200 },\n { type: 'string', name: 'roles', header: t('field.roles'), record: { editable: false }, width: 200 },\n { type: 'string', name: 'status', header: t('field.status'), record: { editable: false, align: 'center', renderer: statusRenderer(() => 0) }, width: 80 },\n { type: 'datetime', name: 'lastCheckinAt', header: t('audit.field.last-checkin'), record: { editable: false }, width: 160 },\n number('checkins', t('audit.field.checkins')),\n number('failedSignins', t('audit.field.failed-signins'), record => this.narrow({ actor: person(record), door: undefined, outcome: 'failed' })),\n number('granted', t('audit.field.granted'), record => this.narrow({ actor: person(record), door: undefined, outcome: '' })),\n number('denied', t('audit.field.denied'), record => this.narrow({ actor: person(record), door: undefined, outcome: 'denied' })),\n ...this.filterColumns(view)\n ]\n }\n }\n\n if (view === 'doors') {\n return {\n rows: { appendable: false, selectable: false },\n pagination: { infinite: true },\n columns: [\n { type: 'gutter', gutterName: 'sequence' },\n {\n type: 'string',\n name: 'doorWords',\n header: t('audit.field.privilege'),\n record: { editable: false },\n width: 240,\n handlers: { click: (_c: any, _d: any, _col: any, record: any) => record && this.narrow({ door: record.door, actor: undefined, outcome: '' }) }\n },\n number('people', t('audit.field.people')),\n number('granted', t('audit.field.granted'), record => this.narrow({ door: record.door, actor: undefined, outcome: '' })),\n number('denied', t('audit.field.denied'), record => this.narrow({ door: record.door, actor: undefined, outcome: 'denied' })),\n ...this.filterColumns(view)\n ]\n }\n }\n\n return {\n rows: { appendable: false, selectable: false },\n pagination: { pages: [50, 100, 200] },\n columns: [\n { type: 'gutter', gutterName: 'sequence' },\n { type: 'datetime', name: 'createdAt', header: t('audit.field.time'), record: { editable: false }, width: 160 },\n { type: 'string', name: 'actorName', header: t('audit.field.actor'), record: { editable: false }, width: 120 },\n { type: 'string', name: 'operation', header: t('audit.field.request'), record: { editable: false }, width: 200 },\n { type: 'string', name: 'what', header: t('audit.field.actions'), record: { editable: false }, width: 360 },\n { type: 'string', name: 'ip', header: t('audit.field.address'), record: { editable: false }, width: 120 },\n { type: 'integer', name: 'durationMs', header: t('audit.field.duration'), record: { editable: false, align: 'right' }, width: 80 },\n ...this.filterColumns(view)\n ]\n }\n }\n\n async fetchHandler({ page, limit, filters = [] }: FetchOption) {\n const t = i18next.t.bind(i18next)\n this.asked = filters as GridFilter[]\n const { from, to, actor, door, outcome } = auditQueryOf(filters)\n const period = { from: from.toISOString(), to: to.toISOString() }\n\n if (this.view === 'people') {\n const response = await client.query({\n query: gql`\n query ($from: DateTimeISO!, $to: DateTimeISO!) {\n auditPeople(from: $from, to: $to) {\n user {\n id\n name\n email\n status\n }\n roles\n lastCheckinAt\n checkins\n failedSignins\n granted\n denied\n }\n }\n `,\n variables: period,\n fetchPolicy: 'no-cache'\n })\n const people = response.data?.auditPeople || []\n const records = people\n .map((one: any) => ({\n ...one,\n id: one.user.id,\n name: one.user.name,\n email: one.user.email,\n roles: one.roles.join(', '),\n status: one.user.status\n }))\n .sort((a: any, b: any) => String(b.lastCheckinAt || '').localeCompare(String(a.lastCheckinAt || '')))\n return { total: records.length, records }\n }\n\n if (this.view === 'doors') {\n const response = await client.query({\n query: gql`\n query ($from: DateTimeISO!, $to: DateTimeISO!) {\n auditDoors(from: $from, to: $to) {\n door\n people\n granted\n denied\n }\n }\n `,\n variables: period,\n fetchPolicy: 'no-cache'\n })\n /* The doors used come first; the rest keep the server's order. */\n const used = (one: any) => one.granted + one.denied\n const records = (response.data?.auditDoors || [])\n .map((one: any) => ({ ...one, doorWords: doorWords(t, one.door) }))\n .sort((a: any, b: any) => used(b) - used(a))\n return { total: records.length, records }\n }\n\n const response = await client.query({\n query: gql`\n query ($filter: AuditRecordFilter!) {\n auditRecords(filter: $filter) {\n items {\n request {\n id\n createdAt\n actor {\n id\n name\n email\n }\n ip\n channel\n operationType\n operationName\n fields\n route\n durationMs\n }\n actions {\n kind\n door\n decision\n outcome\n code\n count\n objectId\n detail\n }\n }\n total\n }\n }\n `,\n variables: {\n filter: {\n ...period,\n actorId: actor?.id,\n door,\n outcome: outcome || undefined,\n page,\n limit\n }\n },\n fetchPolicy: 'no-cache'\n })\n\n const list = response.data?.auditRecords\n return {\n total: list?.total || 0,\n records: (list?.items || []).map(({ request, actions }: any) => ({\n id: request.id,\n createdAt: request.createdAt,\n actorName: request.actor?.name || request.actor?.email || '',\n what: recordWords(t, actions),\n operation: request.channel === 'graphql' ? [request.operationType, request.fields || request.operationName].filter(Boolean).join(' ') : request.route || '',\n ip: request.ip,\n durationMs: request.durationMs\n }))\n }\n }\n}\n"]}
@@ -1,5 +1,6 @@
1
1
  import '@material/web/icon/icon.js';
2
2
  import '@operato/data-grist';
3
+ import '@things-factory/ai-assistant/dist-client/index.js';
3
4
  import { FetchOption } from '@operato/data-grist';
4
5
  import { PageView } from '@operato/shell';
5
6
  declare const AuthProviderManagementPage_base: (new (...args: any[]) => {
@@ -31,17 +32,21 @@ export declare class AuthProviderManagementPage extends AuthProviderManagementPa
31
32
  handler: () => void;
32
33
  };
33
34
  actions: ({
35
+ id: string;
34
36
  title: string;
35
- action: () => Promise<void>;
36
37
  icon: string;
37
- emphasis?: undefined;
38
+ action: () => import("@operato/data-grist").GristRecord;
38
39
  } | {
39
- title: string;
40
- action: () => Promise<void>;
41
40
  icon: string;
42
41
  emphasis: {
42
+ raised: boolean;
43
+ outlined: boolean;
44
+ dense: boolean;
43
45
  danger: boolean;
44
46
  };
47
+ id: string;
48
+ title: string;
49
+ action: () => Promise<void>;
45
50
  })[];
46
51
  };
47
52
  render(): import("lit-html").TemplateResult<1>;
@@ -1,6 +1,7 @@
1
1
  import { __decorate, __metadata } from "tslib";
2
2
  import '@material/web/icon/icon.js';
3
3
  import '@operato/data-grist';
4
+ import '@things-factory/ai-assistant/dist-client/index.js';
4
5
  import gql from 'graphql-tag';
5
6
  import { css, html } from 'lit';
6
7
  import { customElement, query, state } from 'lit/decorators.js';
@@ -9,7 +10,7 @@ import { client } from '@operato/graphql';
9
10
  import { i18next, localize } from '@operato/i18n';
10
11
  import { notify } from '@operato/layout';
11
12
  import { PageView } from '@operato/shell';
12
- import { CommonGristStyles, CommonHeaderStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles';
13
+ import { CommonButtonStyles, CommonGristStyles, CommonHeaderStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles';
13
14
  import { isMobileDevice } from '@operato/utils';
14
15
  import { OxPrompt } from '@operato/popup/ox-prompt.js';
15
16
  import { p13n } from '@operato/p13n';
@@ -52,21 +53,23 @@ let AuthProviderManagementPage = class AuthProviderManagementPage extends p13n(l
52
53
  },
53
54
  // help: 'auth/auth-provider',
54
55
  actions: [
55
- { title: i18next.t('button.save'),
56
- action: this.updateAuthProvider.bind(this),
57
- icon: 'save'
58
- },
59
- { title: i18next.t('button.delete'),
60
- action: this.deleteAuthProvider.bind(this),
61
- icon: 'delete',
62
- emphasis: { danger: true
63
- }
64
- }
56
+ /* The only way to start a provider - there is no empty row under the records. */
57
+ { id: 'add-row', title: i18next.t('button.add-row'), icon: 'add', action: () => this.grist.addNewRecord() },
58
+ { id: 'save', title: i18next.t('button.save'), action: this.updateAuthProvider.bind(this), ...CommonButtonStyles.save }
65
59
  ] };
66
60
  }
67
61
  render() {
68
62
  const mode = this.mode || (isMobileDevice() ? 'CARD' : 'GRID');
63
+ /* Deleting acts on the picked rows, so it sits on the bar over the list that shows while rows are picked (F06). */
69
64
  return html `
65
+ <ox-assistant-selection-bar
66
+ .gridOf=${() => this.grist}
67
+ name=${i18next.t('title.auth-provider')}
68
+ .assistant=${false}
69
+ .actions=${[
70
+ { id: 'delete', title: i18next.t('button.delete'), icon: 'delete_outline', emphasis: { danger: true }, action: () => this.deleteAuthProvider() }
71
+ ]}
72
+ ></ox-assistant-selection-bar>
70
73
  <ox-grist class="page-fill"
71
74
  .mode=${mode}
72
75
  .config=${this.gristConfig}
@@ -89,6 +92,8 @@ let AuthProviderManagementPage = class AuthProviderManagementPage extends p13n(l
89
92
  this.gristConfig = { list: { fields: ['entity', 'description']
90
93
  },
91
94
  columns: [
95
+ /* A row's state (new, changed); a new row's mark removes it until it is saved (data-grist 행 제거). */
96
+ { type: 'gutter', gutterName: 'dirty' },
92
97
  { type: 'gutter', gutterName: 'sequence' },
93
98
  { type: 'gutter', gutterName: 'row-selector', multiple: true },
94
99
  { type: 'gutter',
@@ -168,7 +173,10 @@ let AuthProviderManagementPage = class AuthProviderManagementPage extends p13n(l
168
173
  width: 180
169
174
  }
170
175
  ],
171
- rows: { selectable: { multiple: true
176
+ /* No empty row under the records: 「행 추가」 starts one, and a paste past the last row adds rows. */
177
+ rows: { appendable: false,
178
+ pasteAppendable: true,
179
+ selectable: { multiple: true
172
180
  }
173
181
  },
174
182
  sorters: [
@@ -232,12 +240,16 @@ let AuthProviderManagementPage = class AuthProviderManagementPage extends p13n(l
232
240
  return { total, records: items };
233
241
  }
234
242
  async deleteAuthProvider() {
243
+ if (!this.grist.selected.some(record => record.id)) {
244
+ notify({ level: 'info', message: i18next.t('text.select-rows-to-delete') });
245
+ return;
246
+ }
235
247
  if (await OxPrompt.open({ title: i18next.t('text.are_you_sure'),
236
248
  text: i18next.t('text.sure_to_x', { x: i18next.t('text.delete') }),
237
249
  confirmButton: { text: i18next.t('button.confirm') },
238
250
  cancelButton: { text: i18next.t('button.cancel') }
239
251
  })) {
240
- const ids = this.grist.selected.map(record => record.id);
252
+ const ids = this.grist.selected.map(record => record.id).filter(Boolean);
241
253
  if (ids && ids.length > 0) {
242
254
  const response = await client.mutate({ mutation: gql `
243
255
  mutation ($ids: [String!]!) { deleteAuthProviders(ids: $ids)
@@ -256,6 +268,10 @@ let AuthProviderManagementPage = class AuthProviderManagementPage extends p13n(l
256
268
  }
257
269
  async updateAuthProvider() {
258
270
  let patches = this.grist.dirtyRecords;
271
+ if (!patches?.length) {
272
+ notify({ level: 'info', message: i18next.t('text.nothing-to-save') });
273
+ return;
274
+ }
259
275
  if (patches && patches.length) {
260
276
  patches = patches.map(patch => {
261
277
  let patchField = patch.id ? { id: patch.id } : {};
@@ -1 +1 @@
1
- {"version":3,"file":"auth-provider-management.js","sourceRoot":"","sources":["../../../client/pages/auth-provider/auth-provider-management.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\n\nimport '@operato/data-grist'\n\nimport gql from 'graphql-tag'\nimport { css, html } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\nimport { getEditor, getRenderer, ColumnConfig, DataGrist, FetchOption, SortersControl } from '@operato/data-grist'\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { notify, openPopup } from '@operato/layout'\nimport { PageView } from '@operato/shell'\nimport { CommonGristStyles, CommonHeaderStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles'\nimport { isMobileDevice, sleep } from '@operato/utils'\nimport { OxPopup } from '@operato/popup'\nimport { OxPrompt } from '@operato/popup/ox-prompt.js'\nimport { p13n } from '@operato/p13n'\n\nimport { listOutcome, pageFromResponse } from '../../utils/list-result.js'\n\n@customElement('auth-provider-management')\nexport class AuthProviderManagementPage extends p13n(localize(i18next)(PageView)) { static styles = [\n /* The work surface frame for a list screen (ADR-0060 decision 8). */\n WorkSurfacePageStyles,\n ScrollbarStyles,\n CommonGristStyles,\n CommonHeaderStyles,\n css`\n :host {\n --grid-record-emphasized-background-color: #8b0000;\n --grid-record-emphasized-color: #ff6b6b;\n }\n\n [failed] { padding: var(--spacing-medium);\n color: var(--md-sys-color-error);\n font: var(--label-font, inherit);\n }\n `\n ]\n\n @state() gristConfig: any\n @state() mode: 'CARD' | 'GRID' | 'LIST' = isMobileDevice() ? 'CARD' : 'GRID'\n /** The last fetch did not answer. Distinct from answering with nothing. */\n @state() failed: boolean = false\n\n @state() authProviderTypes: { type: string; description?: string; help?: string; parameterSpec?: any[] }[] = []\n\n @query('ox-grist') private grist!: DataGrist\n\n get context() { return { title: i18next.t('title.auth-provider'),\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 // help: 'auth/auth-provider',\n actions: [\n { title: i18next.t('button.save'),\n action: this.updateAuthProvider.bind(this),\n icon: 'save'\n },\n { title: i18next.t('button.delete'),\n action: this.deleteAuthProvider.bind(this),\n icon: 'delete',\n emphasis: { danger: true\n }\n }\n ]\n }\n }\n\n render() { const mode = this.mode || (isMobileDevice() ? 'CARD' : 'GRID')\n\n return html`\n <ox-grist class=\"page-fill\"\n .mode=${mode}\n .config=${this.gristConfig}\n .fetchHandler=${this.fetchHandler.bind(this)}\n .personalConfigProvider=${this.getPagePreferenceProvider('ox-grist')!}\n ?url-params-sensitive=${this.active}\n >\n <div slot=\"headroom\" class=\"header\">\n <ox-filters-form autofocus without-search class=\"filters\"></ox-filters-form>\n\n </div>\n\n <ox-grist-personalizer slot=\"setting\"></ox-grist-personalizer>\n </ox-grist>\n\n ${this.failed ? html`<div failed>${i18next.t('text.the list could not be loaded')}</div>` : ''}\n `\n }\n\n async pageInitialized(lifecycle) { this.gristConfig = { list: { fields: ['entity', 'description']\n },\n columns: [\n { type: 'gutter', gutterName: 'sequence' },\n { type: 'gutter', gutterName: 'row-selector', multiple: true },\n { type: 'gutter',\n gutterName: 'button',\n title: i18next.t('title.auth-provider'),\n icon: 'sync',\n handlers: { click: (columns, data, column, record, rowIndex) => { if (!record.id) return\n this.synchronizeUsers(record.id)\n }\n }\n },\n { type: 'select',\n name: 'type',\n header: i18next.t('field.type'),\n record: { editable: true,\n options: () => ['', ...this.authProviderTypes.map(({ type }) => type)]\n },\n filter: 'search',\n sortable: true,\n width: 150\n },\n { type: 'boolean',\n name: 'active',\n header: i18next.t('field.active'),\n record: { editable: true\n },\n sortable: true,\n width: 150\n },\n { type: 'string',\n name: 'tenantId',\n header: i18next.t('field.tenant-id'),\n record: { editable: true\n },\n width: 200\n },\n { type: 'string',\n name: 'clientId',\n header: i18next.t('field.client-id'),\n record: { editable: true\n },\n width: 200\n },\n { type: 'secret',\n name: 'clientSecret',\n header: i18next.t('field.client-secret'),\n record: { editable: true\n },\n width: 200\n },\n { type: 'secret',\n name: 'privateKey',\n header: i18next.t('field.private-key'),\n record: { editable: true\n },\n width: 200\n },\n { type: 'parameters',\n name: 'params',\n header: i18next.t('field.params'),\n record: { editable: true,\n options: async (value, column, record, row, field) => { const { description,\n help,\n parameterSpec: spec\n } = record.type ? this.authProviderTypes[record.type] : ({} as any)\n const context = this.grist\n\n return { description, help, spec, context }\n },\n renderer: 'json5'\n },\n width: 200\n },\n { type: 'datetime',\n name: 'updatedAt',\n header: i18next.t('field.updated_at'),\n record: { editable: false\n },\n sortable: true,\n width: 180\n }\n ],\n rows: { selectable: { multiple: true\n }\n },\n sorters: [\n { name: 'type'\n }\n ]\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!]) { authProviderTypes { items { type\n description\n help\n parameterSpec { type\n label\n name\n placeholder\n property\n styles\n }\n }\n total\n }\n\n responses: authProviders(filters: $filters, pagination: $pagination, sortings: $sortings) { items { id\n type\n active\n tenantId\n clientId\n clientSecret\n privateKey\n params\n updatedAt\n }\n total\n }\n }\n `,\n variables: { filters,\n pagination: { page, limit },\n sortings\n }\n })\n\n /*\n This read `response.data.authProviderTypes.items` with no check at all. On a refused\n query `data` is null, so the line threw inside the grist's fetch handler — an empty\n grid and nothing said.\n\n `clientSecret` and `privateKey` each carry their own\n `@privilege(category: \"security\", privilege: \"query\", domainOwnerGranted: true)`, so a\n viewer without that privilege gets the whole list **plus** one error per withheld\n value. Those errors point inside the page, and `pageFromResponse` reads the path and\n keeps the list — blacking it out would take the screen away from everyone who may see\n the providers but not their secrets.\n */\n const types = pageFromResponse(response, 'authProviderTypes')\n\n if (types) {\n this.authProviderTypes = types.items\n }\n\n const { items, total, failed } = listOutcome(pageFromResponse(response, 'responses'))\n\n this.failed = failed\n\n return { total, records: items }\n }\n\n private async deleteAuthProvider() { if (\n await OxPrompt.open({ title: i18next.t('text.are_you_sure'),\n text: i18next.t('text.sure_to_x', { x: i18next.t('text.delete') }),\n confirmButton: { text: i18next.t('button.confirm') },\n cancelButton: { text: i18next.t('button.cancel') }\n })\n ) { const ids = this.grist.selected.map(record => record.id)\n if (ids && ids.length > 0) { const response = await client.mutate({ mutation: gql`\n mutation ($ids: [String!]!) { deleteAuthProviders(ids: $ids)\n }\n `,\n variables: { ids\n }\n })\n\n if (!response.errors) { this.grist.fetch()\n notify({ message: i18next.t('text.info_x_successfully', { x: i18next.t('text.delete') })\n })\n }\n }\n }\n }\n\n private async updateAuthProvider() { let patches = this.grist.dirtyRecords\n if (patches && patches.length) { patches = patches.map(patch => { let patchField: any = patch.id ? { id: patch.id } : {}\n const dirtyFields = patch.__dirtyfields__\n for (let key in dirtyFields) { patchField[key] = dirtyFields[key].after\n }\n if (patchField['reportTemplate'] instanceof FileList) { patchField['reportTemplate'] = patchField['reportTemplate'][0]\n }\n patchField.cuFlag = patch.__dirty__\n\n return patchField\n })\n\n const response = await client.mutate({ mutation: gql`\n mutation ($patches: [AuthProviderPatch!]!) { updateMultipleAuthProvider(patches: $patches) { id\n }\n }\n `,\n variables: { patches\n }\n })\n\n if (!response.errors) { this.grist.fetch()\n }\n }\n }\n\n private async synchronizeUsers(id: string) { if (\n await OxPrompt.open({ title: i18next.t('text.are_you_sure'),\n text: i18next.t('text.sure_to_x', { x: i18next.t('text.synchronize') }),\n confirmButton: { text: i18next.t('button.confirm') },\n cancelButton: { text: i18next.t('button.cancel') }\n })\n ) { if (id && id.length > 0) { const response = await client.mutate({ mutation: gql`\n mutation ($id: String!) { synchronizeAuthProviderUsers(id: $id)\n }\n `,\n variables: { id\n }\n })\n\n if (!response.errors) { this.grist.fetch()\n notify({ message: i18next.t('text.info_x_successfully', { x: i18next.t('text.synchronize') })\n })\n }\n }\n }\n }\n}\n"]}
1
+ {"version":3,"file":"auth-provider-management.js","sourceRoot":"","sources":["../../../client/pages/auth-provider/auth-provider-management.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\n\nimport '@operato/data-grist'\nimport '@things-factory/ai-assistant/dist-client/index.js'\n\nimport gql from 'graphql-tag'\nimport { css, html } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\nimport { getEditor, getRenderer, ColumnConfig, DataGrist, FetchOption, SortersControl } from '@operato/data-grist'\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { notify, openPopup } from '@operato/layout'\nimport { PageView } from '@operato/shell'\nimport { CommonButtonStyles, CommonGristStyles, CommonHeaderStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles'\nimport { isMobileDevice, sleep } from '@operato/utils'\nimport { OxPopup } from '@operato/popup'\nimport { OxPrompt } from '@operato/popup/ox-prompt.js'\nimport { p13n } from '@operato/p13n'\n\nimport { listOutcome, pageFromResponse } from '../../utils/list-result.js'\n\n@customElement('auth-provider-management')\nexport class AuthProviderManagementPage extends p13n(localize(i18next)(PageView)) { static styles = [\n /* The work surface frame for a list screen (ADR-0060 decision 8). */\n WorkSurfacePageStyles,\n ScrollbarStyles,\n CommonGristStyles,\n CommonHeaderStyles,\n css`\n :host {\n --grid-record-emphasized-background-color: #8b0000;\n --grid-record-emphasized-color: #ff6b6b;\n }\n\n [failed] { padding: var(--spacing-medium);\n color: var(--md-sys-color-error);\n font: var(--label-font, inherit);\n }\n `\n ]\n\n @state() gristConfig: any\n @state() mode: 'CARD' | 'GRID' | 'LIST' = isMobileDevice() ? 'CARD' : 'GRID'\n /** The last fetch did not answer. Distinct from answering with nothing. */\n @state() failed: boolean = false\n\n @state() authProviderTypes: { type: string; description?: string; help?: string; parameterSpec?: any[] }[] = []\n\n @query('ox-grist') private grist!: DataGrist\n\n get context() { return { title: i18next.t('title.auth-provider'),\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 // help: 'auth/auth-provider',\n actions: [\n /* The only way to start a provider - there is no empty row under the records. */\n { id: 'add-row', title: i18next.t('button.add-row'), icon: 'add', action: () => this.grist.addNewRecord() },\n { id: 'save', title: i18next.t('button.save'), action: this.updateAuthProvider.bind(this), ...CommonButtonStyles.save }\n ]\n }\n }\n\n render() { const mode = this.mode || (isMobileDevice() ? 'CARD' : 'GRID')\n\n /* Deleting acts on the picked rows, so it sits on the bar over the list that shows while rows are picked (F06). */\n return html`\n <ox-assistant-selection-bar\n .gridOf=${() => this.grist}\n name=${i18next.t('title.auth-provider')}\n .assistant=${false}\n .actions=${[\n { id: 'delete', title: i18next.t('button.delete'), icon: 'delete_outline', emphasis: { danger: true }, action: () => this.deleteAuthProvider() }\n ]}\n ></ox-assistant-selection-bar>\n <ox-grist class=\"page-fill\"\n .mode=${mode}\n .config=${this.gristConfig}\n .fetchHandler=${this.fetchHandler.bind(this)}\n .personalConfigProvider=${this.getPagePreferenceProvider('ox-grist')!}\n ?url-params-sensitive=${this.active}\n >\n <div slot=\"headroom\" class=\"header\">\n <ox-filters-form autofocus without-search class=\"filters\"></ox-filters-form>\n\n </div>\n\n <ox-grist-personalizer slot=\"setting\"></ox-grist-personalizer>\n </ox-grist>\n\n ${this.failed ? html`<div failed>${i18next.t('text.the list could not be loaded')}</div>` : ''}\n `\n }\n\n async pageInitialized(lifecycle) { this.gristConfig = { list: { fields: ['entity', 'description']\n },\n columns: [\n /* A row's state (new, changed); a new row's mark removes it until it is saved (data-grist 행 제거). */\n { type: 'gutter', gutterName: 'dirty' },\n { type: 'gutter', gutterName: 'sequence' },\n { type: 'gutter', gutterName: 'row-selector', multiple: true },\n { type: 'gutter',\n gutterName: 'button',\n title: i18next.t('title.auth-provider'),\n icon: 'sync',\n handlers: { click: (columns, data, column, record, rowIndex) => { if (!record.id) return\n this.synchronizeUsers(record.id)\n }\n }\n },\n { type: 'select',\n name: 'type',\n header: i18next.t('field.type'),\n record: { editable: true,\n options: () => ['', ...this.authProviderTypes.map(({ type }) => type)]\n },\n filter: 'search',\n sortable: true,\n width: 150\n },\n { type: 'boolean',\n name: 'active',\n header: i18next.t('field.active'),\n record: { editable: true\n },\n sortable: true,\n width: 150\n },\n { type: 'string',\n name: 'tenantId',\n header: i18next.t('field.tenant-id'),\n record: { editable: true\n },\n width: 200\n },\n { type: 'string',\n name: 'clientId',\n header: i18next.t('field.client-id'),\n record: { editable: true\n },\n width: 200\n },\n { type: 'secret',\n name: 'clientSecret',\n header: i18next.t('field.client-secret'),\n record: { editable: true\n },\n width: 200\n },\n { type: 'secret',\n name: 'privateKey',\n header: i18next.t('field.private-key'),\n record: { editable: true\n },\n width: 200\n },\n { type: 'parameters',\n name: 'params',\n header: i18next.t('field.params'),\n record: { editable: true,\n options: async (value, column, record, row, field) => { const { description,\n help,\n parameterSpec: spec\n } = record.type ? this.authProviderTypes[record.type] : ({} as any)\n const context = this.grist\n\n return { description, help, spec, context }\n },\n renderer: 'json5'\n },\n width: 200\n },\n { type: 'datetime',\n name: 'updatedAt',\n header: i18next.t('field.updated_at'),\n record: { editable: false\n },\n sortable: true,\n width: 180\n }\n ],\n /* No empty row under the records: 「행 추가」 starts one, and a paste past the last row adds rows. */\n rows: { appendable: false,\n pasteAppendable: true,\n selectable: { multiple: true\n }\n },\n sorters: [\n { name: 'type'\n }\n ]\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!]) { authProviderTypes { items { type\n description\n help\n parameterSpec { type\n label\n name\n placeholder\n property\n styles\n }\n }\n total\n }\n\n responses: authProviders(filters: $filters, pagination: $pagination, sortings: $sortings) { items { id\n type\n active\n tenantId\n clientId\n clientSecret\n privateKey\n params\n updatedAt\n }\n total\n }\n }\n `,\n variables: { filters,\n pagination: { page, limit },\n sortings\n }\n })\n\n /*\n This read `response.data.authProviderTypes.items` with no check at all. On a refused\n query `data` is null, so the line threw inside the grist's fetch handler — an empty\n grid and nothing said.\n\n `clientSecret` and `privateKey` each carry their own\n `@privilege(category: \"security\", privilege: \"query\", domainOwnerGranted: true)`, so a\n viewer without that privilege gets the whole list **plus** one error per withheld\n value. Those errors point inside the page, and `pageFromResponse` reads the path and\n keeps the list — blacking it out would take the screen away from everyone who may see\n the providers but not their secrets.\n */\n const types = pageFromResponse(response, 'authProviderTypes')\n\n if (types) {\n this.authProviderTypes = types.items\n }\n\n const { items, total, failed } = listOutcome(pageFromResponse(response, 'responses'))\n\n this.failed = failed\n\n return { total, records: items }\n }\n\n private async deleteAuthProvider() {\n if (!this.grist.selected.some(record => record.id)) {\n notify({ level: 'info', message: i18next.t('text.select-rows-to-delete') })\n return\n }\n if (\n await OxPrompt.open({ title: i18next.t('text.are_you_sure'),\n text: i18next.t('text.sure_to_x', { x: i18next.t('text.delete') }),\n confirmButton: { text: i18next.t('button.confirm') },\n cancelButton: { text: i18next.t('button.cancel') }\n })\n ) { const ids = this.grist.selected.map(record => record.id).filter(Boolean)\n if (ids && ids.length > 0) { const response = await client.mutate({ mutation: gql`\n mutation ($ids: [String!]!) { deleteAuthProviders(ids: $ids)\n }\n `,\n variables: { ids\n }\n })\n\n if (!response.errors) { this.grist.fetch()\n notify({ message: i18next.t('text.info_x_successfully', { x: i18next.t('text.delete') })\n })\n }\n }\n }\n }\n\n private async updateAuthProvider() { let patches = this.grist.dirtyRecords\n if (!patches?.length) {\n notify({ level: 'info', message: i18next.t('text.nothing-to-save') })\n return\n }\n if (patches && patches.length) { patches = patches.map(patch => { let patchField: any = patch.id ? { id: patch.id } : {}\n const dirtyFields = patch.__dirtyfields__\n for (let key in dirtyFields) { patchField[key] = dirtyFields[key].after\n }\n if (patchField['reportTemplate'] instanceof FileList) { patchField['reportTemplate'] = patchField['reportTemplate'][0]\n }\n patchField.cuFlag = patch.__dirty__\n\n return patchField\n })\n\n const response = await client.mutate({ mutation: gql`\n mutation ($patches: [AuthProviderPatch!]!) { updateMultipleAuthProvider(patches: $patches) { id\n }\n }\n `,\n variables: { patches\n }\n })\n\n if (!response.errors) { this.grist.fetch()\n }\n }\n }\n\n private async synchronizeUsers(id: string) { if (\n await OxPrompt.open({ title: i18next.t('text.are_you_sure'),\n text: i18next.t('text.sure_to_x', { x: i18next.t('text.synchronize') }),\n confirmButton: { text: i18next.t('button.confirm') },\n cancelButton: { text: i18next.t('button.cancel') }\n })\n ) { if (id && id.length > 0) { const response = await client.mutate({ mutation: gql`\n mutation ($id: String!) { synchronizeAuthProviderUsers(id: $id)\n }\n `,\n variables: { id\n }\n })\n\n if (!response.errors) { this.grist.fetch()\n notify({ message: i18next.t('text.info_x_successfully', { x: i18next.t('text.synchronize') })\n })\n }\n }\n }\n }\n}\n"]}
@@ -70,6 +70,7 @@ let DomainOwnerManagement = class DomainOwnerManagement extends p13n(localize(i1
70
70
  .config=${this.config}
71
71
  .fetchHandler=${this._fetchHandler.bind(this)}
72
72
  .personalConfigProvider=${this.getPagePreferenceProvider('ox-grist')}
73
+ ?url-params-sensitive=${this.active}
73
74
  >
74
75
  </ox-grist>
75
76
 
@@ -136,8 +137,7 @@ let DomainOwnerManagement = class DomainOwnerManagement extends p13n(localize(i1
136
137
  async pageUpdated(_changes, _lifecycle) {
137
138
  if (this.active) {
138
139
  this._refreshPermissions();
139
- await this.updateComplete;
140
- this.grist.fetch();
140
+ /* The list reads itself on activation - it is bound to the address (FOOTER-BUTTON-REVIEW G09). */
141
141
  }
142
142
  }
143
143
  _refreshPermissions() {
@@ -1 +1 @@
1
- {"version":3,"file":"domain-owner-management.js","sourceRoot":"","sources":["../../../client/pages/domain-owner/domain-owner-management.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@material/web/button/elevated-button.js'\n\nimport '@operato/data-grist/ox-grist.js'\n\nimport '../../components/add-domain-owner-popup.js'\n\nimport gql from 'graphql-tag'\nimport { css, html } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\n\nimport { DataGrist } from '@operato/data-grist/ox-grist.js'\nimport { client, gqlContext } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { openPopup } from '@operato/layout'\nimport { PageView, store } from '@operato/shell'\nimport { OxPrompt } from '@operato/popup/ox-prompt.js'\nimport { CommonHeaderStyles, CommonGristStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles'\nimport { isMobileDevice } from '@operato/utils'\nimport { p13n } from '@operato/p13n'\n\nimport { arrayFromResponse, listOutcome } from '../../utils/list-result.js'\n\n/**\n * Domain Owners Management Page\n *\n * 현재 도메인의 owner 목록을 표시하고, 추가/제거를 관리한다.\n * 멀티 오너 지원 — 모든 owner는 동등한 권한을 가짐 (primary 없음).\n * Domain.owner legacy cache 필드는 대표 owner 표시용으로 유지됨.\n */\n@customElement('domain-owner-management')\nexport class DomainOwnerManagement extends p13n(localize(i18next)(PageView)) {\n static styles = [\n /* The work surface frame for a list screen (ADR-0060 decision 8). */\n WorkSurfacePageStyles,\n CommonGristStyles,\n CommonHeaderStyles,\n ScrollbarStyles,\n css`\n [failed] {\n padding: var(--spacing-medium);\n color: var(--md-sys-color-error);\n font: var(--label-font, inherit);\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 @state() private isDomainOwner: boolean = false\n\n /** The last fetch did not answer. Distinct from answering with nothing. */\n @state() private failed: boolean = false\n\n @query('ox-grist') private grist!: DataGrist\n\n get context() {\n return {\n title: i18next.t('text.domain owners'),\n help: 'auth/domain-owners',\n // 서버의 @privilege 가 최종 게이트. 버튼 표시/숨김은 isDomainOwner\n // 클라이언트 플래그에 의존하지 않음 — auth profile 이 해당 플래그를\n // 제대로 세팅 안 했을 때 버튼이 사라져 조작 불가 상태가 되는 것을 방지.\n actions: [\n {\n title: i18next.t('button.add'),\n action: this._onAddOwner.bind(this),\n icon: 'person_add'\n }\n ]\n }\n }\n\n render() {\n return html`\n <ox-grist\n class=\"page-fill\"\n .mode=${this.mode}\n .config=${this.config}\n .fetchHandler=${this._fetchHandler.bind(this)}\n .personalConfigProvider=${this.getPagePreferenceProvider('ox-grist')!}\n >\n </ox-grist>\n\n ${this.failed ? html`<div failed>${i18next.t('text.the list could not be loaded')}</div>` : ''}\n `\n }\n\n async pageInitialized() {\n this.config = {\n rows: { appendable: false, selectable: { multiple: false } },\n columns: [\n { type: 'gutter', gutterName: 'sequence' },\n {\n type: 'gutter',\n gutterName: 'button',\n icon: 'person_remove',\n title: i18next.t('button.remove owner'),\n handlers: {\n click: (_columns, _data, _column, record, _rowIndex) => {\n // 클라이언트 게이트 없음 — 서버의 @privilege(domainOwnerGranted:true)\n // 가 최종 authoritative. 오너 아니면 서버 에러를 프롬프트로 표시.\n if (record?.user) {\n this._onRemoveOwner(record)\n }\n }\n }\n },\n {\n type: 'string',\n name: 'userName',\n header: i18next.t('field.name'),\n record: { editable: false },\n width: 180\n },\n {\n type: 'string',\n name: 'userEmail',\n header: i18next.t('field.email'),\n record: { editable: false },\n width: 220\n },\n {\n type: 'string',\n name: 'reason',\n header: i18next.t('field.reason'),\n record: { editable: false },\n width: 220\n },\n {\n type: 'string',\n name: 'grantedByName',\n header: i18next.t('field.granted by'),\n record: { editable: false },\n width: 160\n },\n {\n type: 'datetime',\n name: 'grantedAt',\n header: i18next.t('field.granted at'),\n width: 180\n }\n ]\n }\n }\n\n async pageUpdated(_changes: any, _lifecycle: any) {\n if (this.active) {\n this._refreshPermissions()\n await this.updateComplete\n this.grist.fetch()\n }\n }\n\n private _refreshPermissions() {\n const __state__ = store.getState() as any\n const me = __state__.auth?.user || {}\n this.isDomainOwner = !!me.domainOwner || !!me.super\n }\n\n private async _fetchHandler() {\n const response = await client.query({\n query: gql`\n query {\n domainOwners {\n id\n user {\n id\n name\n email\n username\n }\n grantedBy {\n id\n name\n email\n }\n grantedAt\n reason\n }\n }\n `,\n context: gqlContext(),\n fetchPolicy: 'network-only'\n })\n\n /*\n * This read `response.data?.domainOwners || []`, which turned a refused query into\n * \"this domain has no owners\". That is not a harmless blank: an administrator who\n * believes it may go and add one, and the screen gave them no reason to doubt it.\n *\n * `arrayFromResponse` answers nothing when the server did not, and `failed` says so on\n * screen beside the empty grid.\n */\n const { items, total, failed } = listOutcome(arrayFromResponse(response, 'domainOwners'))\n\n this.failed = failed\n\n return {\n total,\n records: items.map((ow: any) => ({\n ...ow,\n userName: ow.user?.name,\n userEmail: ow.user?.email,\n grantedByName: ow.grantedBy?.name || ''\n }))\n }\n }\n\n private _onAddOwner() {\n openPopup(\n html`\n <add-domain-owner-popup\n @domain-owner-added=${() => {\n this.grist.fetch()\n this._notify(i18next.t('text.domain owner added successfully'))\n }}\n ></add-domain-owner-popup>\n `,\n {\n size: 'small',\n title: i18next.t('title.add domain owner')\n }\n )\n }\n\n private async _onRemoveOwner(record: any) {\n const username = record.user?.username || record.user?.email\n const displayName = record.user?.name || username\n\n const confirmed = await OxPrompt.open({\n type: 'warning',\n title: i18next.t('text.are_you_sure'),\n text: i18next.t('text.are_you_sure_to_remove_domain_owner', { x: displayName }),\n confirmButton: { text: i18next.t('button.remove owner') },\n cancelButton: { text: i18next.t('button.cancel') }\n })\n if (!confirmed) return\n\n try {\n const response = await client.mutate({\n mutation: gql`\n mutation removeDomainOwner($username: String!) {\n removeDomainOwner(username: $username)\n }\n `,\n variables: { username },\n context: gqlContext()\n })\n\n if (!response.errors?.length) {\n this._notify(i18next.t('text.domain owner removed successfully'))\n this.grist.fetch()\n }\n } catch (err: any) {\n await OxPrompt.open({\n type: 'error',\n title: i18next.t('text.failed'),\n text: err?.message || String(err),\n confirmButton: { text: i18next.t('button.confirm') }\n })\n }\n }\n\n private _notify(message: string) {\n document.dispatchEvent(new CustomEvent('notify', { detail: { message, option: { timer: 1500 } } }))\n }\n}\n"]}
1
+ {"version":3,"file":"domain-owner-management.js","sourceRoot":"","sources":["../../../client/pages/domain-owner/domain-owner-management.ts"],"names":[],"mappings":";AAAA,OAAO,4BAA4B,CAAA;AACnC,OAAO,yCAAyC,CAAA;AAEhD,OAAO,iCAAiC,CAAA;AAExC,OAAO,4CAA4C,CAAA;AAEnD,OAAO,GAAG,MAAM,aAAa,CAAA;AAC7B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC/B,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAEzE,OAAO,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAA;AAC3D,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AACrD,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAA;AACtD,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AAC/G,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAEpC,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AAE3E;;;;;;GAMG;AAEI,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC;IAArE;;QAgBwB,WAAM,GAAY,KAAK,CAAA;QAExB,SAAI,GAA6B,cAAc,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAA;QAE9E,kBAAa,GAAY,KAAK,CAAA;QAE/C,2EAA2E;QAC1D,WAAM,GAAY,KAAK,CAAA;IAuN1C,CAAC;aA7OQ,WAAM,GAAG;QACd,qEAAqE;QACrE,qBAAqB;QACrB,iBAAiB;QACjB,kBAAkB;QAClB,eAAe;QACf,GAAG,CAAA;;;;;;KAMF;KACF,AAbY,CAaZ;IAaD,IAAI,OAAO;QACT,OAAO;YACL,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,oBAAoB,CAAC;YACtC,IAAI,EAAE,oBAAoB;YAC1B,mDAAmD;YACnD,8CAA8C;YAC9C,4CAA4C;YAC5C,OAAO,EAAE;gBACP;oBACE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC;oBAC9B,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;oBACnC,IAAI,EAAE,YAAY;iBACnB;aACF;SACF,CAAA;IACH,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAA;;;gBAGC,IAAI,CAAC,IAAI;kBACP,IAAI,CAAC,MAAM;wBACL,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;kCACnB,IAAI,CAAC,yBAAyB,CAAC,UAAU,CAAE;gCAC7C,IAAI,CAAC,MAAM;;;;QAInC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAA,eAAe,OAAO,CAAC,CAAC,CAAC,mCAAmC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE;KAC/F,CAAA;IACH,CAAC;IAED,KAAK,CAAC,eAAe;QACnB,IAAI,CAAC,MAAM,GAAG;YACZ,IAAI,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;YAC5D,OAAO,EAAE;gBACP,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE;gBAC1C;oBACE,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE,QAAQ;oBACpB,IAAI,EAAE,eAAe;oBACrB,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC;oBACvC,QAAQ,EAAE;wBACR,KAAK,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE;4BACrD,yDAAyD;4BACzD,8CAA8C;4BAC9C,IAAI,MAAM,EAAE,IAAI,EAAE,CAAC;gCACjB,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAA;4BAC7B,CAAC;wBACH,CAAC;qBACF;iBACF;gBACD;oBACE,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,UAAU;oBAChB,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC;oBAC/B,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE;oBAC3B,KAAK,EAAE,GAAG;iBACX;gBACD;oBACE,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,WAAW;oBACjB,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC;oBAChC,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE;oBAC3B,KAAK,EAAE,GAAG;iBACX;gBACD;oBACE,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,QAAQ;oBACd,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC;oBACjC,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE;oBAC3B,KAAK,EAAE,GAAG;iBACX;gBACD;oBACE,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,eAAe;oBACrB,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC;oBACrC,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE;oBAC3B,KAAK,EAAE,GAAG;iBACX;gBACD;oBACE,IAAI,EAAE,UAAU;oBAChB,IAAI,EAAE,WAAW;oBACjB,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC;oBACrC,KAAK,EAAE,GAAG;iBACX;aACF;SACF,CAAA;IACH,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,QAAa,EAAE,UAAe;QAC9C,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,mBAAmB,EAAE,CAAA;YAC1B,kGAAkG;QACpG,CAAC;IACH,CAAC;IAEO,mBAAmB;QACzB,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,EAAS,CAAA;QACzC,MAAM,EAAE,GAAG,SAAS,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAA;QACrC,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,EAAE,CAAC,WAAW,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAA;IACrD,CAAC;IAEO,KAAK,CAAC,aAAa;QACzB,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;YAClC,KAAK,EAAE,GAAG,CAAA;;;;;;;;;;;;;;;;;;;OAmBT;YACD,OAAO,EAAE,UAAU,EAAE;YACrB,WAAW,EAAE,cAAc;SAC5B,CAAC,CAAA;QAEF;;;;;;;WAOG;QACH,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,WAAW,CAAC,iBAAiB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAA;QAEzF,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QAEpB,OAAO;YACL,KAAK;YACL,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,EAAO,EAAE,EAAE,CAAC,CAAC;gBAC/B,GAAG,EAAE;gBACL,QAAQ,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI;gBACvB,SAAS,EAAE,EAAE,CAAC,IAAI,EAAE,KAAK;gBACzB,aAAa,EAAE,EAAE,CAAC,SAAS,EAAE,IAAI,IAAI,EAAE;aACxC,CAAC,CAAC;SACJ,CAAA;IACH,CAAC;IAEO,WAAW;QACjB,SAAS,CACP,IAAI,CAAA;;gCAEsB,GAAG,EAAE;YACzB,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAA;YAClB,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,sCAAsC,CAAC,CAAC,CAAA;QACjE,CAAC;;OAEJ,EACD;YACE,IAAI,EAAE,OAAO;YACb,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC;SAC3C,CACF,CAAA;IACH,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,MAAW;QACtC,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,EAAE,QAAQ,IAAI,MAAM,CAAC,IAAI,EAAE,KAAK,CAAA;QAC5D,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,EAAE,IAAI,IAAI,QAAQ,CAAA;QAEjD,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC;YACpC,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC;YACrC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,0CAA0C,EAAE,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC;YAC/E,aAAa,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC,EAAE;YACzD,YAAY,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,EAAE;SACnD,CAAC,CAAA;QACF,IAAI,CAAC,SAAS;YAAE,OAAM;QAEtB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC;gBACnC,QAAQ,EAAE,GAAG,CAAA;;;;SAIZ;gBACD,SAAS,EAAE,EAAE,QAAQ,EAAE;gBACvB,OAAO,EAAE,UAAU,EAAE;aACtB,CAAC,CAAA;YAEF,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;gBAC7B,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,wCAAwC,CAAC,CAAC,CAAA;gBACjE,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAA;YACpB,CAAC;QACH,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,MAAM,QAAQ,CAAC,IAAI,CAAC;gBAClB,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC;gBAC/B,IAAI,EAAE,GAAG,EAAE,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC;gBACjC,aAAa,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,EAAE;aACrD,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAEO,OAAO,CAAC,OAAe;QAC7B,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;;AA7N4B;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;;qDAAwB;AACxB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;qDAAY;AACX;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;mDAAoE;AAE9E;IAAhB,KAAK,EAAE;;4DAAuC;AAG9B;IAAhB,KAAK,EAAE;;qDAAgC;AAEb;IAA1B,KAAK,CAAC,UAAU,CAAC;8BAAiB,SAAS;oDAAA;AAzBjC,qBAAqB;IADjC,aAAa,CAAC,yBAAyB,CAAC;GAC5B,qBAAqB,CA8OjC","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@material/web/button/elevated-button.js'\n\nimport '@operato/data-grist/ox-grist.js'\n\nimport '../../components/add-domain-owner-popup.js'\n\nimport gql from 'graphql-tag'\nimport { css, html } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\n\nimport { DataGrist } from '@operato/data-grist/ox-grist.js'\nimport { client, gqlContext } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { openPopup } from '@operato/layout'\nimport { PageView, store } from '@operato/shell'\nimport { OxPrompt } from '@operato/popup/ox-prompt.js'\nimport { CommonHeaderStyles, CommonGristStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles'\nimport { isMobileDevice } from '@operato/utils'\nimport { p13n } from '@operato/p13n'\n\nimport { arrayFromResponse, listOutcome } from '../../utils/list-result.js'\n\n/**\n * Domain Owners Management Page\n *\n * 현재 도메인의 owner 목록을 표시하고, 추가/제거를 관리한다.\n * 멀티 오너 지원 — 모든 owner는 동등한 권한을 가짐 (primary 없음).\n * Domain.owner legacy cache 필드는 대표 owner 표시용으로 유지됨.\n */\n@customElement('domain-owner-management')\nexport class DomainOwnerManagement extends p13n(localize(i18next)(PageView)) {\n static styles = [\n /* The work surface frame for a list screen (ADR-0060 decision 8). */\n WorkSurfacePageStyles,\n CommonGristStyles,\n CommonHeaderStyles,\n ScrollbarStyles,\n css`\n [failed] {\n padding: var(--spacing-medium);\n color: var(--md-sys-color-error);\n font: var(--label-font, inherit);\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 @state() private isDomainOwner: boolean = false\n\n /** The last fetch did not answer. Distinct from answering with nothing. */\n @state() private failed: boolean = false\n\n @query('ox-grist') private grist!: DataGrist\n\n get context() {\n return {\n title: i18next.t('text.domain owners'),\n help: 'auth/domain-owners',\n // 서버의 @privilege 가 최종 게이트. 버튼 표시/숨김은 isDomainOwner\n // 클라이언트 플래그에 의존하지 않음 — auth profile 이 해당 플래그를\n // 제대로 세팅 안 했을 때 버튼이 사라져 조작 불가 상태가 되는 것을 방지.\n actions: [\n {\n title: i18next.t('button.add'),\n action: this._onAddOwner.bind(this),\n icon: 'person_add'\n }\n ]\n }\n }\n\n render() {\n return html`\n <ox-grist\n class=\"page-fill\"\n .mode=${this.mode}\n .config=${this.config}\n .fetchHandler=${this._fetchHandler.bind(this)}\n .personalConfigProvider=${this.getPagePreferenceProvider('ox-grist')!}\n ?url-params-sensitive=${this.active}\n >\n </ox-grist>\n\n ${this.failed ? html`<div failed>${i18next.t('text.the list could not be loaded')}</div>` : ''}\n `\n }\n\n async pageInitialized() {\n this.config = {\n rows: { appendable: false, selectable: { multiple: false } },\n columns: [\n { type: 'gutter', gutterName: 'sequence' },\n {\n type: 'gutter',\n gutterName: 'button',\n icon: 'person_remove',\n title: i18next.t('button.remove owner'),\n handlers: {\n click: (_columns, _data, _column, record, _rowIndex) => {\n // 클라이언트 게이트 없음 — 서버의 @privilege(domainOwnerGranted:true)\n // 가 최종 authoritative. 오너 아니면 서버 에러를 프롬프트로 표시.\n if (record?.user) {\n this._onRemoveOwner(record)\n }\n }\n }\n },\n {\n type: 'string',\n name: 'userName',\n header: i18next.t('field.name'),\n record: { editable: false },\n width: 180\n },\n {\n type: 'string',\n name: 'userEmail',\n header: i18next.t('field.email'),\n record: { editable: false },\n width: 220\n },\n {\n type: 'string',\n name: 'reason',\n header: i18next.t('field.reason'),\n record: { editable: false },\n width: 220\n },\n {\n type: 'string',\n name: 'grantedByName',\n header: i18next.t('field.granted by'),\n record: { editable: false },\n width: 160\n },\n {\n type: 'datetime',\n name: 'grantedAt',\n header: i18next.t('field.granted at'),\n width: 180\n }\n ]\n }\n }\n\n async pageUpdated(_changes: any, _lifecycle: any) {\n if (this.active) {\n this._refreshPermissions()\n /* The list reads itself on activation - it is bound to the address (FOOTER-BUTTON-REVIEW G09). */\n }\n }\n\n private _refreshPermissions() {\n const __state__ = store.getState() as any\n const me = __state__.auth?.user || {}\n this.isDomainOwner = !!me.domainOwner || !!me.super\n }\n\n private async _fetchHandler() {\n const response = await client.query({\n query: gql`\n query {\n domainOwners {\n id\n user {\n id\n name\n email\n username\n }\n grantedBy {\n id\n name\n email\n }\n grantedAt\n reason\n }\n }\n `,\n context: gqlContext(),\n fetchPolicy: 'network-only'\n })\n\n /*\n * This read `response.data?.domainOwners || []`, which turned a refused query into\n * \"this domain has no owners\". That is not a harmless blank: an administrator who\n * believes it may go and add one, and the screen gave them no reason to doubt it.\n *\n * `arrayFromResponse` answers nothing when the server did not, and `failed` says so on\n * screen beside the empty grid.\n */\n const { items, total, failed } = listOutcome(arrayFromResponse(response, 'domainOwners'))\n\n this.failed = failed\n\n return {\n total,\n records: items.map((ow: any) => ({\n ...ow,\n userName: ow.user?.name,\n userEmail: ow.user?.email,\n grantedByName: ow.grantedBy?.name || ''\n }))\n }\n }\n\n private _onAddOwner() {\n openPopup(\n html`\n <add-domain-owner-popup\n @domain-owner-added=${() => {\n this.grist.fetch()\n this._notify(i18next.t('text.domain owner added successfully'))\n }}\n ></add-domain-owner-popup>\n `,\n {\n size: 'small',\n title: i18next.t('title.add domain owner')\n }\n )\n }\n\n private async _onRemoveOwner(record: any) {\n const username = record.user?.username || record.user?.email\n const displayName = record.user?.name || username\n\n const confirmed = await OxPrompt.open({\n type: 'warning',\n title: i18next.t('text.are_you_sure'),\n text: i18next.t('text.are_you_sure_to_remove_domain_owner', { x: displayName }),\n confirmButton: { text: i18next.t('button.remove owner') },\n cancelButton: { text: i18next.t('button.cancel') }\n })\n if (!confirmed) return\n\n try {\n const response = await client.mutate({\n mutation: gql`\n mutation removeDomainOwner($username: String!) {\n removeDomainOwner(username: $username)\n }\n `,\n variables: { username },\n context: gqlContext()\n })\n\n if (!response.errors?.length) {\n this._notify(i18next.t('text.domain owner removed successfully'))\n this.grist.fetch()\n }\n } catch (err: any) {\n await OxPrompt.open({\n type: 'error',\n title: i18next.t('text.failed'),\n text: err?.message || String(err),\n confirmButton: { text: i18next.t('button.confirm') }\n })\n }\n }\n\n private _notify(message: string) {\n document.dispatchEvent(new CustomEvent('notify', { detail: { message, option: { timer: 1500 } } }))\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,51 @@
1
+ import { readFileSync } from 'fs';
2
+ import { join } from 'path';
3
+ /*
4
+ * One rule for a list's query state (FOOTER-BUTTON-REVIEW G09): the list's grid keeps its filters, sort, search, page
5
+ * and page size in the address, so reloading, sharing and going back read the same list. What narrows the query is the
6
+ * grid's own filter, not page state read by a direct fetch. Comments are stripped before reading.
7
+ */
8
+ const source = (name) => readFileSync(join(__dirname, name), 'utf-8')
9
+ .replace(/\/\*[\s\S]*?\*\//g, '')
10
+ .replace(/<!--[\s\S]*?-->/g, '')
11
+ .replace(/^[ \t]*\/\/.*$/gm, '');
12
+ const LISTS = [
13
+ 'role/role-list-page.ts',
14
+ 'user/user-list-page.ts',
15
+ 'auth-provider/auth-provider-management.ts',
16
+ 'audit/audit-page.ts',
17
+ 'appliance/home.ts',
18
+ 'application/applications.ts',
19
+ 'domain-owner/domain-owner-management.ts'
20
+ ];
21
+ describe('the auth lists keep their query in the address', () => {
22
+ it.each(LISTS)('★ %s binds its grid to the address and does not read again on activation', name => {
23
+ const text = source(name);
24
+ expect(text).toContain('?url-params-sensitive=${this.active}');
25
+ const at = text.indexOf('async pageUpdated(');
26
+ const updated = at < 0 ? '' : text.slice(at, text.indexOf('\n }\n', at));
27
+ expect(updated).not.toMatch(/this\.grist\??\.fetch\(\)/);
28
+ });
29
+ it('★ the role list\'s 묶음 is the grid\'s filter, 「우리 역할」 by default, counted by the grid', () => {
30
+ const text = source('role/role-list-page.ts');
31
+ expect(text).not.toMatch(/@state\(\) private scope/);
32
+ expect(text).toMatch(/name: 'inherited',[\s\S]*?type: 'select-buttons',[\s\S]*?value: InheritedValueType\.None/);
33
+ expect(text).toContain('.countHandler=${this.countHandler.bind(this)}');
34
+ expect(text).toContain('roleQueryOf(asked)');
35
+ });
36
+ it('★ the audit conditions are the grid\'s filters; only the view stays page state', () => {
37
+ const text = source('audit/audit-page.ts');
38
+ expect(text).not.toMatch(/@state\(\) private (days|from|to|actor|door|outcome)\b/);
39
+ expect(text).toMatch(/@state\(\) private view: View/);
40
+ expect(text).toContain('auditQueryOf(filters)');
41
+ expect((text.match(/\.\.\.this\.filterColumns\(view\)/g) || []).length).toBe(3);
42
+ });
43
+ it('★ deleting auth providers acts on the picked rows, from the selection bar - not the page bar', () => {
44
+ const text = source('auth-provider/auth-provider-management.ts');
45
+ const actions = text.slice(text.indexOf('actions: ['), text.indexOf('render()'));
46
+ expect(actions).not.toContain('button.delete');
47
+ expect(text).toMatch(/<ox-assistant-selection-bar[\s\S]*?\.assistant=\$\{false\}[\s\S]*?id: 'delete'[\s\S]*?emphasis: \{ danger: true \}[\s\S]*?<\/ox-assistant-selection-bar>\s*<ox-grist/);
48
+ expect(text).toContain("gutterName: 'row-selector', multiple: true");
49
+ });
50
+ });
51
+ //# sourceMappingURL=list-address.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-address.test.js","sourceRoot":"","sources":["../../client/pages/list-address.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync } from 'fs'\nimport { join } from 'path'\n\n/*\n * One rule for a list's query state (FOOTER-BUTTON-REVIEW G09): the list's grid keeps its filters, sort, search, page\n * and page size in the address, so reloading, sharing and going back read the same list. What narrows the query is the\n * grid's own filter, not page state read by a direct fetch. Comments are stripped before reading.\n */\nconst source = (name: string) =>\n readFileSync(join(__dirname, name), 'utf-8')\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '')\n .replace(/<!--[\\s\\S]*?-->/g, '')\n .replace(/^[ \\t]*\\/\\/.*$/gm, '')\n\nconst LISTS = [\n 'role/role-list-page.ts',\n 'user/user-list-page.ts',\n 'auth-provider/auth-provider-management.ts',\n 'audit/audit-page.ts',\n 'appliance/home.ts',\n 'application/applications.ts',\n 'domain-owner/domain-owner-management.ts'\n]\n\ndescribe('the auth lists keep their query in the address', () => {\n it.each(LISTS)('★ %s binds its grid to the address and does not read again on activation', name => {\n const text = source(name)\n expect(text).toContain('?url-params-sensitive=${this.active}')\n const at = text.indexOf('async pageUpdated(')\n const updated = at < 0 ? '' : text.slice(at, text.indexOf('\\n }\\n', at))\n expect(updated).not.toMatch(/this\\.grist\\??\\.fetch\\(\\)/)\n })\n\n it('★ the role list\\'s 묶음 is the grid\\'s filter, 「우리 역할」 by default, counted by the grid', () => {\n const text = source('role/role-list-page.ts')\n expect(text).not.toMatch(/@state\\(\\) private scope/)\n expect(text).toMatch(/name: 'inherited',[\\s\\S]*?type: 'select-buttons',[\\s\\S]*?value: InheritedValueType\\.None/)\n expect(text).toContain('.countHandler=${this.countHandler.bind(this)}')\n expect(text).toContain('roleQueryOf(asked)')\n })\n\n it('★ the audit conditions are the grid\\'s filters; only the view stays page state', () => {\n const text = source('audit/audit-page.ts')\n expect(text).not.toMatch(/@state\\(\\) private (days|from|to|actor|door|outcome)\\b/)\n expect(text).toMatch(/@state\\(\\) private view: View/)\n expect(text).toContain('auditQueryOf(filters)')\n expect((text.match(/\\.\\.\\.this\\.filterColumns\\(view\\)/g) || []).length).toBe(3)\n })\n\n it('★ deleting auth providers acts on the picked rows, from the selection bar - not the page bar', () => {\n const text = source('auth-provider/auth-provider-management.ts')\n const actions = text.slice(text.indexOf('actions: ['), text.indexOf('render()'))\n expect(actions).not.toContain('button.delete')\n expect(text).toMatch(/<ox-assistant-selection-bar[\\s\\S]*?\\.assistant=\\$\\{false\\}[\\s\\S]*?id: 'delete'[\\s\\S]*?emphasis: \\{ danger: true \\}[\\s\\S]*?<\\/ox-assistant-selection-bar>\\s*<ox-grist/)\n expect(text).toContain(\"gutterName: 'row-selector', multiple: true\")\n })\n})\n"]}
@@ -7,16 +7,17 @@ import path from 'path';
7
7
  */
8
8
  const source = readFileSync(path.join(__dirname, 'role-list-page.ts'), 'utf-8');
9
9
  const code = source.replace(/\/\*[\s\S]*?\*\//g, '').replace(/^\s*\/\/.*$/gm, '');
10
- const scopes = code.slice(code.indexOf('private renderScopes('), code.indexOf('private renderLineage('));
11
- const initialized = code.slice(code.indexOf('async pageInitialized('), code.indexOf('async pageUpdated('));
10
+ const initialized = code.slice(code.indexOf('async pageInitialized('), code.indexOf('async fetchHandler('));
11
+ const counting = code.slice(code.indexOf('async countHandler('), code.indexOf('private renderNote('));
12
12
  describe('the role list in a domain with no parent', () => {
13
13
  it('★ inherits only when the profile names a parent - not knowing is not having none', () => {
14
14
  expect(code).toMatch(/private hasParent\(\): boolean \{\s*return this\.parentDomain !== null\s*\}/);
15
15
  });
16
- it('★ draws no scope buttons, and so no lineage line', () => {
17
- expect(scopes).toMatch(/^private renderScopes\(\) \{\s*if \(!this\.hasParent\(\)\) \{\s*return nothing\s*\}/);
16
+ it('★ draws no scope chips, and so no lineage line', () => {
17
+ /* The chips are the grid's `inherited` filter (FOOTER-BUTTON-REVIEW G09): owned but not drawn without a parent. */
18
+ expect(initialized).toMatch(/name: 'inherited',[\s\S]*?hidden: !inheriting,/);
18
19
  expect(code.match(/this\.renderLineage\(\)/g)).toHaveLength(1);
19
- expect(scopes).toMatch(/this\.renderLineage\(\)/);
20
+ expect(code).toMatch(/\$\{this\.hasParent\(\) \? this\.renderLineage\(\) : nothing\}/);
20
21
  });
21
22
  it('★ leaves the source column and its list detail out', () => {
22
23
  expect(initialized).toMatch(/const inheriting = this\.hasParent\(\)/);
@@ -25,7 +26,7 @@ describe('the role list in a domain with no parent', () => {
25
26
  expect(initialized.match(/name: 'source'/g)).toHaveLength(1);
26
27
  });
27
28
  it('counts the scopes only where there are scopes to count', () => {
28
- expect(initialized).toMatch(/if \(this\.hasParent\(\)\) \{\s*this\.countScopes\(\)\s*\}/);
29
+ expect(counting).toMatch(/^async countHandler\([^)]*\) \{\s*if \(!this\.hasParent\(\)\) \{\s*return \{\}\s*\}/);
29
30
  });
30
31
  });
31
32
  //# sourceMappingURL=role-inheritance-shown.test.js.map