@things-factory/organization 10.1.256 → 10.1.258

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 (27) hide show
  1. package/dist-client/component/approval-line-items-editor.d.ts +2 -2
  2. package/dist-client/component/approval-line-items-editor.js +16 -24
  3. package/dist-client/component/approval-line-items-editor.js.map +1 -1
  4. package/dist-client/component/department-selector.d.ts +2 -2
  5. package/dist-client/component/department-selector.js +48 -46
  6. package/dist-client/component/department-selector.js.map +1 -1
  7. package/dist-client/entity360/department-360.d.ts +3 -4
  8. package/dist-client/entity360/department-360.js +28 -41
  9. package/dist-client/entity360/department-360.js.map +1 -1
  10. package/dist-client/entity360/person-membership-section.d.ts +3 -4
  11. package/dist-client/entity360/person-membership-section.js +28 -42
  12. package/dist-client/entity360/person-membership-section.js.map +1 -1
  13. package/dist-client/pages/employee/employee-list-page.d.ts +7 -9
  14. package/dist-client/pages/employee/employee-list-page.js +42 -69
  15. package/dist-client/pages/employee/employee-list-page.js.map +1 -1
  16. package/dist-client/pages/employee-profile/my-employee-profile-page.d.ts +11 -12
  17. package/dist-client/pages/employee-profile/my-employee-profile-page.js +53 -108
  18. package/dist-client/pages/employee-profile/my-employee-profile-page.js.map +1 -1
  19. package/dist-client/tsconfig.tsbuildinfo +1 -1
  20. package/package.json +10 -10
  21. package/tests/department-query-shape.test.ts +2 -2
  22. package/translations/en.json +0 -2
  23. package/translations/es.json +0 -2
  24. package/translations/ja.json +0 -2
  25. package/translations/ko.json +0 -2
  26. package/translations/ms.json +0 -2
  27. package/translations/zh.json +0 -2
@@ -1,10 +1,10 @@
1
1
  import { __decorate, __metadata } from "tslib";
2
2
  import gql from 'graphql-tag';
3
3
  import { css, html, LitElement } from 'lit';
4
- import { customElement, property, state } from 'lit/decorators.js';
5
- import { client } from '@operato/graphql';
4
+ import { customElement, property } from 'lit/decorators.js';
5
+ import { QueryController } from '@operato/graphql';
6
6
  import { i18next } from '@operato/i18n';
