@things-factory/auth-ui 10.1.254 → 10.1.257
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-client/bootstrap.js +2 -2
- package/dist-client/bootstrap.js.map +1 -1
- package/dist-client/components/access-decision-popup.d.ts +9 -8
- package/dist-client/components/access-decision-popup.js +46 -58
- package/dist-client/components/access-decision-popup.js.map +1 -1
- package/dist-client/components/access-request-popup.d.ts +13 -8
- package/dist-client/components/access-request-popup.js +78 -102
- package/dist-client/components/access-request-popup.js.map +1 -1
- package/dist-client/components/app-binding-detail.d.ts +7 -5
- package/dist-client/components/app-binding-detail.js +62 -82
- package/dist-client/components/app-binding-detail.js.map +1 -1
- package/dist-client/components/appliance-editor.d.ts +10 -9
- package/dist-client/components/appliance-editor.js +87 -138
- package/dist-client/components/appliance-editor.js.map +1 -1
- package/dist-client/components/application-editor.d.ts +7 -5
- package/dist-client/components/application-editor.js +58 -92
- package/dist-client/components/application-editor.js.map +1 -1
- package/dist-client/components/my-login-history.js +18 -40
- package/dist-client/components/my-login-history.js.map +1 -1
- package/dist-client/components/my-passkeys.d.ts +4 -3
- package/dist-client/components/my-passkeys.js +29 -51
- package/dist-client/components/my-passkeys.js.map +1 -1
- package/dist-client/components/my-roles.d.ts +3 -4
- package/dist-client/components/my-roles.js +36 -55
- package/dist-client/components/my-roles.js.map +1 -1
- package/dist-client/components/partner-role-editor.js +27 -50
- package/dist-client/components/partner-role-editor.js.map +1 -1
- package/dist-client/components/profile-component.d.ts +2 -2
- package/dist-client/components/profile-component.js +18 -26
- package/dist-client/components/profile-component.js.map +1 -1
- package/dist-client/components/role-template-picker.d.ts +3 -3
- package/dist-client/components/role-template-picker.js +28 -42
- package/dist-client/components/role-template-picker.js.map +1 -1
- package/dist-client/components/user-detail.d.ts +23 -22
- package/dist-client/components/user-detail.js +125 -179
- package/dist-client/components/user-detail.js.map +1 -1
- package/dist-client/components/user-invite.d.ts +8 -6
- package/dist-client/components/user-invite.js +106 -141
- package/dist-client/components/user-invite.js.map +1 -1
- package/dist-client/components/user-popups-standard.test.js +1 -1
- package/dist-client/components/user-popups-standard.test.js.map +1 -1
- package/dist-client/components/user-role-editor.js +72 -122
- package/dist-client/components/user-role-editor.js.map +1 -1
- package/dist-client/entity360/person-360.d.ts +8 -11
- package/dist-client/entity360/person-360.js +49 -68
- package/dist-client/entity360/person-360.js.map +1 -1
- package/dist-client/entries/oauth2/oauth2-decision-page.js +13 -25
- package/dist-client/entries/oauth2/oauth2-decision-page.js.map +1 -1
- package/dist-client/identity-confirmation/identity-confirmation.d.ts +13 -14
- package/dist-client/identity-confirmation/identity-confirmation.js +39 -45
- package/dist-client/identity-confirmation/identity-confirmation.js.map +1 -1
- package/dist-client/pages/audit/audit-page.d.ts +4 -4
- package/dist-client/pages/audit/audit-page.js +28 -39
- package/dist-client/pages/audit/audit-page.js.map +1 -1
- package/dist-client/pages/domain-link/domain-link-management.js +1 -1
- package/dist-client/pages/domain-link/domain-link-management.js.map +1 -1
- package/dist-client/pages/partner/partner-management.js +30 -68
- package/dist-client/pages/partner/partner-management.js.map +1 -1
- package/dist-client/pages/role/role-extra-removal.test.d.mts +1 -0
- package/dist-client/pages/role/role-extra-removal.test.mjs +73 -0
- package/dist-client/pages/role/role-extra-removal.test.mjs.map +1 -0
- package/dist-client/pages/role/role-list-page.js +20 -22
- package/dist-client/pages/role/role-list-page.js.map +1 -1
- package/dist-client/pages/role/role-privilege-page.d.ts +36 -8
- package/dist-client/pages/role/role-privilege-page.js +216 -158
- package/dist-client/pages/role/role-privilege-page.js.map +1 -1
- package/dist-client/pages/role/role-task-review.test.js +20 -16
- package/dist-client/pages/role/role-task-review.test.js.map +1 -1
- package/dist-client/pages/role/role-template-gap.test.js +8 -3
- package/dist-client/pages/role/role-template-gap.test.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/helps/auth/roles.en.md +13 -49
- package/helps/auth/roles.ko.md +13 -32
- package/package.json +9 -8
- package/tests/page-state.test.ts +2 -1
- package/tests/password-rule-shown.test.ts +2 -2
- package/tests/person-360-sections.test.ts +9 -5
- package/translations/en.json +5 -1
- package/translations/es.json +5 -1
- package/translations/ja.json +5 -1
- package/translations/ko.json +5 -1
- package/translations/ms.json +5 -1
- package/translations/zh.json +5 -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 } 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 @state() private outcomeCounts = new Map<string, number>()\n @state() private health?: { failures: number; since: string } | 'unknown'\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 /*\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.\n */\n private async countOutcomes(filter: { from: string; to: string; actorId?: string; door?: string }) {\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) return console.error(response.errors)\n this.outcomeCounts = new Map(OUTCOMES.map((outcome, at) => [outcome || 'all', response.data?.[`c${at}`]?.total ?? 0]))\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 this.readHealth()\n }\n }\n\n private async readHealth() {\n try {\n const response = await client.query({ query: gql`{ auditHealth { failures since } }`, fetchPolicy: 'no-cache' })\n this.health = response.errors?.length || !response.data?.auditHealth ? 'unknown' : response.data.auditHealth\n } catch {\n this.health = 'unknown'\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 this.countOutcomes({ ...period, actorId: this.actor?.id, door: this.door })\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":"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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"]}
|
|
@@ -251,7 +251,7 @@ let DomainLinkLManagement = class DomainLinkLManagement extends localize(i18next
|
|
|
251
251
|
if (domainLink.sourceDomain.id === domainLink.targetDomain.id) {
|
|
252
252
|
throw new Error(i18next.t('text.source_and_target_domain_cannot_be_same'));
|
|
253
253
|
}
|
|
254
|
-
const response = await client.
|
|
254
|
+
const response = await client.mutate({ mutation: gql `
|
|
255
255
|
mutation ($domainLink: NewDomainLink!) { createDomainLink(domainLink: $domainLink) { id
|
|
256
256
|
}
|
|
257
257
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"domain-link-management.js","sourceRoot":"","sources":["../../../client/pages/domain-link/domain-link-management.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@material/web/button/elevated-button.js'\nimport '@operato/data-grist/ox-grist.js'\nimport '@operato/data-grist/ox-filters-form.js'\nimport '@operato/data-grist/ox-record-creator.js'\n\nimport { CommonButtonStyles, CommonHeaderStyles, CommonGristStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles'\nimport { PageView } from '@operato/shell'\nimport { css, html } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\nimport { DataGrist, FetchOption } from '@operato/data-grist'\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { notify } from '@operato/layout'\nimport { OxPrompt } from '@operato/popup'\nimport { isMobileDevice } from '@operato/utils'\n\nimport gql from 'graphql-tag'\n\n@customElement('domain-link-management')\nexport class DomainLinkLManagement extends 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 ox-filters-form { flex: 1;\n }\n `\n ]\n\n @property({ type: Object }) gristConfig: any\n @property({ type: String }) mode: 'CARD' | 'GRID' | 'LIST' = isMobileDevice() ? 'CARD' : 'GRID'\n\n @query('ox-grist') private grist!: DataGrist\n\n get context() { return { title: i18next.t('title.domain-link management'),\n search: { handler: (search: string) => { this.grist.searchText = search\n },\n value: this.grist.searchText\n },\n filter: { handler: () => { this.grist.toggleHeadroom()\n }\n },\n help: 'auth/domain-link',\n actions: [\n { title: i18next.t('button.save'),\n action: this.updateDomainLink.bind(this),\n ...CommonButtonStyles.save\n },\n { title: i18next.t('button.delete'),\n action: this.deleteDomainLink.bind(this),\n ...CommonButtonStyles.delete\n }\n ]\n }\n }\n\n render() { const mode = this.mode || (isMobileDevice() ? 'CARD' : 'GRID')\n\n return html`\n <ox-grist class=\"page-fill\" .mode=${mode} .config=${this.gristConfig} .fetchHandler=${this.fetchHandler.bind(this)}>\n <div slot=\"headroom\" class=\"header\">\n <div class=\"filters\">\n <ox-filters-form autofocus without-search></ox-filters-form>\n\n <div id=\"modes\">\n <md-icon @click=${() => (this.mode = 'GRID')} ?active=${mode == 'GRID'}>grid_on</md-icon>\n <md-icon @click=${() => (this.mode = 'LIST')} ?active=${mode == 'LIST'}>format_list_bulleted</md-icon>\n <md-icon @click=${() => (this.mode = 'CARD')} ?active=${mode == 'CARD'}>apps</md-icon>\n </div>\n\n <ox-record-creator id=\"add\" .callback=${this.creationCallback.bind(this)}>\n <button>\n <md-icon>add</md-icon>\n </button>\n </ox-record-creator>\n </div>\n </div>\n </ox-grist>\n `\n }\n\n async pageInitialized(lifecycle: any) { this.gristConfig = { list: { fields: ['sourceDomain', 'targetDomain'],\n details: ['type', 'updatedAt']\n },\n columns: [\n { type: 'gutter', gutterName: 'sequence' },\n { type: 'gutter', gutterName: 'row-selector', multiple: true },\n { type: 'resource-object',\n name: 'sourceDomain',\n header: i18next.t('field.source-domain'),\n record: { editable: true,\n mandatory: true,\n options: { title: i18next.t('title.lookup domains'),\n queryName: 'domains'\n }\n },\n filter: 'search',\n sortable: true,\n width: 150\n },\n { type: 'select',\n name: 'type',\n header: i18next.t('field.type'),\n record: { editable: true,\n mandatory: true,\n options: () => ['', 'has', 'maintains', 'owns']\n },\n filter: 'search',\n width: 200\n },\n { type: 'resource-object',\n name: 'targetDomain',\n header: i18next.t('field.target-domain'),\n record: { editable: true,\n mandatory: true,\n options: { title: i18next.t('title.lookup domains'),\n queryName: 'domains'\n }\n },\n filter: 'search',\n sortable: true,\n width: 150\n },\n { type: 'resource-object',\n name: 'updater',\n header: i18next.t('field.updater'),\n record: { editable: false\n },\n sortable: true,\n width: 120\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: { appendable: false,\n selectable: { multiple: true\n }\n },\n sorters: [\n { name: 'sourceDomain'\n }\n ]\n }\n }\n\n async pageUpdated(changes: any, lifecycle: any) { if (this.active) { // do something here when this page just became as active\n }\n }\n\n async fetchHandler({ page = 1, limit = 100, sortings = [], filters = [] }: FetchOption) { const response = await client.query({ query: gql`\n query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) { responses: domainLinks(filters: $filters, pagination: $pagination, sortings: $sortings) { items { id\n sourceDomain { id\n name\n subdomain\n }\n targetDomain { id\n name\n subdomain\n }\n type\n updater { id\n name\n }\n updatedAt\n }\n total\n }\n }\n `,\n variables: { filters,\n pagination: { page, limit },\n sortings\n }\n })\n\n return { total: response.data.responses.total || 0,\n records: response.data.responses.items || []\n }\n }\n\n private async deleteDomainLink() { 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!]!) { deleteDomainLinks(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 updateDomainLink() { 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 patchField.cuFlag = patch.__dirty__\n\n return patchField\n })\n\n const response = await client.mutate({ mutation: gql`\n mutation ($patches: [DomainLinkPatch!]!) { updateMultipleDomainLink(patches: $patches) { sourceDomain { id\n name\n subdomain\n }\n targetDomain { id\n name\n subdomain\n }\n type\n }\n }\n `,\n variables: { patches\n }\n })\n\n if (!response.errors) { this.grist.fetch()\n }\n }\n }\n\n async creationCallback(domainLink) { try { const { sourceDomain, targetDomain, type } = domainLink\n if (!sourceDomain || !targetDomain || !type) { throw new Error(i18next.t('text.please_fill_all_required_fields'))\n }\n\n if (domainLink.sourceDomain.id === domainLink.targetDomain.id) { throw new Error(i18next.t('text.source_and_target_domain_cannot_be_same'))\n }\n\n const response = await client.query({ query: gql`\n mutation ($domainLink: NewDomainLink!) { createDomainLink(domainLink: $domainLink) { id\n }\n }\n `,\n variables: { domainLink\n },\n context: { hasUpload: true\n }\n })\n\n if (!response.errors) { this.grist.fetch()\n document.dispatchEvent(\n new CustomEvent('notify', { detail: { message: i18next.t('text.data_created_successfully')\n }\n })\n )\n }\n\n return true\n } catch (ex) { console.error(ex)\n document.dispatchEvent(\n new CustomEvent('notify', { detail: { type: 'error',\n message: (ex as Error).message || String(ex)\n }\n })\n )\n return false\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"domain-link-management.js","sourceRoot":"","sources":["../../../client/pages/domain-link/domain-link-management.ts"],"names":[],"mappings":";AAAA,OAAO,4BAA4B,CAAA;AACnC,OAAO,yCAAyC,CAAA;AAChD,OAAO,iCAAiC,CAAA;AACxC,OAAO,wCAAwC,CAAA;AAC/C,OAAO,0CAA0C,CAAA;AAEjD,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AACnI,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC/B,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAClE,OAAO,EAAE,SAAS,EAAe,MAAM,qBAAqB,CAAA;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAE/C,OAAO,GAAG,MAAM,aAAa,CAAA;AAGtB,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,QAAQ,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC;IAA/D;;QAkBuB,SAAI,GAA6B,cAAc,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAA;IAwPjG,CAAC;aA1QiF,WAAM,GAAG;QACvF,qEAAqE;QACrE,qBAAqB;QACrB,eAAe;QACf,iBAAiB;QACjB,kBAAkB;QAClB,GAAG,CAAA;;;;;;;;KAQF;KACF,AAfqF,CAerF;IAOD,IAAI,OAAO;QAAS,OAAO,EAAQ,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,8BAA8B,CAAC;YAC/E,MAAM,EAAE,EAAU,OAAO,EAAE,CAAC,MAAc,EAAE,EAAE;oBAAa,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,MAAM,CAAA;gBAC9F,CAAC;gBACM,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,EAClC;YACI,MAAM,EAAE,EAAU,OAAO,EAAE,GAAG,EAAE;oBAAa,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,CAAA;gBAC7E,CAAC;aACA;YACI,IAAI,EAAE,kBAAkB;YACxB,OAAO,EAAE;gBACP,EAAY,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC;oBACzC,MAAM,EAAE,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC;oBACxC,GAAG,kBAAkB,CAAC,IAAI;iBAClC;gBACM,EAAY,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;oBAC3C,MAAM,EAAE,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC;oBACxC,GAAG,kBAAkB,CAAC,MAAM;iBACpC;aACK,EACL,CAAA;IACD,CAAC;IAEA,MAAM;QAAS,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;QAE3E,OAAO,IAAI,CAAA;0CAC2B,IAAI,YAAY,IAAI,CAAC,WAAW,kBAAkB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;;;;;;gCAMxF,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,YAAY,IAAI,IAAI,MAAM;gCACpD,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,YAAY,IAAI,IAAI,MAAM;gCACpD,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,YAAY,IAAI,IAAI,MAAM;;;oDAGhC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC;;;;;;;;KAQ/E,CAAA;IACJ,CAAC;IAEA,KAAK,CAAC,eAAe,CAAC,SAAc;QAAQ,IAAI,CAAC,WAAW,GAAG,EAAQ,IAAI,EAAE,EAAU,MAAM,EAAE,CAAC,cAAc,EAAE,cAAc,CAAC;gBACzH,OAAO,EAAE,CAAC,MAAM,EAAE,WAAW,CAAC;aACpC;YACI,OAAO,EAAE;gBACP,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE;gBAC1C,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC9D,EAAY,IAAI,EAAE,iBAAiB;oBACjC,IAAI,EAAE,cAAc;oBACpB,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC;oBACxC,MAAM,EAAE,EAAc,QAAQ,EAAE,IAAI;wBAClC,SAAS,EAAE,IAAI;wBACf,OAAO,EAAE,EAAgB,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,sBAAsB,CAAC;4BAC/D,SAAS,EAAE,SAAS;yBAChC;qBACA;oBACQ,MAAM,EAAE,QAAQ;oBAChB,QAAQ,EAAE,IAAI;oBACd,KAAK,EAAE,GAAG;iBAClB;gBACM,EAAY,IAAI,EAAE,QAAQ;oBACxB,IAAI,EAAE,MAAM;oBACZ,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC;oBAC/B,MAAM,EAAE,EAAc,QAAQ,EAAE,IAAI;wBAClC,SAAS,EAAE,IAAI;wBACf,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,CAAC;qBACzD;oBACQ,MAAM,EAAE,QAAQ;oBAChB,KAAK,EAAE,GAAG;iBAClB;gBACM,EAAY,IAAI,EAAE,iBAAiB;oBACjC,IAAI,EAAE,cAAc;oBACpB,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC;oBACxC,MAAM,EAAE,EAAc,QAAQ,EAAE,IAAI;wBAClC,SAAS,EAAE,IAAI;wBACf,OAAO,EAAE,EAAgB,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,sBAAsB,CAAC;4BAC/D,SAAS,EAAE,SAAS;yBAChC;qBACA;oBACQ,MAAM,EAAE,QAAQ;oBAChB,QAAQ,EAAE,IAAI;oBACd,KAAK,EAAE,GAAG;iBAClB;gBACM,EAAY,IAAI,EAAE,iBAAiB;oBACjC,IAAI,EAAE,SAAS;oBACf,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;oBAClC,MAAM,EAAE,EAAc,QAAQ,EAAE,KAAK;qBAC7C;oBACQ,QAAQ,EAAE,IAAI;oBACd,KAAK,EAAE,GAAG;iBAClB;gBACM,EAAY,IAAI,EAAE,UAAU;oBAC1B,IAAI,EAAE,WAAW;oBACjB,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC;oBACrC,MAAM,EAAE,EAAc,QAAQ,EAAE,KAAK;qBAC7C;oBACQ,QAAQ,EAAE,IAAI;oBACd,KAAK,EAAE,GAAG;iBAClB;aACK;YACD,IAAI,EAAE,EAAU,UAAU,EAAE,KAAK;gBAC/B,UAAU,EAAE,EAAY,QAAQ,EAAE,IAAI;iBAC5C;aACA;YACI,OAAO,EAAE;gBACP,EAAY,IAAI,EAAE,cAAc;iBACtC;aACK;SACL,CAAA;IACD,CAAC;IAEA,KAAK,CAAC,WAAW,CAAC,OAAY,EAAE,SAAc;QAAQ,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,CAAO,yDAAyD;QACzI,CAAC;IACD,CAAC;IAEA,KAAK,CAAC,YAAY,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,KAAK,GAAG,GAAG,EAAE,QAAQ,GAAG,EAAE,EAAE,OAAO,GAAG,EAAE,EAAe;QAAQ,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,EAAQ,KAAK,EAAE,GAAG,CAAA;;;;;;;;;;;;;;;;;;;OAmB/I;YACD,SAAS,EAAE,EAAU,OAAO;gBAC1B,UAAU,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE;gBAC3B,QAAQ;aACd;SACA,CAAC,CAAA;QAEC,OAAO,EAAQ,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,CAAC;YACtD,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,EAAE;SAChD,CAAA;IACD,CAAC;IAEQ,KAAK,CAAC,gBAAgB;QAAS,IACnC,MAAM,QAAQ,CAAC,IAAI,CAAC,EAAU,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC;YACjE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,gBAAgB,EAAE,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC;YAClE,aAAa,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,EAAE;YACpD,YAAY,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,EAAE;SACxD,CAAC,EACG,CAAC;YAAO,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;YAChE,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAAS,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,EAAY,QAAQ,EAAE,GAAG,CAAA;;;WAG9F;oBACD,SAAS,EAAE,EAAc,GAAG;qBACpC;iBACA,CAAC,CAAA;gBAEK,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;oBAAW,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAA;oBAClD,MAAM,CAAC,EAAc,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,0BAA0B,EAAE,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC;qBAC5G,CAAC,CAAA;gBACF,CAAC;YACD,CAAC;QACD,CAAC;IACD,CAAC;IAEQ,KAAK,CAAC,gBAAgB;QAAS,IAAI,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAA;QAC1E,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YAAO,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;gBAAW,IAAI,UAAU,GAAQ,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;gBAClI,MAAM,WAAW,GAAG,KAAK,CAAC,eAAe,CAAA;gBACzC,KAAK,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC;oBAAW,UAAU,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,KAAK,CAAA;gBACxF,CAAC;gBACM,UAAU,CAAC,MAAM,GAAG,KAAK,CAAC,SAAS,CAAA;gBAEnC,OAAO,UAAU,CAAA;YACxB,CAAC,CAAC,CAAA;YAEG,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,EAAU,QAAQ,EAAE,GAAG,CAAA;;;;;;;;;;;;SAYzD;gBACD,SAAS,EAAE,EAAY,OAAO;iBACpC;aACA,CAAC,CAAA;YAEG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;gBAAS,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAA;YACvD,CAAC;QACD,CAAC;IACD,CAAC;IAEA,KAAK,CAAC,gBAAgB,CAAC,UAAU;QAAQ,IAAI,CAAC;YAAO,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,IAAI,EAAE,GAAG,UAAU,CAAA;YACxG,IAAI,CAAC,YAAY,IAAI,CAAC,YAAY,IAAI,CAAC,IAAI,EAAE,CAAC;gBAAS,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,sCAAsC,CAAC,CAAC,CAAA;YAC9H,CAAC;YAEI,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,KAAK,UAAU,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC;gBAAS,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,8CAA8C,CAAC,CAAC,CAAA;YACxJ,CAAC;YAEI,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,EAAU,QAAQ,EAAE,GAAG,CAAA;;;;SAIzD;gBACD,SAAS,EAAE,EAAY,UAAU;iBACvC;gBACM,OAAO,EAAE,EAAY,SAAS,EAAE,IAAI;iBAC1C;aACA,CAAC,CAAA;YAEG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;gBAAS,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAA;gBAChD,QAAQ,CAAC,aAAa,CACpB,IAAI,WAAW,CAAC,QAAQ,EAAE,EAAc,MAAM,EAAE,EAAgB,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,gCAAgC,CAAC;qBAC5H;iBACA,CAAC,CACM,CAAA;YACR,CAAC;YAEI,OAAO,IAAI,CAAA;QAChB,CAAC;QAAC,OAAO,EAAE,EAAE,CAAC;YAAO,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;YACjC,QAAQ,CAAC,aAAa,CACpB,IAAI,WAAW,CAAC,QAAQ,EAAE,EAAY,MAAM,EAAE,EAAc,IAAI,EAAE,OAAO;oBACrE,OAAO,EAAG,EAAY,CAAC,OAAO,IAAI,MAAM,CAAC,EAAE,CAAC;iBACtD;aACA,CAAC,CACI,CAAA;YACD,OAAO,KAAK,CAAA;QACjB,CAAC;IACD,CAAC;;AAxP4B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;0DAAiB;AAChB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;mDAAoE;AAEpE;IAA1B,KAAK,CAAC,UAAU,CAAC;8BAAiB,SAAS;oDAAA;AApBjC,qBAAqB;IADjC,aAAa,CAAC,wBAAwB,CAAC;GAC3B,qBAAqB,CA0QjC","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@material/web/button/elevated-button.js'\nimport '@operato/data-grist/ox-grist.js'\nimport '@operato/data-grist/ox-filters-form.js'\nimport '@operato/data-grist/ox-record-creator.js'\n\nimport { CommonButtonStyles, CommonHeaderStyles, CommonGristStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles'\nimport { PageView } from '@operato/shell'\nimport { css, html } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\nimport { DataGrist, FetchOption } from '@operato/data-grist'\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { notify } from '@operato/layout'\nimport { OxPrompt } from '@operato/popup'\nimport { isMobileDevice } from '@operato/utils'\n\nimport gql from 'graphql-tag'\n\n@customElement('domain-link-management')\nexport class DomainLinkLManagement extends 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 ox-filters-form { flex: 1;\n }\n `\n ]\n\n @property({ type: Object }) gristConfig: any\n @property({ type: String }) mode: 'CARD' | 'GRID' | 'LIST' = isMobileDevice() ? 'CARD' : 'GRID'\n\n @query('ox-grist') private grist!: DataGrist\n\n get context() { return { title: i18next.t('title.domain-link management'),\n search: { handler: (search: string) => { this.grist.searchText = search\n },\n value: this.grist.searchText\n },\n filter: { handler: () => { this.grist.toggleHeadroom()\n }\n },\n help: 'auth/domain-link',\n actions: [\n { title: i18next.t('button.save'),\n action: this.updateDomainLink.bind(this),\n ...CommonButtonStyles.save\n },\n { title: i18next.t('button.delete'),\n action: this.deleteDomainLink.bind(this),\n ...CommonButtonStyles.delete\n }\n ]\n }\n }\n\n render() { const mode = this.mode || (isMobileDevice() ? 'CARD' : 'GRID')\n\n return html`\n <ox-grist class=\"page-fill\" .mode=${mode} .config=${this.gristConfig} .fetchHandler=${this.fetchHandler.bind(this)}>\n <div slot=\"headroom\" class=\"header\">\n <div class=\"filters\">\n <ox-filters-form autofocus without-search></ox-filters-form>\n\n <div id=\"modes\">\n <md-icon @click=${() => (this.mode = 'GRID')} ?active=${mode == 'GRID'}>grid_on</md-icon>\n <md-icon @click=${() => (this.mode = 'LIST')} ?active=${mode == 'LIST'}>format_list_bulleted</md-icon>\n <md-icon @click=${() => (this.mode = 'CARD')} ?active=${mode == 'CARD'}>apps</md-icon>\n </div>\n\n <ox-record-creator id=\"add\" .callback=${this.creationCallback.bind(this)}>\n <button>\n <md-icon>add</md-icon>\n </button>\n </ox-record-creator>\n </div>\n </div>\n </ox-grist>\n `\n }\n\n async pageInitialized(lifecycle: any) { this.gristConfig = { list: { fields: ['sourceDomain', 'targetDomain'],\n details: ['type', 'updatedAt']\n },\n columns: [\n { type: 'gutter', gutterName: 'sequence' },\n { type: 'gutter', gutterName: 'row-selector', multiple: true },\n { type: 'resource-object',\n name: 'sourceDomain',\n header: i18next.t('field.source-domain'),\n record: { editable: true,\n mandatory: true,\n options: { title: i18next.t('title.lookup domains'),\n queryName: 'domains'\n }\n },\n filter: 'search',\n sortable: true,\n width: 150\n },\n { type: 'select',\n name: 'type',\n header: i18next.t('field.type'),\n record: { editable: true,\n mandatory: true,\n options: () => ['', 'has', 'maintains', 'owns']\n },\n filter: 'search',\n width: 200\n },\n { type: 'resource-object',\n name: 'targetDomain',\n header: i18next.t('field.target-domain'),\n record: { editable: true,\n mandatory: true,\n options: { title: i18next.t('title.lookup domains'),\n queryName: 'domains'\n }\n },\n filter: 'search',\n sortable: true,\n width: 150\n },\n { type: 'resource-object',\n name: 'updater',\n header: i18next.t('field.updater'),\n record: { editable: false\n },\n sortable: true,\n width: 120\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: { appendable: false,\n selectable: { multiple: true\n }\n },\n sorters: [\n { name: 'sourceDomain'\n }\n ]\n }\n }\n\n async pageUpdated(changes: any, lifecycle: any) { if (this.active) { // do something here when this page just became as active\n }\n }\n\n async fetchHandler({ page = 1, limit = 100, sortings = [], filters = [] }: FetchOption) { const response = await client.query({ query: gql`\n query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) { responses: domainLinks(filters: $filters, pagination: $pagination, sortings: $sortings) { items { id\n sourceDomain { id\n name\n subdomain\n }\n targetDomain { id\n name\n subdomain\n }\n type\n updater { id\n name\n }\n updatedAt\n }\n total\n }\n }\n `,\n variables: { filters,\n pagination: { page, limit },\n sortings\n }\n })\n\n return { total: response.data.responses.total || 0,\n records: response.data.responses.items || []\n }\n }\n\n private async deleteDomainLink() { 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!]!) { deleteDomainLinks(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 updateDomainLink() { 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 patchField.cuFlag = patch.__dirty__\n\n return patchField\n })\n\n const response = await client.mutate({ mutation: gql`\n mutation ($patches: [DomainLinkPatch!]!) { updateMultipleDomainLink(patches: $patches) { sourceDomain { id\n name\n subdomain\n }\n targetDomain { id\n name\n subdomain\n }\n type\n }\n }\n `,\n variables: { patches\n }\n })\n\n if (!response.errors) { this.grist.fetch()\n }\n }\n }\n\n async creationCallback(domainLink) { try { const { sourceDomain, targetDomain, type } = domainLink\n if (!sourceDomain || !targetDomain || !type) { throw new Error(i18next.t('text.please_fill_all_required_fields'))\n }\n\n if (domainLink.sourceDomain.id === domainLink.targetDomain.id) { throw new Error(i18next.t('text.source_and_target_domain_cannot_be_same'))\n }\n\n const response = await client.mutate({ mutation: gql`\n mutation ($domainLink: NewDomainLink!) { createDomainLink(domainLink: $domainLink) { id\n }\n }\n `,\n variables: { domainLink\n },\n context: { hasUpload: true\n }\n })\n\n if (!response.errors) { this.grist.fetch()\n document.dispatchEvent(\n new CustomEvent('notify', { detail: { message: i18next.t('text.data_created_successfully')\n }\n })\n )\n }\n\n return true\n } catch (ex) { console.error(ex)\n document.dispatchEvent(\n new CustomEvent('notify', { detail: { type: 'error',\n message: (ex as Error).message || String(ex)\n }\n })\n )\n return false\n }\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __decorate
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
2
|
import '@things-factory/component-ui';
|
|
3
3
|
import '@operato/list-state/ox-page-state.js';
|
|
4
4
|
import '../../components/partner-info-card.js';
|
|
@@ -6,20 +6,28 @@ import '../../components/partner-role-editor.js';
|
|
|
6
6
|
import '../../components/invite-customer.js';
|
|
7
7
|
import gql from 'graphql-tag';
|
|
8
8
|
import { css, html } from 'lit';
|
|
9
|
-
import { customElement
|
|
10
|
-
import {
|
|
9
|
+
import { customElement } from 'lit/decorators.js';
|
|
10
|
+
import { gqlContext, QueryController } from '@operato/graphql';
|
|
11
11
|
import { i18next } from '@operato/i18n';
|
|
12
12
|
import { PageView } from '@operato/shell';
|
|
13
13
|
import { WorkSurfacePageStyles } from '@operato/styles';
|
|
14
14
|
let PartnerManagement = class PartnerManagement extends PageView {
|
|
15
15
|
constructor() {
|
|
16
16
|
super(...arguments);
|
|
17
|
-
this.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
this.partners = new QueryController(this, gql `
|
|
18
|
+
query {
|
|
19
|
+
customers {
|
|
20
|
+
id
|
|
21
|
+
name
|
|
22
|
+
description
|
|
23
|
+
}
|
|
24
|
+
vendors {
|
|
25
|
+
id
|
|
26
|
+
name
|
|
27
|
+
description
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
`, { context: gqlContext() });
|
|
23
31
|
}
|
|
24
32
|
static { this.styles = [
|
|
25
33
|
/* The frame owns the page shell (ADR-0060 decision 8). `quick-find-list` scrolls inside itself. */
|
|
@@ -34,6 +42,12 @@ let PartnerManagement = class PartnerManagement extends PageView {
|
|
|
34
42
|
}
|
|
35
43
|
`
|
|
36
44
|
]; }
|
|
45
|
+
get customers() {
|
|
46
|
+
return this.partners.data?.customers ?? [];
|
|
47
|
+
}
|
|
48
|
+
get vendors() {
|
|
49
|
+
return this.partners.data?.vendors ?? [];
|
|
50
|
+
}
|
|
37
51
|
get context() {
|
|
38
52
|
return { title: `${i18next.t('title.partners')}`,
|
|
39
53
|
help: 'operato-hub/partners'
|
|
@@ -44,7 +58,11 @@ let PartnerManagement = class PartnerManagement extends PageView {
|
|
|
44
58
|
[i18next.t('label.vendors')]: this.vendors || []
|
|
45
59
|
};
|
|
46
60
|
return html `
|
|
47
|
-
<ox-page-state
|
|
61
|
+
<ox-page-state
|
|
62
|
+
.loading=${this.partners.loading && !this.partners.data}
|
|
63
|
+
.error=${this.partners.error ?? null}
|
|
64
|
+
@retry=${() => this.partners.refetch()}
|
|
65
|
+
>
|
|
48
66
|
<quick-find-list
|
|
49
67
|
class="page-fill"
|
|
50
68
|
.data="${data}"
|
|
@@ -54,7 +72,7 @@ let PartnerManagement = class PartnerManagement extends PageView {
|
|
|
54
72
|
<partner-role-editor
|
|
55
73
|
class="role-editor"
|
|
56
74
|
.customer="${item}"
|
|
57
|
-
@contractTerminated="${this.
|
|
75
|
+
@contractTerminated="${() => this.partners.refetch()}"
|
|
58
76
|
></partner-role-editor>
|
|
59
77
|
`
|
|
60
78
|
: html `<partner-info-card .partner="${item}"></partner-info-card>`}
|
|
@@ -64,68 +82,12 @@ let PartnerManagement = class PartnerManagement extends PageView {
|
|
|
64
82
|
|
|
65
83
|
<invite-customer
|
|
66
84
|
.customers=${this.customers || []}
|
|
67
|
-
@invitationCompleted="${this.
|
|
85
|
+
@invitationCompleted="${() => this.partners.refetch()}"
|
|
68
86
|
></invite-customer>
|
|
69
87
|
</ox-page-state>
|
|
70
88
|
`;
|
|
71
89
|
}
|
|
72
|
-
pageUpdated() {
|
|
73
|
-
if (this.active) {
|
|
74
|
-
this.refreshPartners();
|
|
75
|
-
}
|
|
76
|
-
else { /* this page is deactivated */
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
async refreshPartners() {
|
|
80
|
-
this.loading = !this.customers.length && !this.vendors.length && !this.loadError;
|
|
81
|
-
let response;
|
|
82
|
-
try {
|
|
83
|
-
response = await client.query({ query: gql `
|
|
84
|
-
query { customers { id
|
|
85
|
-
name
|
|
86
|
-
description
|
|
87
|
-
}
|
|
88
|
-
vendors { id
|
|
89
|
-
name
|
|
90
|
-
description
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
`,
|
|
94
|
-
context: gqlContext()
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
catch (error) {
|
|
98
|
-
this.loadError = error;
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
finally {
|
|
102
|
-
this.loading = false;
|
|
103
|
-
}
|
|
104
|
-
if (response.errors?.length) {
|
|
105
|
-
this.loadError = response.errors;
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
this.loadError = null;
|
|
109
|
-
this.customers = response.data.customers;
|
|
110
|
-
this.vendors = response.data.vendors;
|
|
111
|
-
}
|
|
112
90
|
};
|
|
113
|
-
__decorate([
|
|
114
|
-
property({ type: Array }),
|
|
115
|
-
__metadata("design:type", Array)
|
|
116
|
-
], PartnerManagement.prototype, "customers", void 0);
|
|
117
|
-
__decorate([
|
|
118
|
-
property({ type: Array }),
|
|
119
|
-
__metadata("design:type", Array)
|
|
120
|
-
], PartnerManagement.prototype, "vendors", void 0);
|
|
121
|
-
__decorate([
|
|
122
|
-
state(),
|
|
123
|
-
__metadata("design:type", Object)
|
|
124
|
-
], PartnerManagement.prototype, "loading", void 0);
|
|
125
|
-
__decorate([
|
|
126
|
-
state(),
|
|
127
|
-
__metadata("design:type", Object)
|
|
128
|
-
], PartnerManagement.prototype, "loadError", void 0);
|
|
129
91
|
PartnerManagement = __decorate([
|
|
130
92
|
customElement('partner-management')
|
|
131
93
|
], PartnerManagement);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"partner-management.js","sourceRoot":"","sources":["../../../client/pages/partner/partner-management.ts"],"names":[],"mappings":";AAAA,OAAO,8BAA8B,CAAA;AACrC,OAAO,sCAAsC,CAAA;AAC7C,OAAO,uCAAuC,CAAA;AAC9C,OAAO,yCAAyC,CAAA;AAChD,OAAO,qCAAqC,CAAA;AAE5C,OAAO,GAAG,MAAM,aAAa,CAAA;AAC7B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC/B,OAAO,EAAE,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"partner-management.js","sourceRoot":"","sources":["../../../client/pages/partner/partner-management.ts"],"names":[],"mappings":";AAAA,OAAO,8BAA8B,CAAA;AACrC,OAAO,sCAAsC,CAAA;AAC7C,OAAO,uCAAuC,CAAA;AAC9C,OAAO,yCAAyC,CAAA;AAChD,OAAO,qCAAqC,CAAA;AAE5C,OAAO,GAAG,MAAM,aAAa,CAAA;AAC7B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC/B,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AAGvD,IAAM,iBAAiB,GAAvB,MAAM,iBAAkB,SAAQ,QAAQ;IAAxC;;QAcU,aAAQ,GAAG,IAAI,eAAe,CACpC,IAAI,EACJ,GAAG,CAAA;;;;;;;;;;;;;KAaF,EACD,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,CAC1B,CAAA;IAiDH,CAAC;aAhFmD,WAAM,GAAG;QACzD,mGAAmG;QACnG,qBAAqB;QACrB,GAAG,CAAA;;;;;;;;KAQF;KACF,AAZuD,CAYvD;IAqBD,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,IAAI,EAAE,CAAA;IAC5C,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,IAAI,EAAE,CAAA;IAC1C,CAAC;IAED,IAAI,OAAO;QAAS,OAAO,EAAQ,KAAK,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,EAAE;YACtE,IAAI,EAAE,sBAAsB;SAChC,CAAA;IACD,CAAC;IAEA,MAAM;QAAS,MAAM,IAAI,GAAG,EAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,IAAI,EAAE;YACpF,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,IAAI,EAAE;SACpD,CAAA;QAEE,OAAO,IAAI,CAAA;;mBAEI,IAAI,CAAC,QAAQ,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI;iBAC9C,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,IAAI;iBAC3B,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE;;;;iBAI7B,IAAI;4BACO,CAAC,IAAI,EAAE,aAAa,EAAE,EAAE,CAAC,IAAI,CAAA;YAC7C,aAAa,KAAK,OAAO,CAAC,CAAC,CAAC,iBAAiB,CAAC;YAC9C,CAAC,CAAC,IAAI,CAAA;;;+BAGa,IAAI;yCACM,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE;;eAEvD;YACH,CAAC,CAAC,IAAI,CAAA,gCAAgC,IAAI,wBAAwB;SACrE;;;;;qBAKY,IAAI,CAAC,SAAS,IAAI,EAAE;gCACT,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE;;;KAGxD,CAAA;IACJ,CAAC;;AA/EI,iBAAiB;IADtB,aAAa,CAAC,oBAAoB,CAAC;GAC9B,iBAAiB,CAgFtB","sourcesContent":["import '@things-factory/component-ui'\nimport '@operato/list-state/ox-page-state.js'\nimport '../../components/partner-info-card.js'\nimport '../../components/partner-role-editor.js'\nimport '../../components/invite-customer.js'\n\nimport gql from 'graphql-tag'\nimport { css, html } from 'lit'\nimport { customElement } from 'lit/decorators.js'\nimport { gqlContext, QueryController } from '@operato/graphql'\nimport { i18next } from '@operato/i18n'\nimport { PageView } from '@operato/shell'\nimport { WorkSurfacePageStyles } from '@operato/styles'\n\n@customElement('partner-management')\nclass PartnerManagement extends PageView { static styles = [\n /* The frame owns the page shell (ADR-0060 decision 8). `quick-find-list` scrolls inside itself. */\n WorkSurfacePageStyles,\n css`\n /* The card list is a bordered panel with a shadow, so it keeps a gutter off the window edge. */\n :host {\n padding: var(--spacing-large);\n }\n\n .role-editor { flex: 1;\n }\n `\n ]\n\n private partners = new QueryController(\n this,\n gql`\n query {\n customers {\n id\n name\n description\n }\n vendors {\n id\n name\n description\n }\n }\n `,\n { context: gqlContext() }\n )\n\n get customers(): any[] {\n return this.partners.data?.customers ?? []\n }\n\n get vendors(): any[] {\n return this.partners.data?.vendors ?? []\n }\n\n get context() { return { title: `${i18next.t('title.partners')}`,\n help: 'operato-hub/partners'\n }\n }\n\n render() { const data = { [i18next.t('label.customers')]: this.customers || [],\n [i18next.t('label.vendors')]: this.vendors || []\n }\n\n return html`\n <ox-page-state\n .loading=${this.partners.loading && !this.partners.data}\n .error=${this.partners.error ?? null}\n @retry=${() => this.partners.refetch()}\n >\n <quick-find-list\n class=\"page-fill\"\n .data=\"${data}\"\n .contentRenderer=\"${(item, currentTabKey) => html`\n ${currentTabKey === i18next.t('label.customers')\n ? html`\n <partner-role-editor\n class=\"role-editor\"\n .customer=\"${item}\"\n @contractTerminated=\"${() => this.partners.refetch()}\"\n ></partner-role-editor>\n `\n : html`<partner-info-card .partner=\"${item}\"></partner-info-card>`}\n `}\"\n >\n </quick-find-list>\n\n <invite-customer\n .customers=${this.customers || []}\n @invitationCompleted=\"${() => this.partners.refetch()}\"\n ></invite-customer>\n </ox-page-state>\n `\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { test } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { readFileSync } from 'node:fs';
|
|
4
|
+
import ts from 'typescript';
|
|
5
|
+
// Execute the actual page method without constructing its DOM and application shell.
|
|
6
|
+
const source = readFileSync(new URL('./role-privilege-page.ts', import.meta.url), 'utf8');
|
|
7
|
+
const tree = ts.createSourceFile('page.ts', source, ts.ScriptTarget.Latest, true);
|
|
8
|
+
const page = tree.statements.find(node => ts.isClassDeclaration(node) && node.name?.text === 'RolePrivilegePage');
|
|
9
|
+
const method = page.members.find(node => node.name?.getText(tree) === 'removeExtra');
|
|
10
|
+
const compiled = ts.transpileModule(`class Harness { ${method.getText(tree)} }; return Harness`, {
|
|
11
|
+
compilerOptions: { target: ts.ScriptTarget.ES2022, module: ts.ModuleKind.None }
|
|
12
|
+
}).outputText;
|
|
13
|
+
function setup(confirm = () => true) {
|
|
14
|
+
let prompt, saves = 0;
|
|
15
|
+
const Harness = new Function('OxPrompt', 'i18next', 'pairOf', compiled)({ open: async (options) => { prompt = options; return await confirm(); } }, { t: (key, options) => ({ key, ...options }) }, (category, axis) => `${category}:${axis}`);
|
|
16
|
+
const host = new Harness();
|
|
17
|
+
Object.assign(host, {
|
|
18
|
+
subject: { id: 'role-a', name: 'Role A' },
|
|
19
|
+
gap: { templateName: 'Base', extraCount: 1, extra: [{ category: 'finance', axes: ['mutation'] }] },
|
|
20
|
+
assigned: new Set(['read', 'write', 'other']),
|
|
21
|
+
modules: [
|
|
22
|
+
{ category: 'finance', cells: [{ id: 'read', axis: 'query' }, { id: 'write', axis: 'mutation' }] },
|
|
23
|
+
{ category: 'user', cells: [{ id: 'other', axis: 'query' }] }
|
|
24
|
+
],
|
|
25
|
+
sentenceOf: (category, axis) => `${category} ${axis}`,
|
|
26
|
+
onSave: async () => { saves++; }, gapRead: { refetch: async () => { } },
|
|
27
|
+
active: true, dirty: false, saving: false, inherited: false
|
|
28
|
+
});
|
|
29
|
+
Object.defineProperty(host, 'savable', { get: () => !host.saving && !host.inherited });
|
|
30
|
+
/* The role shown is the one the page took its read of - here, the subject. */
|
|
31
|
+
Object.defineProperty(host, 'shownRoleId', { get: () => host.subject?.id });
|
|
32
|
+
return { host, prompt: () => prompt, saves: () => saves };
|
|
33
|
+
}
|
|
34
|
+
test('confirmation names the role and exact extras, then removes only those privileges', async () => {
|
|
35
|
+
const env = setup();
|
|
36
|
+
await env.host.removeExtra();
|
|
37
|
+
assert.equal(env.prompt().text.role, 'Role A');
|
|
38
|
+
assert.equal(env.prompt().text.list, 'finance mutation');
|
|
39
|
+
assert.deepEqual([...env.host.assigned], ['read', 'other']);
|
|
40
|
+
assert.equal(env.saves(), 1);
|
|
41
|
+
});
|
|
42
|
+
test('cancel preserves all privileges', async () => {
|
|
43
|
+
const env = setup(() => false);
|
|
44
|
+
await env.host.removeExtra();
|
|
45
|
+
assert.deepEqual([...env.host.assigned], ['read', 'write', 'other']);
|
|
46
|
+
assert.equal(env.saves(), 0);
|
|
47
|
+
});
|
|
48
|
+
for (const change of [
|
|
49
|
+
host => { host.subject = { id: 'role-b' }; },
|
|
50
|
+
host => { host.gap = { ...host.gap }; },
|
|
51
|
+
host => { host.assigned = new Set(host.assigned); },
|
|
52
|
+
host => { host.dirty = true; },
|
|
53
|
+
host => { host.saving = true; },
|
|
54
|
+
host => { host.inherited = true; },
|
|
55
|
+
host => { host.active = false; }
|
|
56
|
+
]) {
|
|
57
|
+
test(`stale confirmation cannot save: ${change.toString()}`, async () => {
|
|
58
|
+
const env = setup(() => { change(env.host); return true; });
|
|
59
|
+
await env.host.removeExtra();
|
|
60
|
+
assert.equal(env.saves(), 0);
|
|
61
|
+
assert.equal(env.host.assigned.has('write'), true);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
for (const state of ['dirty', 'saving', 'inherited']) {
|
|
65
|
+
test(`does not offer removal while ${state}`, async () => {
|
|
66
|
+
const env = setup();
|
|
67
|
+
env.host[state] = true;
|
|
68
|
+
await env.host.removeExtra();
|
|
69
|
+
assert.equal(env.prompt(), undefined);
|
|
70
|
+
assert.equal(env.saves(), 0);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=role-extra-removal.test.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"role-extra-removal.test.mjs","sourceRoot":"","sources":["../../../client/pages/role/role-extra-removal.test.mjs"],"names":[],"mappings":"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","sourcesContent":["import { test } from 'node:test'\nimport assert from 'node:assert/strict'\nimport { readFileSync } from 'node:fs'\nimport ts from 'typescript'\n\n// Execute the actual page method without constructing its DOM and application shell.\nconst source = readFileSync(new URL('./role-privilege-page.ts', import.meta.url), 'utf8')\nconst tree = ts.createSourceFile('page.ts', source, ts.ScriptTarget.Latest, true)\nconst page = tree.statements.find(node => ts.isClassDeclaration(node) && node.name?.text === 'RolePrivilegePage')\nconst method = page.members.find(node => node.name?.getText(tree) === 'removeExtra')\nconst compiled = ts.transpileModule(`class Harness { ${method.getText(tree)} }; return Harness`, {\n compilerOptions: { target: ts.ScriptTarget.ES2022, module: ts.ModuleKind.None }\n}).outputText\n\nfunction setup(confirm = () => true) {\n let prompt, saves = 0\n const Harness = new Function('OxPrompt', 'i18next', 'pairOf', compiled)(\n { open: async options => { prompt = options; return await confirm() } },\n { t: (key, options) => ({ key, ...options }) },\n (category, axis) => `${category}:${axis}`\n )\n const host = new Harness()\n Object.assign(host, {\n subject: { id: 'role-a', name: 'Role A' },\n gap: { templateName: 'Base', extraCount: 1, extra: [{ category: 'finance', axes: ['mutation'] }] },\n assigned: new Set(['read', 'write', 'other']),\n modules: [\n { category: 'finance', cells: [{ id: 'read', axis: 'query' }, { id: 'write', axis: 'mutation' }] },\n { category: 'user', cells: [{ id: 'other', axis: 'query' }] }\n ],\n sentenceOf: (category, axis) => `${category} ${axis}`,\n onSave: async () => { saves++ }, gapRead: { refetch: async () => {} },\n active: true, dirty: false, saving: false, inherited: false\n })\n Object.defineProperty(host, 'savable', { get: () => !host.saving && !host.inherited })\n /* The role shown is the one the page took its read of - here, the subject. */\n Object.defineProperty(host, 'shownRoleId', { get: () => host.subject?.id })\n return { host, prompt: () => prompt, saves: () => saves }\n}\n\ntest('confirmation names the role and exact extras, then removes only those privileges', async () => {\n const env = setup()\n await env.host.removeExtra()\n assert.equal(env.prompt().text.role, 'Role A')\n assert.equal(env.prompt().text.list, 'finance mutation')\n assert.deepEqual([...env.host.assigned], ['read', 'other'])\n assert.equal(env.saves(), 1)\n})\n\ntest('cancel preserves all privileges', async () => {\n const env = setup(() => false)\n await env.host.removeExtra()\n assert.deepEqual([...env.host.assigned], ['read', 'write', 'other'])\n assert.equal(env.saves(), 0)\n})\n\nfor (const change of [\n host => { host.subject = { id: 'role-b' } },\n host => { host.gap = { ...host.gap } },\n host => { host.assigned = new Set(host.assigned) },\n host => { host.dirty = true },\n host => { host.saving = true },\n host => { host.inherited = true },\n host => { host.active = false }\n]) {\n test(`stale confirmation cannot save: ${change.toString()}`, async () => {\n const env = setup(() => { change(env.host); return true })\n await env.host.removeExtra()\n assert.equal(env.saves(), 0)\n assert.equal(env.host.assigned.has('write'), true)\n })\n}\n\nfor (const state of ['dirty', 'saving', 'inherited']) {\n test(`does not offer removal while ${state}`, async () => {\n const env = setup()\n env.host[state] = true\n await env.host.removeExtra()\n assert.equal(env.prompt(), undefined)\n assert.equal(env.saves(), 0)\n })\n}\n"]}
|