@things-factory/organization 10.0.18 → 10.1.0

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 (78) hide show
  1. package/dist-client/component/approval-line-brief.js +93 -36
  2. package/dist-client/component/approval-line-brief.js.map +1 -1
  3. package/dist-client/component/approval-line-items-editor-popup.d.ts +2 -0
  4. package/dist-client/component/approval-line-items-editor-popup.js +27 -9
  5. package/dist-client/component/approval-line-items-editor-popup.js.map +1 -1
  6. package/dist-client/component/approval-line-items-editor.d.ts +7 -1
  7. package/dist-client/component/approval-line-items-editor.js +67 -3
  8. package/dist-client/component/approval-line-items-editor.js.map +1 -1
  9. package/dist-client/component/approval-line-selector.d.ts +2 -0
  10. package/dist-client/component/approval-line-selector.js +40 -9
  11. package/dist-client/component/approval-line-selector.js.map +1 -1
  12. package/dist-client/component/approval-line-view.d.ts +15 -0
  13. package/dist-client/component/approval-line-view.js +177 -41
  14. package/dist-client/component/approval-line-view.js.map +1 -1
  15. package/dist-client/component/assignees-editor-popup.d.ts +2 -0
  16. package/dist-client/component/assignees-editor-popup.js +27 -8
  17. package/dist-client/component/assignees-editor-popup.js.map +1 -1
  18. package/dist-client/component/department-selector.d.ts +2 -0
  19. package/dist-client/component/department-selector.js +27 -8
  20. package/dist-client/component/department-selector.js.map +1 -1
  21. package/dist-client/component/recipients-editor-popup.d.ts +2 -0
  22. package/dist-client/component/recipients-editor-popup.js +27 -8
  23. package/dist-client/component/recipients-editor-popup.js.map +1 -1
  24. package/dist-client/filters-form/ox-filter-department-object.js +11 -1
  25. package/dist-client/filters-form/ox-filter-department-object.js.map +1 -1
  26. package/dist-client/pages/approval-line/approval-line-list-page.d.ts +121 -0
  27. package/dist-client/pages/approval-line/approval-line-list-page.js +583 -0
  28. package/dist-client/pages/approval-line/approval-line-list-page.js.map +1 -0
  29. package/dist-client/pages/approval-line/common-approval-line-templates-page.d.ts +0 -2
  30. package/dist-client/pages/approval-line/common-approval-line-templates-page.js +27 -11
  31. package/dist-client/pages/approval-line/common-approval-line-templates-page.js.map +1 -1
  32. package/dist-client/pages/approval-line/my-approval-line-templates-page.d.ts +0 -2
  33. package/dist-client/pages/approval-line/my-approval-line-templates-page.js +33 -9
  34. package/dist-client/pages/approval-line/my-approval-line-templates-page.js.map +1 -1
  35. package/dist-client/pages/department/department-list-page.d.ts +0 -2
  36. package/dist-client/pages/department/department-list-page.js +2 -6
  37. package/dist-client/pages/department/department-list-page.js.map +1 -1
  38. package/dist-client/pages/department/department-tree-page.d.ts +0 -10
  39. package/dist-client/pages/department/department-tree-page.js +35 -16
  40. package/dist-client/pages/department/department-tree-page.js.map +1 -1
  41. package/dist-client/pages/employee/employee-list-page.d.ts +0 -2
  42. package/dist-client/pages/employee/employee-list-page.js +2 -6
  43. package/dist-client/pages/employee/employee-list-page.js.map +1 -1
  44. package/dist-client/route.d.ts +1 -1
  45. package/dist-client/route.js +9 -0
  46. package/dist-client/route.js.map +1 -1
  47. package/dist-client/tsconfig.tsbuildinfo +1 -1
  48. package/dist-client/types/approval-line.d.ts +64 -0
  49. package/dist-client/types/approval-line.js +67 -0
  50. package/dist-client/types/approval-line.js.map +1 -1
  51. package/dist-server/service/approval-line/approval-line-item.d.ts +40 -0
  52. package/dist-server/service/approval-line/approval-line-item.js +42 -2
  53. package/dist-server/service/approval-line/approval-line-item.js.map +1 -1
  54. package/dist-server/service/approval-line/approval-line-mutation.js +24 -33
  55. package/dist-server/service/approval-line/approval-line-mutation.js.map +1 -1
  56. package/dist-server/service/approval-line/approval-line-query.js +36 -21
  57. package/dist-server/service/approval-line/approval-line-query.js.map +1 -1
  58. package/dist-server/service/employee/employee-query.d.ts +25 -0
  59. package/dist-server/service/employee/employee-query.js +41 -0
  60. package/dist-server/service/employee/employee-query.js.map +1 -1
  61. package/dist-server/service/employee/index.d.ts +1 -0
  62. package/dist-server/service/employee/index.js +3 -0
  63. package/dist-server/service/employee/index.js.map +1 -1
  64. package/dist-server/service/employee/my-employee-refusal.d.ts +22 -0
  65. package/dist-server/service/employee/my-employee-refusal.js +56 -0
  66. package/dist-server/service/employee/my-employee-refusal.js.map +1 -0
  67. package/dist-server/service/employee/my-employee.d.ts +22 -0
  68. package/dist-server/service/employee/my-employee.js +43 -0
  69. package/dist-server/service/employee/my-employee.js.map +1 -0
  70. package/dist-server/tsconfig.tsbuildinfo +1 -1
  71. package/package.json +6 -6
  72. package/spec/unit/my-employee.spec.ts +102 -0
  73. package/things-factory.config.js +1 -0
  74. package/translations/en.json +44 -17
  75. package/translations/ja.json +44 -17
  76. package/translations/ko.json +46 -19
  77. package/translations/ms.json +43 -16
  78. package/translations/zh.json +43 -16
@@ -1,5 +1,7 @@
1
1
  import { __decorate, __metadata } from "tslib";
2
2
  import '@material/web/icon/icon.js';
3
+ import '@material/web/button/text-button.js';
4
+ import '@material/web/button/filled-button.js';
3
5
  import '@operato/data-tree';
4
6
  import gql from 'graphql-tag';