7
- import { entity360Name, readEntity360Door, registerEntity360Section } from '@operato/layout';
7
+ import { entity360Answer, entity360Name, registerEntity360Section } from '@operato/layout';
8
8
  export function registerPersonMembershipSection() {
9
9
  registerEntity360Section('person', {
10
10
  name: 'membership',
@@ -13,6 +13,29 @@ export function registerPersonMembershipSection() {
13
13
  });
14
14
  }
15
15
  let PersonMembershipSection = class PersonMembershipSection extends LitElement {
16
+ constructor() {
17
+ super(...arguments);
18
+ /* The employee records of the person shown (ADR-0190). */
19
+ this.memberships = new QueryController(this, gql `
20
+ query ($filters: [Filter!]) {
21
+ employees(filters: $filters) {
22
+ items {
23
+ id
24
+ name
25
+ jobPosition
26
+ department {
27
+ id
28
+ __typename
29
+ name
30
+ }
31
+ supervisor {
32
+ name
33
+ }
34
+ }
35
+ }
36
+ }
37
+ `, { variables: () => (this.subject?.id ? { filters: [{ name: 'userId', operator: 'eq', value: this.subject.id }] } : undefined) });
38
+ }
16
39
  static { this.styles = css `
17
40
  dl {
18
41
  margin: 0;
@@ -35,41 +58,8 @@ let PersonMembershipSection = class PersonMembershipSection extends LitElement {
35
58
  overflow-wrap: anywhere;
36
59
  }
37
60
  `; }
38
- updated(changed) {
39
- if (changed.has('subject'))
40
- this.read();
41
- }
42
- async read() {
43
- const id = this.subject?.id;
44
- this.answer = undefined;
45
- if (!id)
46
- return;
47
- const response = await client.query({
48
- query: gql `
49
- query ($filters: [Filter!]) {
50
- employees(filters: $filters) {
51
- items {
52
- id
53
- name
54
- jobPosition
55
- department {
56
- id
57
- __typename
58
- name
59
- }
60
- supervisor {
61
- name
62
- }
63
- }
64
- }
65
- }
66
- `,
67
- variables: { filters: [{ name: 'userId', operator: 'eq', value: id }] }
68
- });
69
- /* A later subject may have arrived while this one was being read. */
70
- if (this.subject?.id !== id)
71
- return;
72
- this.answer = readEntity360Door(response, data => data?.employees?.items || []);
61
+ get answer() {
62
+ return entity360Answer(this.memberships, data => data?.employees?.items || []);
73
63
  }
74
64
  render() {
75
65
  const answer = this.answer;
@@ -95,10 +85,6 @@ __decorate([
95
85
  property({ attribute: false }),
96
86
  __metadata("design:type", Object)
97
87
  ], PersonMembershipSection.prototype, "subject", void 0);
98
- __decorate([
99
- state(),
100
- __metadata("design:type", Object)
101
- ], PersonMembershipSection.prototype, "answer", void 0);
102
88
  PersonMembershipSection = __decorate([
103
89
  customElement('person-membership-section')
104
90
  ], PersonMembershipSection);
@@ -1 +1 @@
1
- {"version":3,"file":"person-membership-section.js","sourceRoot":"","sources":["../../client/entity360/person-membership-section.ts"],"names":[],"mappings":"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","sourcesContent":["import gql from 'graphql-tag'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport { client } from '@operato/graphql'\nimport { i18next } from '@operato/i18n'\nimport {\n entity360Name,\n readEntity360Door,\n registerEntity360Section,\n type Entity360DoorAnswer,\n type Entity360Subject\n} from '@operato/layout'\n\n/**\n * The person 360's membership section (ADR-0067, design/ui/entity360-person.md §3): department,\n * position and supervisor, from the person's employee records in this domain.\n *\n * Read through `employees`, which asks `employee:query` - someone without it is told they may not\n * see this, never \"none\". A user can hold more than one employee record here (there is no unique\n * constraint on domain and user - `myEmployees` says why), so every record is shown.\n */\n\ntype Membership = {\n id: string\n name?: string\n jobPosition?: string\n department?: { id: string; name?: string; __typename?: string }\n supervisor?: { name?: string }\n}\n\nexport function registerPersonMembershipSection() {\n registerEntity360Section('person', {\n name: 'membership',\n order: 10,\n render: subject => html`<person-membership-section .subject=${subject}></person-membership-section>`\n })\n}\n\n@customElement('person-membership-section')\nexport class PersonMembershipSection extends LitElement {\n static styles = css`\n dl {\n margin: 0;\n display: grid;\n grid-template-columns: max-content 1fr;\n gap: 4px 12px;\n font: 13px/1.5 sans-serif;\n }\n dl + dl {\n margin-top: 8px;\n padding-top: 8px;\n border-top: 1px dashed var(--md-sys-color-outline-variant);\n }\n dt {\n color: var(--md-sys-color-on-surface-variant);\n }\n dd {\n margin: 0;\n color: var(--md-sys-color-on-surface);\n overflow-wrap: anywhere;\n }\n `\n\n @property({ attribute: false }) subject?: Entity360Subject\n @state() answer?: Entity360DoorAnswer<Membership[]>\n\n updated(changed: Map<string, unknown>) {\n if (changed.has('subject')) this.read()\n }\n\n private async read() {\n const id = this.subject?.id\n this.answer = undefined\n if (!id) return\n\n const response = await client.query({\n query: gql`\n query ($filters: [Filter!]) {\n employees(filters: $filters) {\n items {\n id\n name\n jobPosition\n department {\n id\n __typename\n name\n }\n supervisor {\n name\n }\n }\n }\n }\n `,\n variables: { filters: [{ name: 'userId', operator: 'eq', value: id }] }\n })\n\n /* A later subject may have arrived while this one was being read. */\n if (this.subject?.id !== id) return\n this.answer = readEntity360Door(response, data => data?.employees?.items || [])\n }\n\n render() {\n const answer = this.answer\n /* A blank field says 「없음」 in its own row - leaving it out would read as \"not asked\". */\n const none = i18next.t('text.entity360-none', { defaultValue: 'none' })\n\n return html`<ox-entity360-section\n .heading=${i18next.t('title.person-membership', { defaultValue: 'membership' })}\n .state=${answer?.state ?? 'loading'}\n .message=${answer?.message ?? ''}\n >\n ${(answer?.data || []).map(\n one =>\n html`<dl>\n <dt>${i18next.t('label.department')}</dt>\n <dd>${one.department ? entity360Name(one.department, one.department.name || none) : none}</dd>\n <dt>${i18next.t('label.job-position')}</dt>\n <dd>${one.jobPosition || none}</dd>\n <dt>${i18next.t('label.supervisor-person', { defaultValue: 'supervisor' })}</dt>\n <dd>${one.supervisor?.name || none}</dd>\n </dl>`\n )}\n </ox-entity360-section>`\n }\n}\n"]}
1
+ {"version":3,"file":"person-membership-section.js","sourceRoot":"","sources":["../../client/entity360/person-membership-section.ts"],"names":[],"mappings":";AAAA,OAAO,GAAG,MAAM,aAAa,CAAA;AAC7B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAE3D,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,wBAAwB,EAAyB,MAAM,iBAAiB,CAAA;AAmBjH,MAAM,UAAU,+BAA+B;IAC7C,wBAAwB,CAAC,QAAQ,EAAE;QACjC,IAAI,EAAE,YAAY;QAClB,KAAK,EAAE,EAAE;QACT,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,IAAI,CAAA,uCAAuC,OAAO,+BAA+B;KACrG,CAAC,CAAA;AACJ,CAAC;AAGM,IAAM,uBAAuB,GAA7B,MAAM,uBAAwB,SAAQ,UAAU;IAAhD;;QA0BL,0DAA0D;QAClD,gBAAW,GAAG,IAAI,eAAe,CACvC,IAAI,EACJ,GAAG,CAAA;;;;;;;;;;;;;;;;;;KAkBF,EACD,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAChI,CAAA;IA6BH,CAAC;aA7EQ,WAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;GAqBlB,AArBY,CAqBZ;IA6BD,IAAI,MAAM;QACR,OAAO,eAAe,CAAe,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,IAAI,EAAE,CAAC,CAAA;IAC9F,CAAC;IAED,MAAM;QACJ,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;QAC1B,wFAAwF;QACxF,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,qBAAqB,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC,CAAA;QAEvE,OAAO,IAAI,CAAA;iBACE,OAAO,CAAC,CAAC,CAAC,yBAAyB,EAAE,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC;eACtE,MAAM,EAAE,KAAK,IAAI,SAAS;iBACxB,MAAM,EAAE,OAAO,IAAI,EAAE;;QAE9B,CAAC,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CACxB,GAAG,CAAC,EAAE,CACJ,IAAI,CAAA;kBACI,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC;kBAC7B,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI;kBAClF,OAAO,CAAC,CAAC,CAAC,oBAAoB,CAAC;kBAC/B,GAAG,CAAC,WAAW,IAAI,IAAI;kBACvB,OAAO,CAAC,CAAC,CAAC,yBAAyB,EAAE,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC;kBACpE,GAAG,CAAC,UAAU,EAAE,IAAI,IAAI,IAAI;gBAC9B,CACT;4BACqB,CAAA;IAC1B,CAAC;;AArD+B;IAA/B,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;;wDAA2B;AAxB/C,uBAAuB;IADnC,aAAa,CAAC,2BAA2B,CAAC;GAC9B,uBAAuB,CA8EnC","sourcesContent":["import gql from 'graphql-tag'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\nimport { QueryController } from '@operato/graphql'\nimport { i18next } from '@operato/i18n'\nimport { entity360Answer, entity360Name, registerEntity360Section, type Entity360Subject } from '@operato/layout'\n\n/**\n * The person 360's membership section (ADR-0067, design/ui/entity360-person.md §3): department,\n * position and supervisor, from the person's employee records in this domain.\n *\n * Read through `employees`, which asks `employee:query` - someone without it is told they may not\n * see this, never \"none\". A user can hold more than one employee record here (there is no unique\n * constraint on domain and user - `myEmployees` says why), so every record is shown.\n */\n\ntype Membership = {\n id: string\n name?: string\n jobPosition?: string\n department?: { id: string; name?: string; __typename?: string }\n supervisor?: { name?: string }\n}\n\nexport function registerPersonMembershipSection() {\n registerEntity360Section('person', {\n name: 'membership',\n order: 10,\n render: subject => html`<person-membership-section .subject=${subject}></person-membership-section>`\n })\n}\n\n@customElement('person-membership-section')\nexport class PersonMembershipSection extends LitElement {\n static styles = css`\n dl {\n margin: 0;\n display: grid;\n grid-template-columns: max-content 1fr;\n gap: 4px 12px;\n font: 13px/1.5 sans-serif;\n }\n dl + dl {\n margin-top: 8px;\n padding-top: 8px;\n border-top: 1px dashed var(--md-sys-color-outline-variant);\n }\n dt {\n color: var(--md-sys-color-on-surface-variant);\n }\n dd {\n margin: 0;\n color: var(--md-sys-color-on-surface);\n overflow-wrap: anywhere;\n }\n `\n\n @property({ attribute: false }) subject?: Entity360Subject\n\n /* The employee records of the person shown (ADR-0190). */\n private memberships = new QueryController(\n this,\n gql`\n query ($filters: [Filter!]) {\n employees(filters: $filters) {\n items {\n id\n name\n jobPosition\n department {\n id\n __typename\n name\n }\n supervisor {\n name\n }\n }\n }\n }\n `,\n { variables: () => (this.subject?.id ? { filters: [{ name: 'userId', operator: 'eq', value: this.subject.id }] } : undefined) }\n )\n\n get answer() {\n return entity360Answer<Membership[]>(this.memberships, data => data?.employees?.items || [])\n }\n\n render() {\n const answer = this.answer\n /* A blank field says 「없음」 in its own row - leaving it out would read as \"not asked\". */\n const none = i18next.t('text.entity360-none', { defaultValue: 'none' })\n\n return html`<ox-entity360-section\n .heading=${i18next.t('title.person-membership', { defaultValue: 'membership' })}\n .state=${answer?.state ?? 'loading'}\n .message=${answer?.message ?? ''}\n >\n ${(answer?.data || []).map(\n one =>\n html`<dl>\n <dt>${i18next.t('label.department')}</dt>\n <dd>${one.department ? entity360Name(one.department, one.department.name || none) : none}</dd>\n <dt>${i18next.t('label.job-position')}</dt>\n <dd>${one.jobPosition || none}</dd>\n <dt>${i18next.t('label.supervisor-person', { defaultValue: 'supervisor' })}</dt>\n <dd>${one.supervisor?.name || none}</dd>\n </dl>`\n )}\n </ox-entity360-section>`\n }\n}\n"]}
@@ -21,14 +21,17 @@ export declare class EmployeeListPage extends EmployeeListPage_base {
21
21
  gristConfig: any;
22
22
  mode: 'CARD' | 'GRID' | 'LIST';
23
23
  private grist;
24
- /** The department tree, its selection, and whether the rail is showing. */
25
- private departments?;
24
+ /** The department chosen on the rail, and whether the rail is showing. */
26
25
  private selectedDepartment?;
27
- private departmentsLoaded;
28
- private departmentsError;
29
26
  private railFolded;
30
27
  /** Whether this person issues employees' certificates. */
31
28
  private issuesCertificates;
29
+ /**
30
+ * The departments the rail draws (ADR-0190). departmentRoots answers with a list, and the tree draws from
31
+ * the first root - a fragment spread straight onto the list is refused by the server.
32
+ */
33
+ private departmentsRead;
34
+ private get departments();
32
35
  get context(): {
33
36
  title: string;
34
37
  search: {
@@ -65,11 +68,6 @@ export declare class EmployeeListPage extends EmployeeListPage_base {
65
68
  * 트리에서 고른 부서가 목록의 부서 조건이다 — 조건은 하나고, 그것을 고르는 자리도 하나다.
66
69
  */
67
70
  private onSelectDepartment;
68
- /**
69
- * The departments the rail draws. departmentRoots answers with a list, and the tree draws from
70
- * the first root - a fragment spread straight onto the list is refused by the server.
71
- */
72
- private fetchDepartments;
73
71
  /** One certificate of the one employee selected. */
74
72
  private issueCertificate;
75
73
  pageInitialized(lifecycle: any): Promise<void>;
@@ -10,7 +10,7 @@ import { customElement, property, query, state } from 'lit/decorators.js';
10
10
  import { ScopedElementsMixin } from '@open-wc/scoped-elements';
11
11
  import { OxPrompt } from '@operato/popup';
12
12
  import { DataGrist } from '@operato/data-grist';
13
- import { client } from '@operato/graphql';
13
+ import { client, QueryController } from '@operato/graphql';
14
14
  import { i18next, localize } from '@operato/i18n';
15
15
  import { notify, openPopup } from '@operato/layout';
16
16
  import { PageView } from '@operato/shell';
@@ -25,11 +25,42 @@ let EmployeeListPage = class EmployeeListPage extends p13n(localize(i18next)(Sco
25
25
  constructor() {
26
26
  super(...arguments);
27
27
  this.mode = isMobileDevice() ? 'CARD' : 'GRID';
28
- this.departmentsLoaded = false;
29
- this.departmentsError = null;
30
28
  this.railFolded = false;
31
29
  /** Whether this person issues employees' certificates. */
32
30
  this.issuesCertificates = false;
31
+ /**
32
+ * The departments the rail draws (ADR-0190). departmentRoots answers with a list, and the tree draws from
33
+ * the first root - a fragment spread straight onto the list is refused by the server.
34
+ */
35
+ this.departmentsRead = new QueryController(this, gql `
36
+ query {
37
+ responses: departmentRoots {
38
+ items {
39
+ ...EmployeeDepartmentFragment
40
+ children {
41
+ ...EmployeeDepartmentFragment
42
+ children {
43
+ ...EmployeeDepartmentFragment
44
+ children {
45
+ ...EmployeeDepartmentFragment
46
+ children {
47
+ ...EmployeeDepartmentFragment
48
+ }
49
+ }
50
+ }
51
+ }
52
+ }
53
+ }
54
+ }
55
+
56
+ fragment EmployeeDepartmentFragment on Department {
57
+ id
58
+ controlNo
59
+ name
60
+ description
61
+ active
62
+ }
63
+ `);
33
64
  }
34
65
  static { this.styles = [
35
66
  /* The work surface frame for a list screen (ADR-0060 decision 8). */
@@ -146,6 +177,10 @@ let EmployeeListPage = class EmployeeListPage extends p13n(localize(i18next)(Sco
146
177
  static get scopedElements() {
147
178
  return { 'employee-importer': EmployeeImporter };
148
179
  }
180
+ /* Every root department, not just the first - the rail draws an array. */
181
+ get departments() {
182
+ return this.departmentsRead.data?.responses?.items;
183
+ }
149
184
  get context() {
150
185
  return {
151
186
  title: i18next.t('title.employee list'),
@@ -202,9 +237,9 @@ let EmployeeListPage = class EmployeeListPage extends p13n(localize(i18next)(Sco
202
237
  </button>
203
238
  </div>
204
239
  <ox-page-state
205
- .loading=${!this.departmentsLoaded && !this.departmentsError}
206
- .error=${this.departmentsError}
207
- @retry=${() => this.fetchDepartments()}
240
+ .loading=${this.departmentsRead.loading}
241
+ .error=${this.departmentsRead.error ?? null}
242
+ @retry=${() => this.departmentsRead.refetch()}
208
243
  >
209
244
  ${this.departments?.length
210
245
  ? html `<button
@@ -254,55 +289,6 @@ let EmployeeListPage = class EmployeeListPage extends p13n(localize(i18next)(Sco
254
289
  this.grist?.fetch();
255
290
  this.updateContext();
256
291
  }
257
- /**
258
- * The departments the rail draws. departmentRoots answers with a list, and the tree draws from
259
- * the first root - a fragment spread straight onto the list is refused by the server.
260
- */
261
- async fetchDepartments() {
262
- this.departmentsError = null;
263
- try {
264
- const response = await client.query({
265
- query: gql `
266
- query {
267
- responses: departmentRoots {
268
- items {
269
- ...EmployeeDepartmentFragment
270
- children {
271
- ...EmployeeDepartmentFragment
272
- children {
273
- ...EmployeeDepartmentFragment
274
- children {
275
- ...EmployeeDepartmentFragment
276
- children {
277
- ...EmployeeDepartmentFragment
278
- }
279
- }
280
- }
281
- }
282
- }
283
- }
284
- }
285
-
286
- fragment EmployeeDepartmentFragment on Department {
287
- id
288
- controlNo
289
- name
290
- description
291
- active
292
- }
293
- `
294
- });
295
- if (response.errors?.length) {
296
- throw response.errors[0];
297
- }
298
- /* Every root department, not just the first - the rail draws an array. */
299
- this.departments = response.data.responses?.items;
300
- this.departmentsLoaded = true;
301
- }
302
- catch (error) {
303
- this.departmentsError = error;
304
- }
305
- }
306
292
  /** One certificate of the one employee selected. */
307
293
  async issueCertificate(kind) {
308
294
  const selected = this.grist.selected;
@@ -585,7 +571,6 @@ let EmployeeListPage = class EmployeeListPage extends p13n(localize(i18next)(Sco
585
571
  rows: { selectable: { multiple: true } },
586
572
  sorters: [{ name: 'controlNo' }]
587
573
  };
588
- this.fetchDepartments();
589
574
  }
590
575
  async pageUpdated(changes, lifecycle) {
591
576
  if (this.active) {
@@ -835,25 +820,13 @@ __decorate([
835
820
  __decorate([
836
821
  query('ox-grist'),
837
822
  __metadata("design:type", DataGrist
838
- /** The department tree, its selection, and whether the rail is showing. */
823
+ /** The department chosen on the rail, and whether the rail is showing. */
839
824
  )
840
825
  ], EmployeeListPage.prototype, "grist", void 0);
841
- __decorate([
842
- state(),
843
- __metadata("design:type", Array)
844
- ], EmployeeListPage.prototype, "departments", void 0);
845
826
  __decorate([
846
827
  state(),
847
828
  __metadata("design:type", Department)
848
829
  ], EmployeeListPage.prototype, "selectedDepartment", void 0);
849
- __decorate([
850
- state(),
851
- __metadata("design:type", Object)
852
- ], EmployeeListPage.prototype, "departmentsLoaded", void 0);
853
- __decorate([
854
- state(),
855
- __metadata("design:type", Object)
856
- ], EmployeeListPage.prototype, "departmentsError", void 0);
857
830
  __decorate([
858
831
  state(),
859
832
  __metadata("design:type", Object)
@@ -1 +1 @@
1
- {"version":3,"file":"employee-list-page.js","sourceRoot":"","sources":["../../../client/pages/employee/employee-list-page.ts"],"names":[],"mappings":"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","sourcesContent":["import '@operato/data-grist'\nimport '@operato/data-tree'\nimport '@operato/list-state/ox-empty-note.js'\nimport '@operato/list-state/ox-page-state.js'\nimport '@things-factory/contact/dist-client'\n\nimport gql from 'graphql-tag'\nimport { css, html } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements'\nimport { OxPrompt } from '@operato/popup'\nimport { Contact } from '@operato/contact/ox-contact.js'\nimport { DataGrist, FetchOption, GristRecord } 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 { CommonHeaderStyles, CommonGristStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles'\nimport { isMobileDevice } from '@operato/utils'\nimport { p13n } from '@operato/p13n'\n\nimport { hasPrivilege } from '@things-factory/auth-base/dist-client'\nimport { issueDocument } from '@things-factory/pdf/dist-client'\n\nimport { Department } from '../../types/department'\nimport { EmployeeImporter } from './employee-importer'\n\n@customElement('employee-list-page')\nexport class EmployeeListPage extends p13n(localize(i18next)(ScopedElementsMixin(PageView))) {\n 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 --ox-pfp-size: 40px;\n --grid-record-emphasized-background-color: #8b0000;\n --grid-record-emphasized-color: #ff6b6b;\n }\n\n .header {\n grid-template-areas: 'filters';\n }\n\n /*\n * The rail is how you narrow the list to one department; the list is the content\n * (ADR-0060 decision 8, and the ruling of 2026-09-18 that folded the by-department screen\n * into this one). It folds away, because a screen looking at everyone does not need it.\n */\n [body] {\n flex: 1;\n display: flex;\n flex-direction: row;\n min-height: 0;\n }\n\n [rail] {\n display: flex;\n flex-direction: column;\n width: 240px;\n min-width: 240px;\n border-right: 1px solid var(--ui-line, var(--md-sys-color-outline-variant));\n overflow: auto;\n }\n\n [rail][folded] {\n display: none;\n }\n\n [rail-head] {\n display: flex;\n align-items: center;\n gap: var(--spacing-small, 4px);\n padding: var(--spacing-medium, 8px) var(--spacing-medium, 8px) 0;\n font: var(--label-font, inherit);\n color: var(--ui-muted, var(--md-sys-color-on-surface-variant));\n }\n\n /* The word keeps its line. Sharing the row with a filler let it shrink and break in half. */\n [rail-head] > span {\n flex: 0 0 auto;\n white-space: nowrap;\n }\n\n [rail-head] button,\n /*\n * Going back to everyone. Picking a department narrows the list, and without this there is no\n * way out of that except reloading the screen.\n */\n button[all-departments] {\n width: calc(100% - 16px);\n margin: 4px 8px;\n padding: 6px 10px;\n text-align: left;\n border: 1px solid transparent;\n border-radius: var(--md-sys-shape-corner-small, 6px);\n background: transparent;\n color: var(--ui-muted, var(--md-sys-color-on-surface-variant));\n font: inherit;\n cursor: pointer;\n }\n\n button[all-departments][selected] {\n background: var(--md-sys-color-secondary-container);\n color: var(--md-sys-color-on-secondary-container);\n }\n\n [rail-toggle] {\n display: flex;\n align-items: center;\n border: none;\n background: transparent;\n color: inherit;\n cursor: pointer;\n padding: 2px;\n }\n\n [rail-toggle] {\n align-self: flex-start;\n margin: var(--spacing-medium, 8px) 0 0 var(--spacing-small, 4px);\n }\n\n ox-tree {\n flex: 1;\n overflow: auto;\n }\n\n ox-grist {\n flex: 1;\n min-width: 0;\n }\n\n @media screen and (max-width: 780px) {\n [rail] {\n display: none;\n }\n }\n `\n ]\n\n static get scopedElements() {\n return { 'employee-importer': EmployeeImporter }\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 /** The department tree, its selection, and whether the rail is showing. */\n @state() private departments?: Department[]\n @state() private selectedDepartment?: Department\n @state() private departmentsLoaded = false\n @state() private departmentsError: unknown = null\n @state() private railFolded = false\n /** Whether this person issues employees' certificates. */\n @state() private issuesCertificates = false\n\n get context() {\n return {\n title: i18next.t('title.employee list'),\n search: {\n handler: (search: string) => {\n this.grist.searchText = search\n },\n value: this.grist?.searchText || ''\n },\n filter: {\n handler: () => {\n this.grist.toggleHeadroom()\n }\n },\n help: 'organization/employee',\n actions: [\n /* Certificates of the selected employee - for whoever issues them (`employee-certificate`, ADR-0176 decision 5). */\n ...(this.issuesCertificates\n ? [\n { icon: 'workspace_premium', title: i18next.t('button.issue-employment-certificate'), action: () => this.issueCertificate('organization.employment-certificate') },\n { icon: 'history_edu', title: i18next.t('button.issue-career-certificate'), action: () => this.issueCertificate('organization.career-certificate') }\n ]\n : []),\n { icon: 'save', title: i18next.t('button.save'), action: this.onUpdateEmployee.bind(this) },\n {\n icon: 'delete',\n title: i18next.t('button.delete'),\n action: this.onDeleteEmployee.bind(this),\n emphasis: { danger: true }\n }\n ],\n exportable: { name: i18next.t('title.employee list'), data: this.exportHandler.bind(this) },\n importable: { handler: this.importHandler.bind(this) }\n }\n }\n\n render() {\n const mode = this.mode || (isMobileDevice() ? 'CARD' : 'GRID')\n\n return html`\n <div body class=\"page-fill\">\n ${\n this.railFolded\n ? html`<button\n rail-toggle\n title=${i18next.t('title.department list')}\n @click=${() => (this.railFolded = false)}\n >\n <md-icon>account_tree</md-icon>\n </button>`\n : html`<aside rail>\n <div rail-head>\n <span>${i18next.t('title.department list')}</span>\n <div filler style=\"flex: 1\"></div>\n <button title=${i18next.t('label.fold')} @click=${() => (this.railFolded = true)}>\n <md-icon>chevron_left</md-icon>\n </button>\n </div>\n <ox-page-state\n .loading=${!this.departmentsLoaded && !this.departmentsError}\n .error=${this.departmentsError}\n @retry=${() => this.fetchDepartments()}\n >\n ${\n this.departments?.length\n ? html`<button\n all-departments\n ?selected=${!this.selectedDepartment}\n @click=${() => this.onSelectDepartment(undefined)}\n >\n ${i18next.t('text.all departments')}\n </button>\n <ox-tree\n .data=${this.departments}\n .selected=${this.selectedDepartment}\n @select=${(e: CustomEvent) => this.onSelectDepartment(e.detail as Department)}\n id-property=\"controlNo\"\n label-property=\"name\"\n ></ox-tree>`\n : html`<ox-empty-note\n icon=\"account_tree\"\n title=${i18next.t('text.no departments yet')}\n description=${i18next.t('text.departments are made on the department screen')}\n ></ox-empty-note>`\n }\n </ox-page-state>\n </aside>`\n }\n\n <ox-grist\n .mode=${mode}\n .config=${this.gristConfig}\n .fetchHandler=${this.fetchHandler.bind(this)}\n .personalConfigProvider=${this.getPagePreferenceProvider('ox-grist')!}\n >\n <div slot=\"headroom\" class=\"header\">\n <div class=\"filters\">\n <ox-filters-form class=\"filter\" autofocus without-search></ox-filters-form>\n </div>\n </div>\n\n <ox-grist-personalizer slot=\"setting\"></ox-grist-personalizer>\n </ox-grist>\n </div>\n `\n }\n\n /**\n * 트리에서 고른 부서가 목록의 부서 조건이다 — 조건은 하나고, 그것을 고르는 자리도 하나다.\n */\n private onSelectDepartment(department?: Department) {\n this.selectedDepartment = department\n this.grist?.fetch()\n this.updateContext()\n }\n\n /**\n * The departments the rail draws. departmentRoots answers with a list, and the tree draws from\n * the first root - a fragment spread straight onto the list is refused by the server.\n */\n private async fetchDepartments() {\n this.departmentsError = null\n\n try {\n const response = await client.query({\n query: gql`\n query {\n responses: departmentRoots {\n items {\n ...EmployeeDepartmentFragment\n children {\n ...EmployeeDepartmentFragment\n children {\n ...EmployeeDepartmentFragment\n children {\n ...EmployeeDepartmentFragment\n children {\n ...EmployeeDepartmentFragment\n }\n }\n }\n }\n }\n }\n }\n\n fragment EmployeeDepartmentFragment on Department {\n id\n controlNo\n name\n description\n active\n }\n `\n })\n\n if (response.errors?.length) {\n throw response.errors[0]\n }\n\n /* Every root department, not just the first - the rail draws an array. */\n this.departments = response.data.responses?.items\n this.departmentsLoaded = true\n } catch (error) {\n this.departmentsError = error\n }\n }\n\n /** One certificate of the one employee selected. */\n private async issueCertificate(kind: string) {\n const selected = this.grist.selected\n if (selected.length !== 1 || !selected[0].id) {\n notify({ level: 'warn', message: i18next.t('text.select-one-employee') })\n return\n }\n await issueDocument({ kind, refId: selected[0].id })\n }\n\n async pageInitialized(lifecycle: any) {\n hasPrivilege({ category: 'employee-certificate', privilege: 'mutation', domainOwnerGranted: true }).then(may => {\n this.issuesCertificates = may\n this.updateContext()\n })\n this.gristConfig = {\n pagination: { pages: [50, 100, 200] },\n list: {\n thumbnail: 'profile',\n fields: ['controlNo', 'name'],\n details: ['email', 'department', 'hiredOn', 'updatedAt']\n },\n columns: [\n { type: 'gutter', gutterName: 'sequence', fixed: true },\n { type: 'gutter', gutterName: 'row-selector', multiple: true, fixed: true },\n {\n type: 'gutter',\n gutterName: 'button',\n header: i18next.t('field.register-account'),\n icon: record => (record.id && !record.user ? 'badge' : ''),\n iconOnly: false,\n title: record => (record.id && !record.user ? i18next.t('button.register-account') : ''),\n width: 80,\n handlers: {\n click: (columns, data, column, record, rowIndex) => {\n if (!record || !record.id || record.user) {\n return\n }\n\n this.attachSystemUser(record)\n }\n }\n },\n {\n type: 'image',\n name: 'profile',\n header: i18next.t('button.edit-contact'),\n width: 80,\n record: {\n align: 'center',\n renderer: function (value, column, record, rowIndex, field) {\n return html`<ox-pfp-view .profile=${record.profile} .name=${record.name || '+'}></ox-pfp-view>`\n }\n },\n handlers: {\n click: async (columns, data, column, record, rowIndex) => {\n if (record && record.contact) {\n this.openContactPopup(record)\n } else {\n this.openContactSelector(record)\n }\n }\n }\n },\n {\n type: 'string',\n name: 'controlNo',\n fixed: true,\n header: i18next.t('field.control-no'),\n record: { editable: true, mandatory: true },\n filter: 'search',\n sortable: true,\n width: 105\n },\n {\n type: 'string',\n name: 'name',\n fixed: true,\n header: i18next.t('field.name'),\n record: { editable: true, mandatory: true },\n filter: 'search',\n sortable: true,\n width: 100\n },\n {\n type: 'string',\n name: 'alias',\n header: i18next.t('label.alias'),\n record: { editable: true },\n filter: 'search',\n sortable: false,\n width: 110\n },\n {\n type: 'resource-object',\n name: 'user',\n header: i18next.t('field.system-user'),\n record: {\n editable: true,\n options: {\n title: i18next.t('title.lookup system-user'),\n queryName: 'users',\n basicArgs: { filters: [{ name: 'userType', operator: 'eq', value: 'user' }] },\n descriptionField: 'email',\n columns: [\n { name: 'id', hidden: true },\n { name: 'name', header: i18next.t('field.name'), filter: 'search' },\n { name: 'email', header: i18next.t('field.email'), filter: 'search' }\n ],\n list: { fields: ['name', 'email'] }\n }\n },\n sortable: false,\n filter: 'search',\n width: 100\n },\n {\n type: 'code',\n name: 'type',\n header: i18next.t('field.type', { defaultValue: 'type' }),\n width: 115,\n sortable: true,\n filter: true,\n record: { editable: true, codeName: 'EMPLOYEE_TYPE', selectDispOpt: 'name' }\n },\n {\n type: 'department-object',\n name: 'department',\n header: i18next.t('field.department'),\n record: { editable: true },\n sortable: false,\n /* The rail narrows by department; a second department field here would be the same condition twice. */\n filter: false,\n width: 130\n },\n {\n type: 'resource-object',\n name: 'supervisor',\n header: i18next.t('field.supervisor'),\n record: {\n editable: true,\n options: {\n title: i18next.t('title.employee list'),\n queryName: 'employees',\n pagination: { pages: [50, 100, 200] },\n basicArgs: { filters: [{ name: 'active', operator: 'eq', value: true }] },\n list: { fields: ['controlNo', 'name', 'alias', 'hiredOn'] },\n columns: [\n { name: 'id', hidden: true },\n {\n name: 'controlNo',\n width: 120,\n header: { renderer: () => i18next.t('field.control-no') },\n filter: 'search',\n sortable: true\n },\n {\n name: 'name',\n width: 120,\n header: { renderer: () => i18next.t('field.name') },\n filter: 'search',\n sortable: true\n },\n {\n name: 'alias',\n width: 150,\n header: { renderer: () => i18next.t('label.alias') },\n filter: 'search',\n sortable: true\n },\n {\n type: 'code',\n name: 'type',\n width: 110,\n header: { renderer: () => i18next.t('label.type', { defaultValue: 'type' }) },\n record: { editable: false, codeName: 'EMPLOYEE_TYPE', selectDispOpt: 'name' }\n },\n {\n type: 'code',\n name: 'jobPosition',\n width: 110,\n header: { renderer: () => i18next.t('label.job-position') },\n record: { editable: false, codeName: 'JOB_POSITION', selectDispOpt: 'name' }\n },\n {\n type: 'code',\n name: 'jobResponsibility',\n width: 200,\n header: { renderer: () => i18next.t('label.job-responsibility') },\n record: { editable: false, codeName: 'JOB_RESPONSIBILITY', selectDispOpt: 'name' }\n },\n { type: 'date', name: 'hiredOn', header: { renderer: () => i18next.t('field.hired-on') }, width: 120 }\n ],\n valueField: 'id',\n nameField: 'name',\n descriptionField: 'controlNo'\n }\n },\n sortable: false,\n width: 120\n },\n {\n type: 'string',\n name: 'email',\n header: i18next.t('field.email'),\n width: 200,\n record: {\n editable: false,\n renderer: function (value, column, record, rowIndex, field) {\n return record.contact ? record.contact.email : ''\n }\n },\n sortable: false\n },\n {\n type: 'string',\n name: 'phone',\n header: i18next.t('field.phone'),\n width: 130,\n record: {\n editable: false,\n renderer: function (value, column, record, rowIndex, field) {\n return record.contact ? record.contact.phone : ''\n }\n },\n sortable: false\n },\n {\n type: 'code',\n name: 'jobResponsibility',\n header: i18next.t('label.job-responsibility'),\n width: 175,\n record: { editable: true, codeName: 'JOB_RESPONSIBILITY', selectDispOpt: 'name' },\n filter: true\n },\n {\n type: 'code',\n name: 'jobPosition',\n header: i18next.t('label.job-position'),\n width: 100,\n record: { editable: true, codeName: 'JOB_POSITION', selectDispOpt: 'name' },\n filter: true\n },\n {\n type: 'date',\n name: 'hiredOn',\n header: i18next.t('field.hired-on'),\n width: 120,\n record: { editable: true },\n sortable: true\n },\n {\n type: 'date',\n name: 'retiredOn',\n header: i18next.t('label.retired-at'),\n width: 120,\n record: { editable: true }\n },\n {\n type: 'checkbox',\n name: 'active',\n label: true,\n header: i18next.t('field.active'),\n width: 70,\n record: { align: 'center', editable: true },\n filter: true,\n sortable: false\n },\n {\n type: 'string',\n name: 'note',\n header: i18next.t('field.note'),\n width: 200,\n record: { editable: true },\n filter: 'search'\n },\n { type: 'resource-object', name: 'updater', header: i18next.t('field.updater'), width: 90, sortable: false },\n { type: 'datetime', name: 'updatedAt', header: i18next.t('field.updated_at'), width: 180, sortable: true },\n { type: 'resource-object', name: 'contact', hidden: true }\n ],\n rows: { selectable: { multiple: true } },\n sorters: [{ name: 'controlNo' }]\n }\n\n this.fetchDepartments()\n }\n\n async pageUpdated(changes: any, lifecycle: any) {\n if (this.active) {\n // do something here when this page just became as active\n }\n }\n\n async fetchHandler({ page = 1, limit = 100, sortings = [], filters = [] }: FetchOption) {\n /* The rail's selection is the department condition; nothing else sets one. */\n if (this.selectedDepartment) {\n filters = [...filters, { name: 'departmentId', operator: 'eq', value: this.selectedDepartment.id }]\n }\n\n const response = await client.query({\n query: gql`\n query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {\n responses: employees(filters: $filters, pagination: $pagination, sortings: $sortings) {\n items {\n id\n controlNo\n name\n alias\n type\n jobResponsibility\n jobPosition\n active\n email\n phone\n user {\n id\n name\n }\n department {\n id\n __typename\n controlNo\n name\n description\n }\n supervisor {\n id\n name\n controlNo\n }\n note\n hiredOn\n retiredOn\n contact {\n id\n email\n phone\n address\n }\n profile {\n left\n top\n zoom\n picture\n }\n updater {\n id\n name\n }\n updatedAt\n }\n total\n }\n }\n `,\n variables: { filters, pagination: { page, limit }, sortings }\n })\n\n const records = response.data.responses.items\n\n return { total: response.data.responses.total || 0, records }\n }\n\n async onDeleteEmployee() {\n if (await OxPrompt.confirmDelete({ count: this.grist?.selected?.length })) {\n const ids = this.grist.selected.map(record => record.id)\n if (ids && ids.length > 0) {\n const response = await client.mutate({\n mutation: gql`\n mutation ($ids: [String!]!) {\n deleteEmployees(ids: $ids)\n }\n `,\n variables: { ids }\n })\n\n if (!response.errors) {\n this.grist.fetch()\n notify({ message: i18next.t('text.deleted') })\n }\n }\n }\n }\n\n async onUpdateEmployee() {\n let patches = this.grist.dirtyRecords\n if (patches && patches.length) {\n patches = patches.map(patch => {\n let patchField: any = patch.id ? { id: patch.id } : {}\n const dirtyFields = patch.__dirtyfields__\n for (let key in dirtyFields) {\n patchField[key] = dirtyFields[key].after\n }\n patchField.cuFlag = patch.__dirty__\n\n return patchField\n })\n\n const response = await client.mutate({\n mutation: gql`\n mutation ($patches: [EmployeePatch!]!) {\n updateMultipleEmployee(patches: $patches) {\n name\n }\n }\n `,\n variables: { patches }\n })\n\n if (!response.errors) {\n this.grist.fetch()\n }\n }\n }\n\n async exportHandler() {\n const exportTargets = this.grist.selected.length ? this.grist.selected : this.grist.dirtyData.records\n const targetFieldSet = new Set([\n 'id',\n 'controlNo',\n 'name',\n 'alias',\n 'type',\n 'hiredOn',\n 'retiredOn',\n 'active',\n 'note'\n ])\n\n return exportTargets.map(employee => {\n let tempObj = {}\n for (const field of targetFieldSet) {\n tempObj[field] = employee[field]\n }\n\n return tempObj\n })\n }\n\n async importHandler(records) {\n const popup = openPopup(\n html`\n <employee-importer\n .employees=${records}\n @imported=${() => {\n history.back()\n this.grist.fetch()\n }}\n ></employee-importer>\n `,\n { backdrop: true, size: 'large', title: i18next.t('title.import employee') }\n )\n\n popup.onclosed = () => {\n this.grist.fetch()\n }\n }\n\n async openContactPopup(record: GristRecord) {\n if (!record.contact?.id) {\n return\n }\n\n const popup = openPopup(\n html`\n <contact-popup\n .contactId=${record.contact.id}\n @change=${() => {\n this.grist.fetch()\n }}\n @detach=${() => {\n this.detachContact(record)\n }}\n detachable\n ></contact-popup>\n `,\n { backdrop: true, size: 'large', title: i18next.t('title.contact') }\n )\n }\n\n async openContactSelector(record: GristRecord) {\n const popup = openPopup(\n html`\n <contact-selector .confirmCallback=${selected => this.attachContact(record, selected)}></contact-selector>\n `,\n { backdrop: true, size: 'large', title: i18next.t('title.contact') }\n )\n }\n\n async attachContact(record: GristRecord, contact: Contact) {\n if (record.id) {\n const response = await client.mutate({\n mutation: gql`\n mutation ($id: String!, $contactId: String!) {\n attachContact(id: $id, contactId: $contactId) {\n id\n }\n }\n `,\n variables: { id: record.id, contactId: contact.id }\n })\n\n this.grist.fetch()\n } else if (contact?.id) {\n this.grist.addRecord({\n name: contact.name,\n contact: {\n id: contact.id,\n name: contact.name,\n email: (contact as any).email,\n phone: (contact as any).phone,\n address: (contact as any).address\n }\n })\n this.grist.refresh()\n await this.grist.requestUpdate()\n\n this.grist.checkDirties()\n }\n }\n\n async detachContact(record) {\n if (record.id) {\n const response = await client.mutate({\n mutation: gql`\n mutation ($id: String!) {\n detachContact(id: $id) {\n id\n }\n }\n `,\n variables: { id: record.id }\n })\n\n this.grist.fetch()\n } else {\n record.contact = null\n this.grist.refresh()\n }\n }\n\n async attachSystemUser(record) {\n if (!record.user) {\n await client.mutate({\n mutation: gql`\n mutation ($employeeId: String!) {\n registerEmployeeAsSystemUser(employeeId: $employeeId)\n }\n `,\n variables: { employeeId: record.id }\n })\n }\n\n this.grist.fetch()\n }\n}\n"]}
1
+ {"version":3,"file":"employee-list-page.js","sourceRoot":"","sources":["../../../client/pages/employee/employee-list-page.ts"],"names":[],"mappings":"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","sourcesContent":["import '@operato/data-grist'\nimport '@operato/data-tree'\nimport '@operato/list-state/ox-empty-note.js'\nimport '@operato/list-state/ox-page-state.js'\nimport '@things-factory/contact/dist-client'\n\nimport gql from 'graphql-tag'\nimport { css, html } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements'\nimport { OxPrompt } from '@operato/popup'\nimport { Contact } from '@operato/contact/ox-contact.js'\nimport { DataGrist, FetchOption, GristRecord } from '@operato/data-grist'\nimport { client, QueryController } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { notify, openPopup } from '@operato/layout'\nimport { PageView } from '@operato/shell'\nimport { CommonHeaderStyles, CommonGristStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles'\nimport { isMobileDevice } from '@operato/utils'\nimport { p13n } from '@operato/p13n'\n\nimport { hasPrivilege } from '@things-factory/auth-base/dist-client'\nimport { issueDocument } from '@things-factory/pdf/dist-client'\n\nimport { Department } from '../../types/department'\nimport { EmployeeImporter } from './employee-importer'\n\n@customElement('employee-list-page')\nexport class EmployeeListPage extends p13n(localize(i18next)(ScopedElementsMixin(PageView))) {\n 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 --ox-pfp-size: 40px;\n --grid-record-emphasized-background-color: #8b0000;\n --grid-record-emphasized-color: #ff6b6b;\n }\n\n .header {\n grid-template-areas: 'filters';\n }\n\n /*\n * The rail is how you narrow the list to one department; the list is the content\n * (ADR-0060 decision 8, and the ruling of 2026-09-18 that folded the by-department screen\n * into this one). It folds away, because a screen looking at everyone does not need it.\n */\n [body] {\n flex: 1;\n display: flex;\n flex-direction: row;\n min-height: 0;\n }\n\n [rail] {\n display: flex;\n flex-direction: column;\n width: 240px;\n min-width: 240px;\n border-right: 1px solid var(--ui-line, var(--md-sys-color-outline-variant));\n overflow: auto;\n }\n\n [rail][folded] {\n display: none;\n }\n\n [rail-head] {\n display: flex;\n align-items: center;\n gap: var(--spacing-small, 4px);\n padding: var(--spacing-medium, 8px) var(--spacing-medium, 8px) 0;\n font: var(--label-font, inherit);\n color: var(--ui-muted, var(--md-sys-color-on-surface-variant));\n }\n\n /* The word keeps its line. Sharing the row with a filler let it shrink and break in half. */\n [rail-head] > span {\n flex: 0 0 auto;\n white-space: nowrap;\n }\n\n [rail-head] button,\n /*\n * Going back to everyone. Picking a department narrows the list, and without this there is no\n * way out of that except reloading the screen.\n */\n button[all-departments] {\n width: calc(100% - 16px);\n margin: 4px 8px;\n padding: 6px 10px;\n text-align: left;\n border: 1px solid transparent;\n border-radius: var(--md-sys-shape-corner-small, 6px);\n background: transparent;\n color: var(--ui-muted, var(--md-sys-color-on-surface-variant));\n font: inherit;\n cursor: pointer;\n }\n\n button[all-departments][selected] {\n background: var(--md-sys-color-secondary-container);\n color: var(--md-sys-color-on-secondary-container);\n }\n\n [rail-toggle] {\n display: flex;\n align-items: center;\n border: none;\n background: transparent;\n color: inherit;\n cursor: pointer;\n padding: 2px;\n }\n\n [rail-toggle] {\n align-self: flex-start;\n margin: var(--spacing-medium, 8px) 0 0 var(--spacing-small, 4px);\n }\n\n ox-tree {\n flex: 1;\n overflow: auto;\n }\n\n ox-grist {\n flex: 1;\n min-width: 0;\n }\n\n @media screen and (max-width: 780px) {\n [rail] {\n display: none;\n }\n }\n `\n ]\n\n static get scopedElements() {\n return { 'employee-importer': EmployeeImporter }\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 /** The department chosen on the rail, and whether the rail is showing. */\n @state() private selectedDepartment?: Department\n @state() private railFolded = false\n /** Whether this person issues employees' certificates. */\n @state() private issuesCertificates = false\n\n /**\n * The departments the rail draws (ADR-0190). departmentRoots answers with a list, and the tree draws from\n * the first root - a fragment spread straight onto the list is refused by the server.\n */\n private departmentsRead = new QueryController(\n this,\n gql`\n query {\n responses: departmentRoots {\n items {\n ...EmployeeDepartmentFragment\n children {\n ...EmployeeDepartmentFragment\n children {\n ...EmployeeDepartmentFragment\n children {\n ...EmployeeDepartmentFragment\n children {\n ...EmployeeDepartmentFragment\n }\n }\n }\n }\n }\n }\n }\n\n fragment EmployeeDepartmentFragment on Department {\n id\n controlNo\n name\n description\n active\n }\n `\n )\n\n /* Every root department, not just the first - the rail draws an array. */\n private get departments(): Department[] | undefined {\n return this.departmentsRead.data?.responses?.items\n }\n\n get context() {\n return {\n title: i18next.t('title.employee list'),\n search: {\n handler: (search: string) => {\n this.grist.searchText = search\n },\n value: this.grist?.searchText || ''\n },\n filter: {\n handler: () => {\n this.grist.toggleHeadroom()\n }\n },\n help: 'organization/employee',\n actions: [\n /* Certificates of the selected employee - for whoever issues them (`employee-certificate`, ADR-0176 decision 5). */\n ...(this.issuesCertificates\n ? [\n { icon: 'workspace_premium', title: i18next.t('button.issue-employment-certificate'), action: () => this.issueCertificate('organization.employment-certificate') },\n { icon: 'history_edu', title: i18next.t('button.issue-career-certificate'), action: () => this.issueCertificate('organization.career-certificate') }\n ]\n : []),\n { icon: 'save', title: i18next.t('button.save'), action: this.onUpdateEmployee.bind(this) },\n {\n icon: 'delete',\n title: i18next.t('button.delete'),\n action: this.onDeleteEmployee.bind(this),\n emphasis: { danger: true }\n }\n ],\n exportable: { name: i18next.t('title.employee list'), data: this.exportHandler.bind(this) },\n importable: { handler: this.importHandler.bind(this) }\n }\n }\n\n render() {\n const mode = this.mode || (isMobileDevice() ? 'CARD' : 'GRID')\n\n return html`\n <div body class=\"page-fill\">\n ${\n this.railFolded\n ? html`<button\n rail-toggle\n title=${i18next.t('title.department list')}\n @click=${() => (this.railFolded = false)}\n >\n <md-icon>account_tree</md-icon>\n </button>`\n : html`<aside rail>\n <div rail-head>\n <span>${i18next.t('title.department list')}</span>\n <div filler style=\"flex: 1\"></div>\n <button title=${i18next.t('label.fold')} @click=${() => (this.railFolded = true)}>\n <md-icon>chevron_left</md-icon>\n </button>\n </div>\n <ox-page-state\n .loading=${this.departmentsRead.loading}\n .error=${this.departmentsRead.error ?? null}\n @retry=${() => this.departmentsRead.refetch()}\n >\n ${\n this.departments?.length\n ? html`<button\n all-departments\n ?selected=${!this.selectedDepartment}\n @click=${() => this.onSelectDepartment(undefined)}\n >\n ${i18next.t('text.all departments')}\n </button>\n <ox-tree\n .data=${this.departments}\n .selected=${this.selectedDepartment}\n @select=${(e: CustomEvent) => this.onSelectDepartment(e.detail as Department)}\n id-property=\"controlNo\"\n label-property=\"name\"\n ></ox-tree>`\n : html`<ox-empty-note\n icon=\"account_tree\"\n title=${i18next.t('text.no departments yet')}\n description=${i18next.t('text.departments are made on the department screen')}\n ></ox-empty-note>`\n }\n </ox-page-state>\n </aside>`\n }\n\n <ox-grist\n .mode=${mode}\n .config=${this.gristConfig}\n .fetchHandler=${this.fetchHandler.bind(this)}\n .personalConfigProvider=${this.getPagePreferenceProvider('ox-grist')!}\n >\n <div slot=\"headroom\" class=\"header\">\n <div class=\"filters\">\n <ox-filters-form class=\"filter\" autofocus without-search></ox-filters-form>\n </div>\n </div>\n\n <ox-grist-personalizer slot=\"setting\"></ox-grist-personalizer>\n </ox-grist>\n </div>\n `\n }\n\n /**\n * 트리에서 고른 부서가 목록의 부서 조건이다 — 조건은 하나고, 그것을 고르는 자리도 하나다.\n */\n private onSelectDepartment(department?: Department) {\n this.selectedDepartment = department\n this.grist?.fetch()\n this.updateContext()\n }\n\n /** One certificate of the one employee selected. */\n private async issueCertificate(kind: string) {\n const selected = this.grist.selected\n if (selected.length !== 1 || !selected[0].id) {\n notify({ level: 'warn', message: i18next.t('text.select-one-employee') })\n return\n }\n await issueDocument({ kind, refId: selected[0].id })\n }\n\n async pageInitialized(lifecycle: any) {\n hasPrivilege({ category: 'employee-certificate', privilege: 'mutation', domainOwnerGranted: true }).then(may => {\n this.issuesCertificates = may\n this.updateContext()\n })\n this.gristConfig = {\n pagination: { pages: [50, 100, 200] },\n list: {\n thumbnail: 'profile',\n fields: ['controlNo', 'name'],\n details: ['email', 'department', 'hiredOn', 'updatedAt']\n },\n columns: [\n { type: 'gutter', gutterName: 'sequence', fixed: true },\n { type: 'gutter', gutterName: 'row-selector', multiple: true, fixed: true },\n {\n type: 'gutter',\n gutterName: 'button',\n header: i18next.t('field.register-account'),\n icon: record => (record.id && !record.user ? 'badge' : ''),\n iconOnly: false,\n title: record => (record.id && !record.user ? i18next.t('button.register-account') : ''),\n width: 80,\n handlers: {\n click: (columns, data, column, record, rowIndex) => {\n if (!record || !record.id || record.user) {\n return\n }\n\n this.attachSystemUser(record)\n }\n }\n },\n {\n type: 'image',\n name: 'profile',\n header: i18next.t('button.edit-contact'),\n width: 80,\n record: {\n align: 'center',\n renderer: function (value, column, record, rowIndex, field) {\n return html`<ox-pfp-view .profile=${record.profile} .name=${record.name || '+'}></ox-pfp-view>`\n }\n },\n handlers: {\n click: async (columns, data, column, record, rowIndex) => {\n if (record && record.contact) {\n this.openContactPopup(record)\n } else {\n this.openContactSelector(record)\n }\n }\n }\n },\n {\n type: 'string',\n name: 'controlNo',\n fixed: true,\n header: i18next.t('field.control-no'),\n record: { editable: true, mandatory: true },\n filter: 'search',\n sortable: true,\n width: 105\n },\n {\n type: 'string',\n name: 'name',\n fixed: true,\n header: i18next.t('field.name'),\n record: { editable: true, mandatory: true },\n filter: 'search',\n sortable: true,\n width: 100\n },\n {\n type: 'string',\n name: 'alias',\n header: i18next.t('label.alias'),\n record: { editable: true },\n filter: 'search',\n sortable: false,\n width: 110\n },\n {\n type: 'resource-object',\n name: 'user',\n header: i18next.t('field.system-user'),\n record: {\n editable: true,\n options: {\n title: i18next.t('title.lookup system-user'),\n queryName: 'users',\n basicArgs: { filters: [{ name: 'userType', operator: 'eq', value: 'user' }] },\n descriptionField: 'email',\n columns: [\n { name: 'id', hidden: true },\n { name: 'name', header: i18next.t('field.name'), filter: 'search' },\n { name: 'email', header: i18next.t('field.email'), filter: 'search' }\n ],\n list: { fields: ['name', 'email'] }\n }\n },\n sortable: false,\n filter: 'search',\n width: 100\n },\n {\n type: 'code',\n name: 'type',\n header: i18next.t('field.type', { defaultValue: 'type' }),\n width: 115,\n sortable: true,\n filter: true,\n record: { editable: true, codeName: 'EMPLOYEE_TYPE', selectDispOpt: 'name' }\n },\n {\n type: 'department-object',\n name: 'department',\n header: i18next.t('field.department'),\n record: { editable: true },\n sortable: false,\n /* The rail narrows by department; a second department field here would be the same condition twice. */\n filter: false,\n width: 130\n },\n {\n type: 'resource-object',\n name: 'supervisor',\n header: i18next.t('field.supervisor'),\n record: {\n editable: true,\n options: {\n title: i18next.t('title.employee list'),\n queryName: 'employees',\n pagination: { pages: [50, 100, 200] },\n basicArgs: { filters: [{ name: 'active', operator: 'eq', value: true }] },\n list: { fields: ['controlNo', 'name', 'alias', 'hiredOn'] },\n columns: [\n { name: 'id', hidden: true },\n {\n name: 'controlNo',\n width: 120,\n header: { renderer: () => i18next.t('field.control-no') },\n filter: 'search',\n sortable: true\n },\n {\n name: 'name',\n width: 120,\n header: { renderer: () => i18next.t('field.name') },\n filter: 'search',\n sortable: true\n },\n {\n name: 'alias',\n width: 150,\n header: { renderer: () => i18next.t('label.alias') },\n filter: 'search',\n sortable: true\n },\n {\n type: 'code',\n name: 'type',\n width: 110,\n header: { renderer: () => i18next.t('label.type', { defaultValue: 'type' }) },\n record: { editable: false, codeName: 'EMPLOYEE_TYPE', selectDispOpt: 'name' }\n },\n {\n type: 'code',\n name: 'jobPosition',\n width: 110,\n header: { renderer: () => i18next.t('label.job-position') },\n record: { editable: false, codeName: 'JOB_POSITION', selectDispOpt: 'name' }\n },\n {\n type: 'code',\n name: 'jobResponsibility',\n width: 200,\n header: { renderer: () => i18next.t('label.job-responsibility') },\n record: { editable: false, codeName: 'JOB_RESPONSIBILITY', selectDispOpt: 'name' }\n },\n { type: 'date', name: 'hiredOn', header: { renderer: () => i18next.t('field.hired-on') }, width: 120 }\n ],\n valueField: 'id',\n nameField: 'name',\n descriptionField: 'controlNo'\n }\n },\n sortable: false,\n width: 120\n },\n {\n type: 'string',\n name: 'email',\n header: i18next.t('field.email'),\n width: 200,\n record: {\n editable: false,\n renderer: function (value, column, record, rowIndex, field) {\n return record.contact ? record.contact.email : ''\n }\n },\n sortable: false\n },\n {\n type: 'string',\n name: 'phone',\n header: i18next.t('field.phone'),\n width: 130,\n record: {\n editable: false,\n renderer: function (value, column, record, rowIndex, field) {\n return record.contact ? record.contact.phone : ''\n }\n },\n sortable: false\n },\n {\n type: 'code',\n name: 'jobResponsibility',\n header: i18next.t('label.job-responsibility'),\n width: 175,\n record: { editable: true, codeName: 'JOB_RESPONSIBILITY', selectDispOpt: 'name' },\n filter: true\n },\n {\n type: 'code',\n name: 'jobPosition',\n header: i18next.t('label.job-position'),\n width: 100,\n record: { editable: true, codeName: 'JOB_POSITION', selectDispOpt: 'name' },\n filter: true\n },\n {\n type: 'date',\n name: 'hiredOn',\n header: i18next.t('field.hired-on'),\n width: 120,\n record: { editable: true },\n sortable: true\n },\n {\n type: 'date',\n name: 'retiredOn',\n header: i18next.t('label.retired-at'),\n width: 120,\n record: { editable: true }\n },\n {\n type: 'checkbox',\n name: 'active',\n label: true,\n header: i18next.t('field.active'),\n width: 70,\n record: { align: 'center', editable: true },\n filter: true,\n sortable: false\n },\n {\n type: 'string',\n name: 'note',\n header: i18next.t('field.note'),\n width: 200,\n record: { editable: true },\n filter: 'search'\n },\n { type: 'resource-object', name: 'updater', header: i18next.t('field.updater'), width: 90, sortable: false },\n { type: 'datetime', name: 'updatedAt', header: i18next.t('field.updated_at'), width: 180, sortable: true },\n { type: 'resource-object', name: 'contact', hidden: true }\n ],\n rows: { selectable: { multiple: true } },\n sorters: [{ name: 'controlNo' }]\n }\n }\n\n async pageUpdated(changes: any, lifecycle: any) {\n if (this.active) {\n // do something here when this page just became as active\n }\n }\n\n async fetchHandler({ page = 1, limit = 100, sortings = [], filters = [] }: FetchOption) {\n /* The rail's selection is the department condition; nothing else sets one. */\n if (this.selectedDepartment) {\n filters = [...filters, { name: 'departmentId', operator: 'eq', value: this.selectedDepartment.id }]\n }\n\n const response = await client.query({\n query: gql`\n query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {\n responses: employees(filters: $filters, pagination: $pagination, sortings: $sortings) {\n items {\n id\n controlNo\n name\n alias\n type\n jobResponsibility\n jobPosition\n active\n email\n phone\n user {\n id\n name\n }\n department {\n id\n __typename\n controlNo\n name\n description\n }\n supervisor {\n id\n name\n controlNo\n }\n note\n hiredOn\n retiredOn\n contact {\n id\n email\n phone\n address\n }\n profile {\n left\n top\n zoom\n picture\n }\n updater {\n id\n name\n }\n updatedAt\n }\n total\n }\n }\n `,\n variables: { filters, pagination: { page, limit }, sortings }\n })\n\n const records = response.data.responses.items\n\n return { total: response.data.responses.total || 0, records }\n }\n\n async onDeleteEmployee() {\n if (await OxPrompt.confirmDelete({ count: this.grist?.selected?.length })) {\n const ids = this.grist.selected.map(record => record.id)\n if (ids && ids.length > 0) {\n const response = await client.mutate({\n mutation: gql`\n mutation ($ids: [String!]!) {\n deleteEmployees(ids: $ids)\n }\n `,\n variables: { ids }\n })\n\n if (!response.errors) {\n this.grist.fetch()\n notify({ message: i18next.t('text.deleted') })\n }\n }\n }\n }\n\n async onUpdateEmployee() {\n let patches = this.grist.dirtyRecords\n if (patches && patches.length) {\n patches = patches.map(patch => {\n let patchField: any = patch.id ? { id: patch.id } : {}\n const dirtyFields = patch.__dirtyfields__\n for (let key in dirtyFields) {\n patchField[key] = dirtyFields[key].after\n }\n patchField.cuFlag = patch.__dirty__\n\n return patchField\n })\n\n const response = await client.mutate({\n mutation: gql`\n mutation ($patches: [EmployeePatch!]!) {\n updateMultipleEmployee(patches: $patches) {\n name\n }\n }\n `,\n variables: { patches }\n })\n\n if (!response.errors) {\n this.grist.fetch()\n }\n }\n }\n\n async exportHandler() {\n const exportTargets = this.grist.selected.length ? this.grist.selected : this.grist.dirtyData.records\n const targetFieldSet = new Set([\n 'id',\n 'controlNo',\n 'name',\n 'alias',\n 'type',\n 'hiredOn',\n 'retiredOn',\n 'active',\n 'note'\n ])\n\n return exportTargets.map(employee => {\n let tempObj = {}\n for (const field of targetFieldSet) {\n tempObj[field] = employee[field]\n }\n\n return tempObj\n })\n }\n\n async importHandler(records) {\n const popup = openPopup(\n html`\n <employee-importer\n .employees=${records}\n @imported=${() => {\n history.back()\n this.grist.fetch()\n }}\n ></employee-importer>\n `,\n { backdrop: true, size: 'large', title: i18next.t('title.import employee') }\n )\n\n popup.onclosed = () => {\n this.grist.fetch()\n }\n }\n\n async openContactPopup(record: GristRecord) {\n if (!record.contact?.id) {\n return\n }\n\n const popup = openPopup(\n html`\n <contact-popup\n .contactId=${record.contact.id}\n @change=${() => {\n this.grist.fetch()\n }}\n @detach=${() => {\n this.detachContact(record)\n }}\n detachable\n ></contact-popup>\n `,\n { backdrop: true, size: 'large', title: i18next.t('title.contact') }\n )\n }\n\n async openContactSelector(record: GristRecord) {\n const popup = openPopup(\n html`\n <contact-selector .confirmCallback=${selected => this.attachContact(record, selected)}></contact-selector>\n `,\n { backdrop: true, size: 'large', title: i18next.t('title.contact') }\n )\n }\n\n async attachContact(record: GristRecord, contact: Contact) {\n if (record.id) {\n const response = await client.mutate({\n mutation: gql`\n mutation ($id: String!, $contactId: String!) {\n attachContact(id: $id, contactId: $contactId) {\n id\n }\n }\n `,\n variables: { id: record.id, contactId: contact.id }\n })\n\n this.grist.fetch()\n } else if (contact?.id) {\n this.grist.addRecord({\n name: contact.name,\n contact: {\n id: contact.id,\n name: contact.name,\n email: (contact as any).email,\n phone: (contact as any).phone,\n address: (contact as any).address\n }\n })\n this.grist.refresh()\n await this.grist.requestUpdate()\n\n this.grist.checkDirties()\n }\n }\n\n async detachContact(record) {\n if (record.id) {\n const response = await client.mutate({\n mutation: gql`\n mutation ($id: String!) {\n detachContact(id: $id) {\n id\n }\n }\n `,\n variables: { id: record.id }\n })\n\n this.grist.fetch()\n } else {\n record.contact = null\n this.grist.refresh()\n }\n }\n\n async attachSystemUser(record) {\n if (!record.user) {\n await client.mutate({\n mutation: gql`\n mutation ($employeeId: String!) {\n registerEmployeeAsSystemUser(employeeId: $employeeId)\n }\n `,\n variables: { employeeId: record.id }\n })\n }\n\n this.grist.fetch()\n }\n}\n"]}
@@ -15,17 +15,19 @@ declare const MyEmployeeProfilePage_base: (new (...args: any[]) => import("lit")
15
15
  */
16
16
  export declare class MyEmployeeProfilePage extends MyEmployeeProfilePage_base {
17
17
  static styles: import("lit").CSSResult[];
18
- form: ProfileForm;
18
+ private profile;
19
+ private saving;
20
+ /** What is written over the profile read; a save clears what it sent. */
21
+ private typed;
22
+ /** The profile as last read or saved. */
23
+ private get held();
24
+ get form(): ProfileForm;
19
25
  /** Who the profile is about - the employee record's basics. */
20
- me: any;
26
+ private get me();
21
27
  /** Whether the account is linked to an employee record - unknown until read. */
22
- linked: boolean | null;
23
- loading: boolean;
24
- error: unknown;
25
- busy: boolean;
26
- updatedAt: string | null;
27
- /** The form as last read or saved - what is written differs from it until saved. */
28
- private saved;
28
+ private get linked();
29
+ private get updatedAt();
30
+ private get busy();
29
31
  private get dirty();
30
32
  get context(): {
31
33
  title: string;
@@ -39,9 +41,6 @@ export declare class MyEmployeeProfilePage extends MyEmployeeProfilePage_base {
39
41
  action: () => Promise<boolean>;
40
42
  }[];
41
43
  };
42
- pageUpdated(changes: any): Promise<void>;
43
- private load;
44
- private hold;
45
44
  private save;
46
45
  /** The document as sales will hand it in - what is written is saved first, so the preview shows it. */
47
46
  private preview;