5
7
  import { css, html, LitElement } from 'lit';
@@ -7,7 +9,7 @@ import { customElement, property, state } from 'lit/decorators.js';
7
9
  import { client } from '@operato/graphql';
8
10
  import { i18next } from '@operato/i18n';
9
11
  import { closePopup } from '@operato/popup';
10
- import { CommonHeaderStyles } from '@operato/styles';
12
+ import { CommonHeaderStyles, CommonPopupStyles } from '@operato/styles';
11
13
  import { Department } from '../types/department';
12
14
  const departmentFragment = gql `
13
15
  fragment SubDepartment on Department {
@@ -36,7 +38,25 @@ const departmentFragment = gql `
36
38
  let DepartmentSelector = class DepartmentSelector extends LitElement {
37
39
  static { this.styles = [
38
40
  CommonHeaderStyles,
41
+ CommonPopupStyles,
39
42
  css `
43
+ /*
44
+ * 단추 줄은 **제품의 팝업 규약**을 쓴다(CommonPopupStyles 의 .buttons).
45
+ *
46
+ * 전에는 손으로 만든 .footer 였고 organization 의 팝업 다섯이 그것을 복사해 갖고 있었다.
47
+ * 규약이 주는 것을 다 놓쳤다 — 팝업 안 단추의 알약 모서리(담는 카드가 둥그니 그 안도
48
+ * 둥글다), 마우스와 손가락을 가르는 갈래(손가락에서는 카드 아래 폭을 채우는 액션바가 된다),
49
+ * 단추 높이 통일.
50
+ *
51
+ * 단추는 Material 것으로 쓴다. 규약의 마우스 갈래는 **md-*-button 의 토큰으로만** 모양을
52
+ * 말한다 — 평범한 button 을 두면 모서리가 0 으로 남는다(실측: 알약이어야 할 자리에 0px).
53
+ * 제품의 다른 팝업도 같은 관용구다(operato-plant 의 maintenance-dialog).
54
+ *
55
+ * 「비우기」는 왼쪽에 둔다 — 되돌리는 것이라 저지르는 것들과 같은 자리에 두지 않는다.
56
+ */
57
+ .buttons .left {
58
+ margin-right: auto;
59
+ }
40
60
  :host {
41
61
  display: flex;
42
62
  flex-direction: column;
@@ -66,13 +86,12 @@ let DepartmentSelector = class DepartmentSelector extends LitElement {
66
86
  description-property="description"
67
87
  ></ox-tree-vertical>
68
88
 
69
- <div class="footer" style="margin-left:unset;">
70
- <button @click=${this.onEmpty.bind(this)}>
71
- <md-icon>check_box_outline_blank</md-icon>${i18next.t('button.empty')}
72
- </button>
73
- <div filler></div>
74
- <button @click=${this.onCancel.bind(this)}><md-icon>cancel</md-icon>${i18next.t('button.cancel')}</button>
75
- <button @click=${this.onConfirm.bind(this)} done><md-icon>done</md-icon>${i18next.t('button.confirm')}</button>
89
+ <div class="buttons">
90
+ <md-text-button class="left" @click=${this.onEmpty.bind(this)}>
91
+ ${i18next.t('button.empty')}
92
+ </md-text-button>
93
+ <md-text-button @click=${this.onCancel.bind(this)}>${i18next.t('button.cancel')}</md-text-button>
94
+ <md-filled-button @click=${this.onConfirm.bind(this)}>${i18next.t('button.confirm')}</md-filled-button>
76
95
  </div>
77
96
  `;
78
97
  }
@@ -1 +1 @@
1
- {"version":3,"file":"department-selector.js","sourceRoot":"","sources":["../../client/component/department-selector.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@operato/data-tree'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\n\nimport { client } from '@operato/graphql'\nimport { i18next } from '@operato/i18n'\nimport { closePopup } from '@operato/popup'\nimport { CommonHeaderStyles } from '@operato/styles'\n\nimport { Department } from '../types/department'\n\nconst departmentFragment = gql`\n fragment SubDepartment on Department {\n id\n controlNo\n name\n description\n\n manager {\n id\n name\n controlNo\n photo\n email\n }\n active\n picture\n\n updater {\n id\n name\n }\n updatedAt\n }\n`\n\n@customElement('department-selector')\nexport class DepartmentSelector extends LitElement {\n static styles = [\n CommonHeaderStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n\n background-color: var(--md-sys-color-surface);\n\n width: var(--overlay-center-normal-width, 50%);\n height: var(--overlay-center-normal-height, 50%);\n\n overflow: auto;\n }\n\n ox-tree-vertical {\n flex: 1;\n }\n `\n ]\n\n @property({ type: Object }) confirmCallback?: (selected?: any) => void\n @property({ type: Object }) value?: Department\n\n @state() root?: Department\n\n render() {\n return html`\n <ox-tree-vertical\n .data=${this.root}\n .selected=${this.value}\n @select=${e => this.onSelect(e, false)}\n @select-confirm=${e => this.onSelect(e, true)}\n id-property=\"controlNo\"\n label-property=\"name\"\n description-property=\"description\"\n ></ox-tree-vertical>\n\n <div class=\"footer\" style=\"margin-left:unset;\">\n <button @click=${this.onEmpty.bind(this)}>\n <md-icon>check_box_outline_blank</md-icon>${i18next.t('button.empty')}\n </button>\n <div filler></div>\n <button @click=${this.onCancel.bind(this)}><md-icon>cancel</md-icon>${i18next.t('button.cancel')}</button>\n <button @click=${this.onConfirm.bind(this)} done><md-icon>done</md-icon>${i18next.t('button.confirm')}</button>\n </div>\n `\n }\n\n onSelect(e: CustomEvent, confirm?: boolean) {\n this.value = e.detail as Department\n\n if (confirm) {\n this.onConfirm()\n }\n }\n\n onEmpty() {\n this.confirmCallback && this.confirmCallback(null)\n closePopup(this)\n }\n\n onCancel() {\n closePopup(this)\n }\n\n onConfirm() {\n this.confirmCallback && this.confirmCallback(this.value)\n closePopup(this)\n }\n\n async firstUpdated() {\n const response = await client.query({\n query: gql`\n query {\n responses: departmentRoots {\n total\n items {\n ...SubDepartment\n children {\n ...SubDepartment\n children {\n ...SubDepartment\n children {\n ...SubDepartment\n children {\n ...SubDepartment\n children {\n ...SubDepartment\n children {\n ...SubDepartment\n }\n }\n }\n }\n }\n }\n }\n }\n }\n\n ${departmentFragment}\n `\n })\n\n const { items: records, total } = response.data.responses\n\n this.root = records[0]\n }\n}\n"]}
1
+ {"version":3,"file":"department-selector.js","sourceRoot":"","sources":["../../client/component/department-selector.ts"],"names":[],"mappings":";AAAA,OAAO,4BAA4B,CAAA;AACnC,OAAO,qCAAqC,CAAA;AAC5C,OAAO,uCAAuC,CAAA;AAC9C,OAAO,oBAAoB,CAAA;AAE3B,OAAO,GAAG,MAAM,aAAa,CAAA;AAC7B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAS,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAEzE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAC3C,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAEvE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAEhD,MAAM,kBAAkB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;CAuB7B,CAAA;AAGM,IAAM,kBAAkB,GAAxB,MAAM,kBAAmB,SAAQ,UAAU;aACzC,WAAM,GAAG;QACd,kBAAkB;QAClB,iBAAiB;QACjB,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAiCF;KACF,AArCY,CAqCZ;IAOD,MAAM;QACJ,OAAO,IAAI,CAAA;;gBAEC,IAAI,CAAC,IAAI;oBACL,IAAI,CAAC,KAAK;kBACZ,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC;0BACpB,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC;;;;;;;8CAOP,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;YACzD,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC;;iCAEJ,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;mCACpD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC;;KAEtF,CAAA;IACH,CAAC;IAED,QAAQ,CAAC,CAAc,EAAE,OAAiB;QACxC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,MAAoB,CAAA;QAEnC,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC,SAAS,EAAE,CAAA;QAClB,CAAC;IACH,CAAC;IAED,OAAO;QACL,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA;QAClD,UAAU,CAAC,IAAI,CAAC,CAAA;IAClB,CAAC;IAED,QAAQ;QACN,UAAU,CAAC,IAAI,CAAC,CAAA;IAClB,CAAC;IAED,SAAS;QACP,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACxD,UAAU,CAAC,IAAI,CAAC,CAAA;IAClB,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;YAClC,KAAK,EAAE,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA4BN,kBAAkB;OACrB;SACF,CAAC,CAAA;QAEF,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAA;QAEzD,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;IACxB,CAAC;;AAtF2B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;2DAA2C;AAC1C;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;8BAAS,UAAU;iDAAA;AAErC;IAAR,KAAK,EAAE;8BAAQ,UAAU;gDAAA;AA3Cf,kBAAkB;IAD9B,aAAa,CAAC,qBAAqB,CAAC;GACxB,kBAAkB,CA+H9B","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@material/web/button/text-button.js'\nimport '@material/web/button/filled-button.js'\nimport '@operato/data-tree'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\n\nimport { client } from '@operato/graphql'\nimport { i18next } from '@operato/i18n'\nimport { closePopup } from '@operato/popup'\nimport { CommonHeaderStyles, CommonPopupStyles } from '@operato/styles'\n\nimport { Department } from '../types/department'\n\nconst departmentFragment = gql`\n fragment SubDepartment on Department {\n id\n controlNo\n name\n description\n\n manager {\n id\n name\n controlNo\n photo\n email\n }\n active\n picture\n\n updater {\n id\n name\n }\n updatedAt\n }\n`\n\n@customElement('department-selector')\nexport class DepartmentSelector extends LitElement {\n static styles = [\n CommonHeaderStyles,\n CommonPopupStyles,\n css`\n /*\n * 단추 줄은 **제품의 팝업 규약**을 쓴다(CommonPopupStyles 의 .buttons).\n *\n * 전에는 손으로 만든 .footer 였고 organization 의 팝업 다섯이 그것을 복사해 갖고 있었다.\n * 규약이 주는 것을 다 놓쳤다 — 팝업 안 단추의 알약 모서리(담는 카드가 둥그니 그 안도\n * 둥글다), 마우스와 손가락을 가르는 갈래(손가락에서는 카드 아래 폭을 채우는 액션바가 된다),\n * 단추 높이 통일.\n *\n * 단추는 Material 것으로 쓴다. 규약의 마우스 갈래는 **md-*-button 의 토큰으로만** 모양을\n * 말한다 — 평범한 button 을 두면 모서리가 0 으로 남는다(실측: 알약이어야 할 자리에 0px).\n * 제품의 다른 팝업도 같은 관용구다(operato-plant 의 maintenance-dialog).\n *\n * 「비우기」는 왼쪽에 둔다 — 되돌리는 것이라 저지르는 것들과 같은 자리에 두지 않는다.\n */\n .buttons .left {\n margin-right: auto;\n }\n :host {\n display: flex;\n flex-direction: column;\n\n background-color: var(--md-sys-color-surface);\n\n width: var(--overlay-center-normal-width, 50%);\n height: var(--overlay-center-normal-height, 50%);\n\n overflow: auto;\n }\n\n ox-tree-vertical {\n flex: 1;\n }\n `\n ]\n\n @property({ type: Object }) confirmCallback?: (selected?: any) => void\n @property({ type: Object }) value?: Department\n\n @state() root?: Department\n\n render() {\n return html`\n <ox-tree-vertical\n .data=${this.root}\n .selected=${this.value}\n @select=${e => this.onSelect(e, false)}\n @select-confirm=${e => this.onSelect(e, true)}\n id-property=\"controlNo\"\n label-property=\"name\"\n description-property=\"description\"\n ></ox-tree-vertical>\n\n <div class=\"buttons\">\n <md-text-button class=\"left\" @click=${this.onEmpty.bind(this)}>\n ${i18next.t('button.empty')}\n </md-text-button>\n <md-text-button @click=${this.onCancel.bind(this)}>${i18next.t('button.cancel')}</md-text-button>\n <md-filled-button @click=${this.onConfirm.bind(this)}>${i18next.t('button.confirm')}</md-filled-button>\n </div>\n `\n }\n\n onSelect(e: CustomEvent, confirm?: boolean) {\n this.value = e.detail as Department\n\n if (confirm) {\n this.onConfirm()\n }\n }\n\n onEmpty() {\n this.confirmCallback && this.confirmCallback(null)\n closePopup(this)\n }\n\n onCancel() {\n closePopup(this)\n }\n\n onConfirm() {\n this.confirmCallback && this.confirmCallback(this.value)\n closePopup(this)\n }\n\n async firstUpdated() {\n const response = await client.query({\n query: gql`\n query {\n responses: departmentRoots {\n total\n items {\n ...SubDepartment\n children {\n ...SubDepartment\n children {\n ...SubDepartment\n children {\n ...SubDepartment\n children {\n ...SubDepartment\n children {\n ...SubDepartment\n children {\n ...SubDepartment\n }\n }\n }\n }\n }\n }\n }\n }\n }\n\n ${departmentFragment}\n `\n })\n\n const { items: records, total } = response.data.responses\n\n this.root = records[0]\n }\n}\n"]}
@@ -1,4 +1,6 @@
1
1
  import '@material/web/icon/icon.js';
2
+ import '@material/web/button/text-button.js';
3
+ import '@material/web/button/filled-button.js';
2
4
  import { LitElement } from 'lit';
3
5
  import { RecipientsEditor } from './recipients-editor';
4
6
  import { AssigneeItem } from '../types/org-member';
@@ -1,9 +1,11 @@
1
1
  import { __decorate, __metadata } from "tslib";
2
2
  import '@material/web/icon/icon.js';
3
+ import '@material/web/button/text-button.js';
4
+ import '@material/web/button/filled-button.js';
3
5
  import { css, html, LitElement } from 'lit';
4
6
  import { customElement, property, query } from 'lit/decorators.js';
5
7
  import { i18next, localize } from '@operato/i18n';
6
- import { CommonHeaderStyles } from '@operato/styles';
8
+ import { CommonHeaderStyles, CommonPopupStyles } from '@operato/styles';
7
9
  import { closePopup } from '@operato/popup';
8
10
  import { RecipientsEditor } from './recipients-editor';
9
11
  /**
@@ -17,7 +19,25 @@ let RecipientsEditorPopup = class RecipientsEditorPopup extends localize(i18next
17
19
  }
18
20
  static { this.styles = [
19
21
  CommonHeaderStyles,
22
+ CommonPopupStyles,
20
23
  css `
24
+ /*
25
+ * 단추 줄은 **제품의 팝업 규약**을 쓴다(CommonPopupStyles 의 .buttons).
26
+ *
27
+ * 전에는 손으로 만든 .footer 였고 organization 의 팝업 다섯이 그것을 복사해 갖고 있었다.
28
+ * 규약이 주는 것을 다 놓쳤다 — 팝업 안 단추의 알약 모서리(담는 카드가 둥그니 그 안도
29
+ * 둥글다), 마우스와 손가락을 가르는 갈래(손가락에서는 카드 아래 폭을 채우는 액션바가 된다),
30
+ * 단추 높이 통일.
31
+ *
32
+ * 단추는 Material 것으로 쓴다. 규약의 마우스 갈래는 **md-*-button 의 토큰으로만** 모양을
33
+ * 말한다 — 평범한 button 을 두면 모서리가 0 으로 남는다(실측: 알약이어야 할 자리에 0px).
34
+ * 제품의 다른 팝업도 같은 관용구다(operato-plant 의 maintenance-dialog).
35
+ *
36
+ * 「비우기」는 왼쪽에 둔다 — 되돌리는 것이라 저지르는 것들과 같은 자리에 두지 않는다.
37
+ */
38
+ .buttons .left {
39
+ margin-right: auto;
40
+ }
21
41
  :host {
22
42
  display: flex;
23
43
  flex-direction: column;
@@ -39,13 +59,12 @@ let RecipientsEditorPopup = class RecipientsEditorPopup extends localize(i18next
39
59
  }}
40
60
  ></recipients-editor>
41
61
 
42
- <div class="footer">
43
- <button @click=${this.onEmpty.bind(this)}>
44
- <md-icon>check_box_outline_blank</md-icon>${i18next.t('button.empty')}
45
- </button>
46
- <div filler></div>
47
- <button @click=${this.onCancel.bind(this)}><md-icon>cancel</md-icon>${i18next.t('button.cancel')}</button>
48
- <button @click=${this.onConfirm.bind(this)} done><md-icon>done</md-icon>${i18next.t('button.confirm')}</button>
62
+ <div class="buttons">
63
+ <md-text-button class="left" @click=${this.onEmpty.bind(this)}>
64
+ ${i18next.t('button.empty')}
65
+ </md-text-button>
66
+ <md-text-button @click=${this.onCancel.bind(this)}>${i18next.t('button.cancel')}</md-text-button>
67
+ <md-filled-button @click=${this.onConfirm.bind(this)}>${i18next.t('button.confirm')}</md-filled-button>
49
68
  </div>
50
69
  `;
51
70
  }
@@ -1 +1 @@
1
- {"version":3,"file":"recipients-editor-popup.js","sourceRoot":"","sources":["../../client/component/recipients-editor-popup.ts"],"names":[],"mappings":";AAAA,OAAO,4BAA4B,CAAA;AACnC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAS,MAAM,mBAAmB,CAAA;AAEzE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAE3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAGtD;;GAEG;AAEI,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,QAAQ,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC;IAAjE;;QAsBL,wEAAwE;QAChE,iBAAY,GAAoB,IAAI,CAAC,KAAK,CAAA;IAwCpD,CAAC;aA9DQ,WAAM,GAAG;QACd,kBAAkB;QAClB,GAAG,CAAA;;;;;;;;;;;KAWF;KACF,AAdY,CAcZ;IAUD,MAAM;QACJ,OAAO,IAAI,CAAA;;iBAEE,IAAI,CAAC,KAAK;kBACT,CAAC,CAAc,EAAE,EAAE;YAC3B,IAAI,CAAC,YAAY,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAA;QACnC,CAAC;;;;yBAIgB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;sDACM,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC;;;yBAGtD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,6BAA6B,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;yBAC/E,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,gCAAgC,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC;;KAExG,CAAA;IACH,CAAC;IAED,YAAY;QACV,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,KAAK,CAAA;IAChC,CAAC;IAED,OAAO;QACL,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA;QAClD,UAAU,CAAC,IAAI,CAAC,CAAA;IAClB,CAAC;IAED,QAAQ;QACN,UAAU,CAAC,IAAI,CAAC,CAAA;IAClB,CAAC;IAED,SAAS;QACP,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;QAE/D,UAAU,CAAC,IAAI,CAAC,CAAA;IAClB,CAAC;;AA7C0B;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;;oDAAuB;AAErB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;8DAA0D;AACzD;IAA3B,KAAK,CAAC,mBAAmB,CAAC;8BAAU,gBAAgB;IAErD,wEAAwE;;qDAFnB;AApB1C,qBAAqB;IADjC,aAAa,CAAC,yBAAyB,CAAC;GAC5B,qBAAqB,CA+DjC","sourcesContent":["import '@material/web/icon/icon.js'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\n\nimport { i18next, localize } from '@operato/i18n'\nimport { CommonHeaderStyles } from '@operato/styles'\nimport { closePopup } from '@operato/popup'\n\nimport { RecipientsEditor } from './recipients-editor'\nimport { AssigneeItem } from '../types/org-member'\n\n/**\n * 결재선의 각 결재자 리스트를 편집한다.\n */\n@customElement('recipients-editor-popup')\nexport class RecipientsEditorPopup extends localize(i18next)(LitElement) {\n static styles = [\n CommonHeaderStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n\n background-color: var(--md-sys-color-surface);\n }\n\n recipients-editor {\n flex: 1;\n }\n `\n ]\n\n @property({ type: Array }) value?: AssigneeItem[]\n\n @property({ type: Object }) confirmCallback?: (value?: AssigneeItem[] | null) => void\n @query('recipients-editor') editor!: RecipientsEditor\n\n /* this.value는 (원인불명으로) 값이 Reset되므로, 변화값을 유지하도록 별도로 changedValue를 사용함 */\n private changedValue?: AssigneeItem[] = this.value\n\n render() {\n return html`\n <recipients-editor\n .value=${this.value}\n @change=${(e: CustomEvent) => {\n this.changedValue = [...e.detail]\n }}\n ></recipients-editor>\n\n <div class=\"footer\">\n <button @click=${this.onEmpty.bind(this)}>\n <md-icon>check_box_outline_blank</md-icon>${i18next.t('button.empty')}\n </button>\n <div filler></div>\n <button @click=${this.onCancel.bind(this)}><md-icon>cancel</md-icon>${i18next.t('button.cancel')}</button>\n <button @click=${this.onConfirm.bind(this)} done><md-icon>done</md-icon>${i18next.t('button.confirm')}</button>\n </div>\n `\n }\n\n firstUpdated() {\n this.changedValue = this.value\n }\n\n onEmpty() {\n this.confirmCallback && this.confirmCallback(null)\n closePopup(this)\n }\n\n onCancel() {\n closePopup(this)\n }\n\n onConfirm() {\n this.confirmCallback && this.confirmCallback(this.changedValue)\n\n closePopup(this)\n }\n}\n"]}
1
+ {"version":3,"file":"recipients-editor-popup.js","sourceRoot":"","sources":["../../client/component/recipients-editor-popup.ts"],"names":[],"mappings":";AAAA,OAAO,4BAA4B,CAAA;AACnC,OAAO,qCAAqC,CAAA;AAC5C,OAAO,uCAAuC,CAAA;AAC9C,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAS,MAAM,mBAAmB,CAAA;AAEzE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACjD,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAE3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAGtD;;GAEG;AAEI,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,QAAQ,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC;IAAjE;;QAwCL,wEAAwE;QAChE,iBAAY,GAAoB,IAAI,CAAC,KAAK,CAAA;IAuCpD,CAAC;aA/EQ,WAAM,GAAG;QACd,kBAAkB;QAClB,iBAAiB;QACjB,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA4BF;KACF,AAhCY,CAgCZ;IAUD,MAAM;QACJ,OAAO,IAAI,CAAA;;iBAEE,IAAI,CAAC,KAAK;kBACT,CAAC,CAAc,EAAE,EAAE;YAC3B,IAAI,CAAC,YAAY,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAA;QACnC,CAAC;;;;8CAIqC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;YACzD,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC;;iCAEJ,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;mCACpD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC;;KAEtF,CAAA;IACH,CAAC;IAED,YAAY;QACV,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,KAAK,CAAA;IAChC,CAAC;IAED,OAAO;QACL,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA;QAClD,UAAU,CAAC,IAAI,CAAC,CAAA;IAClB,CAAC;IAED,QAAQ;QACN,UAAU,CAAC,IAAI,CAAC,CAAA;IAClB,CAAC;IAED,SAAS;QACP,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;QAE/D,UAAU,CAAC,IAAI,CAAC,CAAA;IAClB,CAAC;;AA5C0B;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;;oDAAuB;AAErB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;8DAA0D;AACzD;IAA3B,KAAK,CAAC,mBAAmB,CAAC;8BAAU,gBAAgB;IAErD,wEAAwE;;qDAFnB;AAtC1C,qBAAqB;IADjC,aAAa,CAAC,yBAAyB,CAAC;GAC5B,qBAAqB,CAgFjC","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@material/web/button/text-button.js'\nimport '@material/web/button/filled-button.js'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\n\nimport { i18next, localize } from '@operato/i18n'\nimport { CommonHeaderStyles, CommonPopupStyles } from '@operato/styles'\nimport { closePopup } from '@operato/popup'\n\nimport { RecipientsEditor } from './recipients-editor'\nimport { AssigneeItem } from '../types/org-member'\n\n/**\n * 결재선의 각 결재자 리스트를 편집한다.\n */\n@customElement('recipients-editor-popup')\nexport class RecipientsEditorPopup extends localize(i18next)(LitElement) {\n static styles = [\n CommonHeaderStyles,\n CommonPopupStyles,\n css`\n /*\n * 단추 줄은 **제품의 팝업 규약**을 쓴다(CommonPopupStyles 의 .buttons).\n *\n * 전에는 손으로 만든 .footer 였고 organization 의 팝업 다섯이 그것을 복사해 갖고 있었다.\n * 규약이 주는 것을 다 놓쳤다 — 팝업 안 단추의 알약 모서리(담는 카드가 둥그니 그 안도\n * 둥글다), 마우스와 손가락을 가르는 갈래(손가락에서는 카드 아래 폭을 채우는 액션바가 된다),\n * 단추 높이 통일.\n *\n * 단추는 Material 것으로 쓴다. 규약의 마우스 갈래는 **md-*-button 의 토큰으로만** 모양을\n * 말한다 — 평범한 button 을 두면 모서리가 0 으로 남는다(실측: 알약이어야 할 자리에 0px).\n * 제품의 다른 팝업도 같은 관용구다(operato-plant 의 maintenance-dialog).\n *\n * 「비우기」는 왼쪽에 둔다 — 되돌리는 것이라 저지르는 것들과 같은 자리에 두지 않는다.\n */\n .buttons .left {\n margin-right: auto;\n }\n :host {\n display: flex;\n flex-direction: column;\n\n background-color: var(--md-sys-color-surface);\n }\n\n recipients-editor {\n flex: 1;\n }\n `\n ]\n\n @property({ type: Array }) value?: AssigneeItem[]\n\n @property({ type: Object }) confirmCallback?: (value?: AssigneeItem[] | null) => void\n @query('recipients-editor') editor!: RecipientsEditor\n\n /* this.value는 (원인불명으로) 값이 Reset되므로, 변화값을 유지하도록 별도로 changedValue를 사용함 */\n private changedValue?: AssigneeItem[] = this.value\n\n render() {\n return html`\n <recipients-editor\n .value=${this.value}\n @change=${(e: CustomEvent) => {\n this.changedValue = [...e.detail]\n }}\n ></recipients-editor>\n\n <div class=\"buttons\">\n <md-text-button class=\"left\" @click=${this.onEmpty.bind(this)}>\n ${i18next.t('button.empty')}\n </md-text-button>\n <md-text-button @click=${this.onCancel.bind(this)}>${i18next.t('button.cancel')}</md-text-button>\n <md-filled-button @click=${this.onConfirm.bind(this)}>${i18next.t('button.confirm')}</md-filled-button>\n </div>\n `\n }\n\n firstUpdated() {\n this.changedValue = this.value\n }\n\n onEmpty() {\n this.confirmCallback && this.confirmCallback(null)\n closePopup(this)\n }\n\n onCancel() {\n closePopup(this)\n }\n\n onConfirm() {\n this.confirmCallback && this.confirmCallback(this.changedValue)\n\n closePopup(this)\n }\n}\n"]}
@@ -11,7 +11,17 @@ let OxFilterDepartmentObject = class OxFilterDepartmentObject extends OxFormFiel
11
11
  :host {
12
12
  display: block;
13
13
  position: relative;
14
- border-bottom: 1px solid rgba(0, 0, 0, 0.15);
14
+ /*
15
+ * 밑줄 톤을 옆의 셀렉터와 맞춘다.
16
+ *
17
+ * rgba(0, 0, 0, 0.15) 를 손으로 박고 있었다. 그 값이 마침 outline-variant 와 비슷했지만
18
+ * 토큰이 아니라 어두운 테마에서는 검정 15%가 그대로 남는다.
19
+ *
20
+ * operato 의 --ox-input-underline 을 쓰지 않는다. 그 토큰은 InputStyles 를 들이는 부품의
21
+ * :host 에만 정의되고 이 부품은 그것을 안 들이므로, 참조하면 선언 전체가 무효가 되어
22
+ * 밑줄이 사라진다. 그래서 같은 Material 토큰을 직접 가리킨다.
23
+ */
24
+ border-bottom: 1px solid var(--md-sys-color-outline-variant, rgba(0, 0, 0, 0.15));
15
25
  min-width: 100px;
16
26
 
17
27
  --ox-select-padding: var(--spacing-tiny);
@@ -1 +1 @@
1
- {"version":3,"file":"ox-filter-department-object.js","sourceRoot":"","sources":["../../client/filters-form/ox-filter-department-object.ts"],"names":[],"mappings":"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","sourcesContent":["import '../component/department-selector.js'\n\nimport { css, html, TemplateResult } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport { i18next } from '@operato/i18n'\nimport { openPopup, PopupHandle } from '@operato/layout'\nimport { OxFormField } from '@operato/input'\n\n@customElement('ox-filter-department-object')\nexport class OxFilterDepartmentObject extends OxFormField {\n static styles = [\n css`\n :host {\n display: block;\n position: relative;\n border-bottom: 1px solid rgba(0, 0, 0, 0.15);\n min-width: 100px;\n\n --ox-select-padding: var(--spacing-tiny);\n --ox-select-font: var(--input-font);\n --ox-select-color: var(--input-color, var(--md-sys-color-on-surface-variant));\n --ox-select-icon-color: var(--theme-primary-text-color, var(--md-sys-color-on-surface-variant));\n --ox-select-icon-hover-color: var(--md-sys-color-on-primary-container, #3c3938);\n }\n\n div {\n width: 100%;\n box-sizing: border-box;\n\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n padding: var(--ox-select-padding);\n font: var(--ox-select-font);\n color: var(--ox-select-color);\n }\n\n span {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n gap: 4px;\n }\n\n md-icon {\n --md-icon-size: 16px;\n display: block;\n text-align: right;\n color: var(--ox-select-icon-color);\n opacity: 0.7;\n }\n\n div:hover md-icon {\n color: var(--md-sys-color-on-primary-container);\n }\n `\n ]\n\n @property({ type: Object }) column: any\n @property({ type: String }) value?: string\n\n @state() department?: any\n\n private popup?: PopupHandle\n private template?: TemplateResult\n\n render() {\n var { name, description } = this.department || (this.value ? { name: this.value } : {})\n\n return html`\n <div @click=${this._onclick} @keydown=${this._onkeydown}>\n <span tabindex=\"0\" style=\"flex:1\">${name || ''}${(description && `(${description})`) || ''}</span>\n <md-icon>search</md-icon>\n </div>\n `\n }\n\n _onclick(e: Event): void {\n e.stopPropagation()\n this.openSelector()\n }\n\n _onkeydown(e: KeyboardEvent): void {\n const key = e.key\n if (key == 'Enter') {\n e.stopPropagation()\n this.openSelector()\n }\n }\n\n openSelector() {\n if (this.popup) {\n delete this.popup\n }\n\n const confirmCallback = (selected?: { [field: string]: any }) => {\n this.department = selected\n ? {\n id: selected.id,\n controlNo: selected.controlNo,\n name: selected.name,\n description: selected.description\n }\n : null\n\n this.value = this.department?.name\n\n this.dispatchEvent(\n new CustomEvent('change', {\n bubbles: true,\n composed: true,\n detail: this.value\n })\n )\n }\n\n var template =\n this.template ||\n html`\n <department-selector\n .value=${this.department || {}}\n .confirmCallback=${confirmCallback.bind(this)}\n ></department-selector>\n `\n\n this.popup = openPopup(template, {\n backdrop: true,\n size: 'large',\n title: i18next.t('title.select_item')\n })\n }\n}\n"]}
1
+ {"version":3,"file":"ox-filter-department-object.js","sourceRoot":"","sources":["../../client/filters-form/ox-filter-department-object.ts"],"names":[],"mappings":"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","sourcesContent":["import '../component/department-selector.js'\n\nimport { css, html, TemplateResult } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport { i18next } from '@operato/i18n'\nimport { openPopup, PopupHandle } from '@operato/layout'\nimport { OxFormField } from '@operato/input'\n\n@customElement('ox-filter-department-object')\nexport class OxFilterDepartmentObject extends OxFormField {\n static styles = [\n css`\n :host {\n display: block;\n position: relative;\n /*\n * 밑줄 톤을 옆의 셀렉터와 맞춘다.\n *\n * rgba(0, 0, 0, 0.15) 를 손으로 박고 있었다. 그 값이 마침 outline-variant 와 비슷했지만\n * 토큰이 아니라 어두운 테마에서는 검정 15%가 그대로 남는다.\n *\n * operato 의 --ox-input-underline 을 쓰지 않는다. 그 토큰은 InputStyles 를 들이는 부품의\n * :host 에만 정의되고 이 부품은 그것을 안 들이므로, 참조하면 선언 전체가 무효가 되어\n * 밑줄이 사라진다. 그래서 같은 Material 토큰을 직접 가리킨다.\n */\n border-bottom: 1px solid var(--md-sys-color-outline-variant, rgba(0, 0, 0, 0.15));\n min-width: 100px;\n\n --ox-select-padding: var(--spacing-tiny);\n --ox-select-font: var(--input-font);\n --ox-select-color: var(--input-color, var(--md-sys-color-on-surface-variant));\n --ox-select-icon-color: var(--theme-primary-text-color, var(--md-sys-color-on-surface-variant));\n --ox-select-icon-hover-color: var(--md-sys-color-on-primary-container, #3c3938);\n }\n\n div {\n width: 100%;\n box-sizing: border-box;\n\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n padding: var(--ox-select-padding);\n font: var(--ox-select-font);\n color: var(--ox-select-color);\n }\n\n span {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n gap: 4px;\n }\n\n md-icon {\n --md-icon-size: 16px;\n display: block;\n text-align: right;\n color: var(--ox-select-icon-color);\n opacity: 0.7;\n }\n\n div:hover md-icon {\n color: var(--md-sys-color-on-primary-container);\n }\n `\n ]\n\n @property({ type: Object }) column: any\n @property({ type: String }) value?: string\n\n @state() department?: any\n\n private popup?: PopupHandle\n private template?: TemplateResult\n\n render() {\n var { name, description } = this.department || (this.value ? { name: this.value } : {})\n\n return html`\n <div @click=${this._onclick} @keydown=${this._onkeydown}>\n <span tabindex=\"0\" style=\"flex:1\">${name || ''}${(description && `(${description})`) || ''}</span>\n <md-icon>search</md-icon>\n </div>\n `\n }\n\n _onclick(e: Event): void {\n e.stopPropagation()\n this.openSelector()\n }\n\n _onkeydown(e: KeyboardEvent): void {\n const key = e.key\n if (key == 'Enter') {\n e.stopPropagation()\n this.openSelector()\n }\n }\n\n openSelector() {\n if (this.popup) {\n delete this.popup\n }\n\n const confirmCallback = (selected?: { [field: string]: any }) => {\n this.department = selected\n ? {\n id: selected.id,\n controlNo: selected.controlNo,\n name: selected.name,\n description: selected.description\n }\n : null\n\n this.value = this.department?.name\n\n this.dispatchEvent(\n new CustomEvent('change', {\n bubbles: true,\n composed: true,\n detail: this.value\n })\n )\n }\n\n var template =\n this.template ||\n html`\n <department-selector\n .value=${this.department || {}}\n .confirmCallback=${confirmCallback.bind(this)}\n ></department-selector>\n `\n\n this.popup = openPopup(template, {\n backdrop: true,\n size: 'large',\n title: i18next.t('title.select_item')\n })\n }\n}\n"]}
@@ -0,0 +1,121 @@
1
+ import '@operato/data-grist';
2
+ import '../../component/approval-line-items-editor-popup';
3
+ import { PageView } from '@operato/shell';
4
+ import { FetchOption } from '@operato/data-grist';
5
+ declare const ApprovalLineListPage_base: (new (...args: any[]) => import("lit").LitElement) & typeof PageView & import("@open-wc/dedupe-mixin").Constructor<import("@open-wc/scoped-elements/types/src/types").ScopedElementsHost>;
6
+ /**
7
+ * 결재선 — **한 화면, 두 축.**
8
+ *
9
+ * ── 왜 한 화면인가 ─────────────────────────────────────────────────────────
10
+ * 전에는 「공용 결재선」과 「내 결재선」이 각각 메뉴였다. 같은 것을 관리하는 두 자리라, 찾을 때마다
11
+ * 어느 쪽에 있었는지를 먼저 기억해야 했다.
12
+ *
13
+ * ── 왜 섞지 않고 축으로 가르는가 ────────────────────────────────────────────
14
+ * 두 결재선은 **바꾸는 행위의 무게가 다르다.**
15
+ *
16
+ * 공용 조직의 규정이다. 바꾸면 남의 결재 경로가 바뀐다. 권한이 있어야 고친다
17
+ * 내 결재선 내 편의다. 바꿔도 나만 영향받는다
18
+ *
19
+ * 한 목록에 섞으면 「저장」 한 번이 내 편의 설정과 조직 규정을 함께 저지른다. 축으로 가르면 축마다
20
+ * 질의도 저장도 따로여서 그 일이 일어나지 않는다.
21
+ *
22
+ * 공용 축을 감추지는 않는다 — **누구나 참조할 수 있고, 권한이 있으면 고칠 수도 있다.** 권한이 없으면
23
+ * 그 축에서 고칠 수만 없게 한다.
24
+ *
25
+ * ── 주소가 축을 갖는다 ──────────────────────────────────────────────────────
26
+ * /approval-line-list 공용
27
+ * /approval-line-list/mine 내 결재선
28
+ *
29
+ * 대상이 바뀌는 것이므로 필터와 달리 주소에 담는다. 붙여 보낼 수 있고, 뒤로 가기가 앞 축으로 돌아간다.
30
+ *
31
+ * ── 줄마다 그 결재선이 보인다 ───────────────────────────────────────────────
32
+ * 결재선의 내용은 **누가 몇 번째로 결재하나**다. 이름만 늘어놓고 내용을 팝업에 두면 「팀장만 거치는
33
+ * 게 있었나」를 알려고 줄마다 열어 봐야 한다.
34
+ *
35
+ * 오세진 → 윤가람 [참조] → 한동수
36
+ *
37
+ * 결재자가 하나도 없으면 상신이 곧 완료된다 — 승인 게이트가 있는 척만 하게 된다. 그것도 줄에 적는다.
38
+ */
39
+ export declare class ApprovalLineListPage extends ApprovalLineListPage_base {
40
+ static styles: import("lit").CSSResult[];
41
+ gristConfig: any;
42
+ mode: 'CARD' | 'GRID' | 'LIST';
43
+ private grist;
44
+ private axis;
45
+ /**
46
+ * 이 사람이 공용 결재선을 고칠 수 있나.
47
+ *
48
+ * `hasPrivilege` 는 프로필을 기다리는 비동기 함수인데 그리스트의 `editable` 은 동기로 불린다. 그래서
49
+ * 한 번 물어 여기에 담는다.
50
+ *
51
+ * **기본값이 false 인 것이 중요하다.** 답이 오기 전 한 순간을 「고칠 수 있음」으로 그리면 그 사이에
52
+ * 누른 사람이 거절당한다.
53
+ */
54
+ private mayEditCommon;
55
+ /**
56
+ * 내가 사원으로 등록되어 있나.
57
+ *
58
+ * 내 결재선은 사원 기록에 매인다 — 서버가 `ownerValue` 를 그 기록의 id 로 채운다. 등록되어 있지
59
+ * 않으면 **만들 수가 없다.** 그것을 미리 알지 못하면 화면이 입력을 다 받아 놓고 저장할 때 실패한다.
60
+ *
61
+ * 없을 수도 있고 둘 이상일 수도 있다(`(domain, user)` 유일 제약이 없다). 여기서 필요한 것은 하나라도
62
+ * 있느냐뿐이다.
63
+ */
64
+ private amEmployee;
65
+ /** 지금 축을 고칠 수 있나. 공용은 권한이 있어야 하고, 내 결재선은 언제나 된다. */
66
+ private get editable();
67
+ get context(): {
68
+ title: string;
69
+ search: {
70
+ handler: (search: string) => void;
71
+ value: string;
72
+ };
73
+ filter: {
74
+ handler: () => void;
75
+ };
76
+ help: string;
77
+ actions: ({
78
+ icon: string;
79
+ title: string;
80
+ action: () => Promise<void>;
81
+ emphasis?: undefined;
82
+ } | {
83
+ icon: string;
84
+ title: string;
85
+ action: () => Promise<void>;
86
+ emphasis: {
87
+ danger: boolean;
88
+ };
89
+ })[];
90
+ };
91
+ render(): import("lit-html").TemplateResult<1>;
92
+ /**
93
+ * 축을 고른다 — **주소만 바꾼다.**
94
+ *
95
+ * 값을 여기서 세우지 않는다. 바뀐 주소를 `pageUpdated` 가 받아 세운다. 그래야 뒤로 가기와 새로 고침이
96
+ * 같은 자리로 온다.
97
+ */
98
+ private selectAxis;
99
+ /** 한 사람을 무엇으로 부를까. 이름이 없으면 관리번호라도 보인다 — 빈 칸으로 두지 않는다. */
100
+ private approverText;
101
+ pageInitialized(lifecycle: any): Promise<void>;
102
+ /**
103
+ * 내가 사원인가를 서버에 묻는다.
104
+ *
105
+ * `myEmployees` 는 권한이 없다 — 「나는 누구인가」는 권한으로 가릴 사실이 아니다. `employees` 는
106
+ * `employee:query` 를 요구해서, 정작 답이 필요한 일반 사원이 물을 수 없다.
107
+ */
108
+ private askAmEmployee;
109
+ pageUpdated(changes: any, after: any, before: any): Promise<void>;
110
+ private applyConfig;
111
+ private emptyNote;
112
+ fetchHandler({ page, limit, sortings, filters }: FetchOption): Promise<{
113
+ total: any;
114
+ records: any;
115
+ }>;
116
+ private save;
117
+ private delete;
118
+ /** 결재선의 내용(누가 몇 번째로 결재하나)을 저장한다. */
119
+ private updateModel;
120
+ }
121
+ export {};