@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.
- package/dist-client/component/approval-line-brief.js +93 -36
- package/dist-client/component/approval-line-brief.js.map +1 -1
- package/dist-client/component/approval-line-items-editor-popup.d.ts +2 -0
- package/dist-client/component/approval-line-items-editor-popup.js +27 -9
- package/dist-client/component/approval-line-items-editor-popup.js.map +1 -1
- package/dist-client/component/approval-line-items-editor.d.ts +7 -1
- package/dist-client/component/approval-line-items-editor.js +67 -3
- package/dist-client/component/approval-line-items-editor.js.map +1 -1
- package/dist-client/component/approval-line-selector.d.ts +2 -0
- package/dist-client/component/approval-line-selector.js +40 -9
- package/dist-client/component/approval-line-selector.js.map +1 -1
- package/dist-client/component/approval-line-view.d.ts +15 -0
- package/dist-client/component/approval-line-view.js +177 -41
- package/dist-client/component/approval-line-view.js.map +1 -1
- package/dist-client/component/assignees-editor-popup.d.ts +2 -0
- package/dist-client/component/assignees-editor-popup.js +27 -8
- package/dist-client/component/assignees-editor-popup.js.map +1 -1
- package/dist-client/component/department-selector.d.ts +2 -0
- package/dist-client/component/department-selector.js +27 -8
- package/dist-client/component/department-selector.js.map +1 -1
- package/dist-client/component/recipients-editor-popup.d.ts +2 -0
- package/dist-client/component/recipients-editor-popup.js +27 -8
- package/dist-client/component/recipients-editor-popup.js.map +1 -1
- package/dist-client/filters-form/ox-filter-department-object.js +11 -1
- package/dist-client/filters-form/ox-filter-department-object.js.map +1 -1
- package/dist-client/pages/approval-line/approval-line-list-page.d.ts +121 -0
- package/dist-client/pages/approval-line/approval-line-list-page.js +583 -0
- package/dist-client/pages/approval-line/approval-line-list-page.js.map +1 -0
- package/dist-client/pages/approval-line/common-approval-line-templates-page.d.ts +0 -2
- package/dist-client/pages/approval-line/common-approval-line-templates-page.js +27 -11
- package/dist-client/pages/approval-line/common-approval-line-templates-page.js.map +1 -1
- package/dist-client/pages/approval-line/my-approval-line-templates-page.d.ts +0 -2
- package/dist-client/pages/approval-line/my-approval-line-templates-page.js +33 -9
- package/dist-client/pages/approval-line/my-approval-line-templates-page.js.map +1 -1
- package/dist-client/pages/department/department-list-page.d.ts +0 -2
- package/dist-client/pages/department/department-list-page.js +2 -6
- package/dist-client/pages/department/department-list-page.js.map +1 -1
- package/dist-client/pages/department/department-tree-page.d.ts +0 -10
- package/dist-client/pages/department/department-tree-page.js +35 -16
- package/dist-client/pages/department/department-tree-page.js.map +1 -1
- package/dist-client/pages/employee/employee-list-page.d.ts +0 -2
- package/dist-client/pages/employee/employee-list-page.js +2 -6
- package/dist-client/pages/employee/employee-list-page.js.map +1 -1
- package/dist-client/route.d.ts +1 -1
- package/dist-client/route.js +9 -0
- package/dist-client/route.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-client/types/approval-line.d.ts +64 -0
- package/dist-client/types/approval-line.js +67 -0
- package/dist-client/types/approval-line.js.map +1 -1
- package/dist-server/service/approval-line/approval-line-item.d.ts +40 -0
- package/dist-server/service/approval-line/approval-line-item.js +42 -2
- package/dist-server/service/approval-line/approval-line-item.js.map +1 -1
- package/dist-server/service/approval-line/approval-line-mutation.js +24 -33
- package/dist-server/service/approval-line/approval-line-mutation.js.map +1 -1
- package/dist-server/service/approval-line/approval-line-query.js +36 -21
- package/dist-server/service/approval-line/approval-line-query.js.map +1 -1
- package/dist-server/service/employee/employee-query.d.ts +25 -0
- package/dist-server/service/employee/employee-query.js +41 -0
- package/dist-server/service/employee/employee-query.js.map +1 -1
- package/dist-server/service/employee/index.d.ts +1 -0
- package/dist-server/service/employee/index.js +3 -0
- package/dist-server/service/employee/index.js.map +1 -1
- package/dist-server/service/employee/my-employee-refusal.d.ts +22 -0
- package/dist-server/service/employee/my-employee-refusal.js +56 -0
- package/dist-server/service/employee/my-employee-refusal.js.map +1 -0
- package/dist-server/service/employee/my-employee.d.ts +22 -0
- package/dist-server/service/employee/my-employee.js +43 -0
- package/dist-server/service/employee/my-employee.js.map +1 -0
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -6
- package/spec/unit/my-employee.spec.ts +102 -0
- package/things-factory.config.js +1 -0
- package/translations/en.json +44 -17
- package/translations/ja.json +44 -17
- package/translations/ko.json +46 -19
- package/translations/ms.json +43 -16
- 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-grist';
|
|
4
6
|
import './approval-line-view';
|
|
5
7
|
import gql from 'graphql-tag';
|
|
@@ -10,7 +12,7 @@ import { client } from '@operato/graphql';
|
|
|
10
12
|
import { i18next } from '@operato/i18n';
|
|
11
13
|
import { closePopup } from '@operato/popup';
|
|
12
14
|
import { isMobileDevice } from '@operato/utils';
|
|
13
|
-
import { CommonHeaderStyles } from '@operato/styles';
|
|
15
|
+
import { CommonHeaderStyles, CommonPopupStyles } from '@operato/styles';
|
|
14
16
|
import { ApprovalLineView } from './approval-line-view';
|
|
15
17
|
let ApprovalLineSelector = class ApprovalLineSelector extends LitElement {
|
|
16
18
|
constructor() {
|
|
@@ -20,7 +22,25 @@ let ApprovalLineSelector = class ApprovalLineSelector extends LitElement {
|
|
|
20
22
|
}
|
|
21
23
|
static { this.styles = [
|
|
22
24
|
CommonHeaderStyles,
|
|
25
|
+
CommonPopupStyles,
|
|
23
26
|
css `
|
|
27
|
+
/*
|
|
28
|
+
* 단추 줄은 **제품의 팝업 규약**을 쓴다(CommonPopupStyles 의 .buttons).
|
|
29
|
+
*
|
|
30
|
+
* 전에는 손으로 만든 .footer 였고 organization 의 팝업 다섯이 그것을 복사해 갖고 있었다.
|
|
31
|
+
* 규약이 주는 것을 다 놓쳤다 — 팝업 안 단추의 알약 모서리(담는 카드가 둥그니 그 안도
|
|
32
|
+
* 둥글다), 마우스와 손가락을 가르는 갈래(손가락에서는 카드 아래 폭을 채우는 액션바가 된다),
|
|
33
|
+
* 단추 높이 통일.
|
|
34
|
+
*
|
|
35
|
+
* 단추는 Material 것으로 쓴다. 규약의 마우스 갈래는 **md-*-button 의 토큰으로만** 모양을
|
|
36
|
+
* 말한다 — 평범한 button 을 두면 모서리가 0 으로 남는다(실측: 알약이어야 할 자리에 0px).
|
|
37
|
+
* 제품의 다른 팝업도 같은 관용구다(operato-plant 의 maintenance-dialog).
|
|
38
|
+
*
|
|
39
|
+
* 「비우기」는 왼쪽에 둔다 — 되돌리는 것이라 저지르는 것들과 같은 자리에 두지 않는다.
|
|
40
|
+
*/
|
|
41
|
+
.buttons .left {
|
|
42
|
+
margin-right: auto;
|
|
43
|
+
}
|
|
24
44
|
:host {
|
|
25
45
|
display: flex;
|
|
26
46
|
flex-direction: column;
|
|
@@ -43,10 +63,22 @@ let ApprovalLineSelector = class ApprovalLineSelector extends LitElement {
|
|
|
43
63
|
render() {
|
|
44
64
|
return html `
|
|
45
65
|
<approval-line-view></approval-line-view>
|
|
66
|
+
<!--
|
|
67
|
+
.data 를 넘기지 않는다 — 목록은 fetchHandler 가 채운다.
|
|
68
|
+
|
|
69
|
+
이 부품은 data 를 **읽지도 채우지도 않는다.** 선언과 이 바인딩만 있어서 값은 늘
|
|
70
|
+
ZERO_DATA(빈 것)이고, 렌더가 돌 때마다 그 빈 것이 내려간다. 그리스트는 data 가 설정되면
|
|
71
|
+
reset() 하므로(data-grist 의 updated), 이 부품이 **다시 그려지는 순간 목록이 통째로
|
|
72
|
+
사라진다.** 조회 결과는 data-provider 가 그리스트에 직접 넣는다.
|
|
73
|
+
|
|
74
|
+
오늘은 안 터진다 — 이 부품에 다시 그릴 상태(@state)가 없다. 그러나 @operato/app 의
|
|
75
|
+
참조 선택기에서 바닥 단추를 고른 상태에 묶자마자 바로 터졌다.
|
|
76
|
+
|
|
77
|
+
[확인함] 2026-09-05 · 라디오 클릭 → reset() 1회(DataGrist.updated) → 20건 → 0건
|
|
78
|
+
-->
|
|
46
79
|
<ox-grist
|
|
47
80
|
.mode=${isMobileDevice() ? 'LIST' : 'GRID'}
|
|
48
81
|
.config=${this.config}
|
|
49
|
-
.data=${this.data}
|
|
50
82
|
.fetchHandler=${this.fetchHandler.bind(this)}
|
|
51
83
|
.selectedRecords=${this.selectedRecords}
|
|
52
84
|
@select-record-change=${e => {
|
|
@@ -55,13 +87,12 @@ let ApprovalLineSelector = class ApprovalLineSelector extends LitElement {
|
|
|
55
87
|
>
|
|
56
88
|
</ox-grist>
|
|
57
89
|
|
|
58
|
-
<div class="
|
|
59
|
-
<button @click=${this.onEmpty.bind(this)}>
|
|
60
|
-
|
|
61
|
-
</button>
|
|
62
|
-
<
|
|
63
|
-
<button @click=${this.
|
|
64
|
-
<button @click=${this.onConfirm.bind(this)} done><md-icon>done</md-icon>${i18next.t('button.confirm')}</button>
|
|
90
|
+
<div class="buttons">
|
|
91
|
+
<md-text-button class="left" @click=${this.onEmpty.bind(this)}>
|
|
92
|
+
${i18next.t('button.empty')}
|
|
93
|
+
</md-text-button>
|
|
94
|
+
<md-text-button @click=${this.onCancel.bind(this)}>${i18next.t('button.cancel')}</md-text-button>
|
|
95
|
+
<md-filled-button @click=${this.onConfirm.bind(this)}>${i18next.t('button.confirm')}</md-filled-button>
|
|
65
96
|
</div>
|
|
66
97
|
`;
|
|
67
98
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"approval-line-selector.js","sourceRoot":"","sources":["../../client/component/approval-line-selector.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@operato/data-grist'\nimport './approval-line-view'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\n\nimport {\n getRenderer,\n DataGrist,\n FetchOption,\n GristEventHandler,\n GristData,\n GristRecord,\n ZERO_DATA\n} from '@operato/data-grist'\nimport { client } from '@operato/graphql'\nimport { i18next } from '@operato/i18n'\nimport { closePopup } from '@operato/popup'\nimport { isMobileDevice } from '@operato/utils'\nimport { CommonHeaderStyles } from '@operato/styles'\n\nimport { ApprovalLineView } from './approval-line-view'\n\n@customElement('approval-line-selector')\nexport class ApprovalLineSelector 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\n approval-line-view {\n min-height: 100px;\n }\n\n ox-grist {\n flex: 1;\n }\n `\n ]\n\n @property({ type: String }) value?: string\n @property({ type: Object }) config: any\n @property({ type: Object }) data: GristData = ZERO_DATA\n @property({ type: Object }) confirmCallback?: (record?: GristRecord) => Promise<void>\n @property({ type: Array }) selectedRecords: GristRecord[] = []\n\n @query('ox-grist') grist!: DataGrist\n @query('approval-line-view') view?: ApprovalLineView\n\n render() {\n return html`\n <approval-line-view></approval-line-view>\n <ox-grist\n .mode=${isMobileDevice() ? 'LIST' : 'GRID'}\n .config=${this.config}\n .data=${this.data}\n .fetchHandler=${this.fetchHandler.bind(this)}\n .selectedRecords=${this.selectedRecords}\n @select-record-change=${e => {\n this.view!.model = this.selected?.model || []\n }}\n >\n </ox-grist>\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 searchText(value: string) {\n this.grist!.searchText = value\n }\n\n onEmpty() {\n this.confirmCallback && this.confirmCallback()\n closePopup(this)\n }\n\n onCancel() {\n closePopup(this)\n }\n\n onConfirm() {\n this.confirmCallback && this.confirmCallback(this.selected)\n closePopup(this)\n }\n\n async fetchHandler({ page = 1, limit = 100, sortings = [], filters = [] }: FetchOption) {\n const response = await client.query({\n query: gql`\n query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {\n responses: approvalLineReferences(filters: $filters, pagination: $pagination, sortings: $sortings) {\n items {\n id\n name\n description\n ownerType\n owner {\n id\n name\n description\n controlNo\n }\n model {\n type\n approver {\n id\n name\n description\n controlNo\n }\n }\n }\n total\n }\n }\n `,\n variables: {\n filters,\n pagination: { page, limit },\n sortings\n }\n })\n\n return {\n total: response.data.responses.total || 0,\n records: response.data.responses.items || []\n }\n }\n\n async firstUpdated() {\n this.config = {\n list: {\n fields: ['name', 'description'],\n details: ['ownerType', 'owner']\n },\n columns: [\n { type: 'gutter', gutterName: 'sequence' },\n { type: 'gutter', gutterName: 'row-selector', multiple: false },\n {\n type: 'string',\n name: 'name',\n header: i18next.t('field.name'),\n record: {\n editable: false\n },\n filter: 'search',\n sortable: true,\n width: 150\n },\n {\n type: 'string',\n name: 'description',\n header: i18next.t('field.description'),\n record: {\n editable: false\n },\n filter: 'search',\n width: 200\n },\n {\n type: 'string',\n name: 'ownerType',\n header: i18next.t('field.owner-type'),\n record: {\n editable: false\n },\n width: 200\n },\n {\n type: 'resource-object',\n name: 'owner',\n header: i18next.t('field.owner'),\n record: {\n editable: false,\n renderer: function (value, column, record, rowIndex, field) {\n var options = {}\n switch (record.ownerType) {\n case 'Employee':\n options = {\n valueField: 'id',\n nameField: 'name',\n descriptionField: 'controlNo'\n }\n break\n case 'Common':\n default:\n return\n }\n\n var dynamicRecord = { ...column.record, options }\n\n return getRenderer(column.type)(value, { ...column, record: dynamicRecord }, record, rowIndex, field)\n }\n },\n width: 200\n }\n ],\n rows: {\n selectable: {\n multiple: false\n },\n appendable: false,\n handlers: {\n click: 'select-row',\n dblclick: ((columns, data, column, record, rowIndex, field) => {\n this.onConfirm()\n }) as GristEventHandler\n }\n }\n }\n }\n\n get selected() {\n var selected = this.grist.selected\n\n return selected && selected.length > 0 ? selected[0] : undefined\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"approval-line-selector.js","sourceRoot":"","sources":["../../client/component/approval-line-selector.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@material/web/button/text-button.js'\nimport '@material/web/button/filled-button.js'\nimport '@operato/data-grist'\nimport './approval-line-view'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\n\nimport {\n getRenderer,\n DataGrist,\n FetchOption,\n GristEventHandler,\n GristData,\n GristRecord,\n ZERO_DATA\n} from '@operato/data-grist'\nimport { client } from '@operato/graphql'\nimport { i18next } from '@operato/i18n'\nimport { closePopup } from '@operato/popup'\nimport { isMobileDevice } from '@operato/utils'\nimport { CommonHeaderStyles, CommonPopupStyles } from '@operato/styles'\n\nimport { ApprovalLineView } from './approval-line-view'\n\n@customElement('approval-line-selector')\nexport class ApprovalLineSelector 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\n approval-line-view {\n min-height: 100px;\n }\n\n ox-grist {\n flex: 1;\n }\n `\n ]\n\n @property({ type: String }) value?: string\n @property({ type: Object }) config: any\n @property({ type: Object }) data: GristData = ZERO_DATA\n @property({ type: Object }) confirmCallback?: (record?: GristRecord) => Promise<void>\n @property({ type: Array }) selectedRecords: GristRecord[] = []\n\n @query('ox-grist') grist!: DataGrist\n @query('approval-line-view') view?: ApprovalLineView\n\n render() {\n return html`\n <approval-line-view></approval-line-view>\n <!--\n .data 를 넘기지 않는다 — 목록은 fetchHandler 가 채운다.\n\n 이 부품은 data 를 **읽지도 채우지도 않는다.** 선언과 이 바인딩만 있어서 값은 늘\n ZERO_DATA(빈 것)이고, 렌더가 돌 때마다 그 빈 것이 내려간다. 그리스트는 data 가 설정되면\n reset() 하므로(data-grist 의 updated), 이 부품이 **다시 그려지는 순간 목록이 통째로\n 사라진다.** 조회 결과는 data-provider 가 그리스트에 직접 넣는다.\n\n 오늘은 안 터진다 — 이 부품에 다시 그릴 상태(@state)가 없다. 그러나 @operato/app 의\n 참조 선택기에서 바닥 단추를 고른 상태에 묶자마자 바로 터졌다.\n\n [확인함] 2026-09-05 · 라디오 클릭 → reset() 1회(DataGrist.updated) → 20건 → 0건\n -->\n <ox-grist\n .mode=${isMobileDevice() ? 'LIST' : 'GRID'}\n .config=${this.config}\n .fetchHandler=${this.fetchHandler.bind(this)}\n .selectedRecords=${this.selectedRecords}\n @select-record-change=${e => {\n this.view!.model = this.selected?.model || []\n }}\n >\n </ox-grist>\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 searchText(value: string) {\n this.grist!.searchText = value\n }\n\n onEmpty() {\n this.confirmCallback && this.confirmCallback()\n closePopup(this)\n }\n\n onCancel() {\n closePopup(this)\n }\n\n onConfirm() {\n this.confirmCallback && this.confirmCallback(this.selected)\n closePopup(this)\n }\n\n async fetchHandler({ page = 1, limit = 100, sortings = [], filters = [] }: FetchOption) {\n const response = await client.query({\n query: gql`\n query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {\n responses: approvalLineReferences(filters: $filters, pagination: $pagination, sortings: $sortings) {\n items {\n id\n name\n description\n ownerType\n owner {\n id\n name\n description\n controlNo\n }\n model {\n type\n approver {\n id\n name\n description\n controlNo\n }\n }\n }\n total\n }\n }\n `,\n variables: {\n filters,\n pagination: { page, limit },\n sortings\n }\n })\n\n return {\n total: response.data.responses.total || 0,\n records: response.data.responses.items || []\n }\n }\n\n async firstUpdated() {\n this.config = {\n list: {\n fields: ['name', 'description'],\n details: ['ownerType', 'owner']\n },\n columns: [\n { type: 'gutter', gutterName: 'sequence' },\n { type: 'gutter', gutterName: 'row-selector', multiple: false },\n {\n type: 'string',\n name: 'name',\n header: i18next.t('field.name'),\n record: {\n editable: false\n },\n filter: 'search',\n sortable: true,\n width: 150\n },\n {\n type: 'string',\n name: 'description',\n header: i18next.t('field.description'),\n record: {\n editable: false\n },\n filter: 'search',\n width: 200\n },\n {\n type: 'string',\n name: 'ownerType',\n header: i18next.t('field.owner-type'),\n record: {\n editable: false\n },\n width: 200\n },\n {\n type: 'resource-object',\n name: 'owner',\n header: i18next.t('field.owner'),\n record: {\n editable: false,\n renderer: function (value, column, record, rowIndex, field) {\n var options = {}\n switch (record.ownerType) {\n case 'Employee':\n options = {\n valueField: 'id',\n nameField: 'name',\n descriptionField: 'controlNo'\n }\n break\n case 'Common':\n default:\n return\n }\n\n var dynamicRecord = { ...column.record, options }\n\n return getRenderer(column.type)(value, { ...column, record: dynamicRecord }, record, rowIndex, field)\n }\n },\n width: 200\n }\n ],\n rows: {\n selectable: {\n multiple: false\n },\n appendable: false,\n handlers: {\n click: 'select-row',\n dblclick: ((columns, data, column, record, rowIndex, field) => {\n this.onConfirm()\n }) as GristEventHandler\n }\n }\n }\n }\n\n get selected() {\n var selected = this.grist.selected\n\n return selected && selected.length > 0 ? selected[0] : undefined\n }\n}\n"]}
|
|
@@ -5,7 +5,22 @@ export declare class ApprovalLineView extends ApprovalLineView_base {
|
|
|
5
5
|
static styles: import("lit").CSSResult[];
|
|
6
6
|
model?: ApprovalLineItem[];
|
|
7
7
|
current?: number;
|
|
8
|
+
updated(changes: any): void;
|
|
8
9
|
render(): TemplateResult<1>;
|
|
10
|
+
/**
|
|
11
|
+
* One step of the approval line.
|
|
12
|
+
*
|
|
13
|
+
* A reference is drawn differently from an approval. Drawn the same it reads as "this person has
|
|
14
|
+
* to approve before it moves on", which a reference does not do — whoever assembles the line has
|
|
15
|
+
* to be able to see here what they put in.
|
|
16
|
+
*
|
|
17
|
+
* It carries no number either: a reference takes no turn, so there is no "third" for it to be.
|
|
18
|
+
*
|
|
19
|
+
* The number is the 1-based position in approvalLine, which is exactly what the server means by
|
|
20
|
+
* `order`: submitter excluded, references included, array position as it stands (see
|
|
21
|
+
* worklist/server/controllers/activity-approval/approval-line.ts). A reference holding a slot
|
|
22
|
+
* without showing a digit is therefore right, not a gap.
|
|
23
|
+
*/
|
|
9
24
|
renderItem(item: ApprovalLineItem, order: number): TemplateResult;
|
|
10
25
|
}
|
|
11
26
|
export {};
|
|
@@ -2,6 +2,7 @@ import { __decorate, __metadata } from "tslib";
|
|
|
2
2
|
import { css, html, LitElement } from 'lit';
|
|
3
3
|
import { customElement, property } from 'lit/decorators.js';
|
|
4
4
|
import { i18next, localize } from '@operato/i18n';
|
|
5
|
+
import { isReferenceStep } from '../types/approval-line';
|
|
5
6
|
import { OrgMemberTargetType } from '../types/org-member';
|
|
6
7
|
let ApprovalLineView = class ApprovalLineView extends localize(i18next)(LitElement) {
|
|
7
8
|
constructor() {
|
|
@@ -10,93 +11,217 @@ let ApprovalLineView = class ApprovalLineView extends localize(i18next)(LitEleme
|
|
|
10
11
|
}
|
|
11
12
|
static { this.styles = [
|
|
12
13
|
css `
|
|
14
|
+
/*
|
|
15
|
+
* 면을 갖지 않는다 — 담는 쪽(worklist 의 곁 패널)이 면을 준다. 회색 면을 스스로 칠하면
|
|
16
|
+
* 패널 안에 회색 덩어리가 생긴다.
|
|
17
|
+
*/
|
|
18
|
+
/*
|
|
19
|
+
* 이 부품은 넓은 자리(결재선 편집기 · 선택기)와 좁은 자리(worklist 의 정보 팝업)에 함께 쓰인다.
|
|
20
|
+
* 그래서 **어느 폭에서도 무너지지 않아야** 한다 — 좁다고 칸을 짜부라뜨리면 이름이 글자마다
|
|
21
|
+
* 줄바꿈되고, 넓다고 늘어뜨리면 단계 사이가 멀어져 한 줄로 안 읽힌다.
|
|
22
|
+
*
|
|
23
|
+
* 칸마다 최소 폭을 주고, 그 폭도 안 되면 이 안에서 가로로 넘긴다. 담는 화면은 건드릴 것이 없다.
|
|
24
|
+
*/
|
|
13
25
|
:host {
|
|
14
|
-
display:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
padding: 10px;
|
|
18
|
-
justify-content: center;
|
|
19
|
-
align-items: center;
|
|
26
|
+
display: block;
|
|
27
|
+
padding: 10px 0;
|
|
28
|
+
overflow-x: auto;
|
|
20
29
|
|
|
21
30
|
--md-icon-size: 3em;
|
|
22
|
-
color: var(--
|
|
23
|
-
background-color: var(--md-sys-color-surface-variant);
|
|
31
|
+
color: var(--ui-ink, #17242c);
|
|
24
32
|
}
|
|
25
33
|
|
|
34
|
+
/*
|
|
35
|
+
* ── 칸은 모두 같은 폭이다 (2026-09-06) ─────────────────────────────
|
|
36
|
+
* approval-line-brief 와 같은 이유다. 이음선을 자기 폭의 50% 로 옆 칸 가운데까지 늘리는데,
|
|
37
|
+
* 그 계산은 칸이 모두 같은 폭일 때만 맞는다. 내용 폭으로 두었더니 「나」는 28px,
|
|
38
|
+
* 「QUALITY-MANAGER」는 140px 이 되어 선이 앞 칸의 가운데를 지나쳤다(실측).
|
|
39
|
+
*
|
|
40
|
+
* grid 로 균등하게 나눈다. 이름은 자기 칸 안에서 줄바꿈하고, 상자는 자기 글자만큼만 넓다.
|
|
41
|
+
* 좁은 팝업에서 4단계도 가로로 넘치지 않는다.
|
|
42
|
+
*/
|
|
26
43
|
ol {
|
|
27
|
-
|
|
44
|
+
list-style: none;
|
|
28
45
|
margin: 0;
|
|
29
46
|
padding: 0;
|
|
30
|
-
display:
|
|
31
|
-
|
|
32
|
-
|
|
47
|
+
display: grid;
|
|
48
|
+
grid-auto-flow: column;
|
|
49
|
+
grid-auto-columns: minmax(96px, 1fr);
|
|
50
|
+
align-items: start;
|
|
51
|
+
min-width: 100%;
|
|
52
|
+
width: max-content;
|
|
33
53
|
}
|
|
34
54
|
|
|
35
55
|
li {
|
|
56
|
+
position: relative;
|
|
57
|
+
min-width: 0;
|
|
58
|
+
padding: 0 4px;
|
|
36
59
|
text-align: center;
|
|
37
|
-
font-size: var(--
|
|
60
|
+
font-size: var(--ui-t-small, 11.5px);
|
|
61
|
+
color: var(--ui-muted, #57676f);
|
|
62
|
+
line-height: 1.35;
|
|
63
|
+
overflow-wrap: anywhere;
|
|
38
64
|
}
|
|
39
65
|
|
|
66
|
+
/*
|
|
67
|
+
* 앞 칸과 잇는 선. 칸이 균등하므로 앞 칸의 가운데는 -50% 자리다. 상자 폭은 글자마다 다르므로
|
|
68
|
+
* 넉넉히 비워 둔다 — 상자에 닿는 것보다 조금 떨어지는 편이 낫다.
|
|
69
|
+
*/
|
|
70
|
+
/*
|
|
71
|
+
* 색은 「어디까지 왔나」를 말한다. 지나온 구간은 강조색, 아직 오지 않은 구간은 흐리게.
|
|
72
|
+
*
|
|
73
|
+
* CSS 는 「현재보다 앞」을 고를 수 없다(형제 선택자는 뒤로만 간다). 그래서 **기본을
|
|
74
|
+
* 강조색**으로 두고, 현재 뒤에 오는 것만 흐리게 되돌린다.
|
|
75
|
+
*/
|
|
40
76
|
li:before {
|
|
41
77
|
content: '';
|
|
42
|
-
height: 2px;
|
|
43
|
-
width: 25px;
|
|
44
|
-
display: block;
|
|
45
78
|
position: absolute;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
79
|
+
top: 10px;
|
|
80
|
+
right: calc(50% + 14px);
|
|
81
|
+
left: calc(-50% + 14px);
|
|
82
|
+
height: 2px;
|
|
83
|
+
background-color: var(--ui-accent, #00727e);
|
|
50
84
|
}
|
|
51
85
|
|
|
52
86
|
li:first-child:before {
|
|
53
87
|
display: none;
|
|
54
88
|
}
|
|
55
89
|
|
|
90
|
+
.who {
|
|
91
|
+
display: block;
|
|
92
|
+
line-height: 1.35;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/*
|
|
96
|
+
* The step marker is the step number, as in approval-line-brief.
|
|
97
|
+
*
|
|
98
|
+
* It used to hold how the approver was chosen — a filled pill reading 역할 (role). Two things
|
|
99
|
+
* were wrong with that. The step number vanished, so the detail view carried less than the
|
|
100
|
+
* summary the user opened it from: the ribbon reads 1 나 · 2 QUALITY-MANAGER, this one read
|
|
101
|
+
* 나 · 역할 QUALITY-MANAGER. And the pill outweighed the name, so "role" was read before
|
|
102
|
+
* "QUALITY-MANAGER" even though the name is what the user came for.
|
|
103
|
+
*
|
|
104
|
+
* How the approver was chosen now sits under the name, in .kind.
|
|
105
|
+
*/
|
|
56
106
|
span {
|
|
57
107
|
display: block;
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
font-size: var(--
|
|
65
|
-
line-height:
|
|
66
|
-
|
|
108
|
+
width: 20px;
|
|
109
|
+
height: 20px;
|
|
110
|
+
margin: 0 auto 4px;
|
|
111
|
+
border-radius: 50%;
|
|
112
|
+
background-color: var(--ui-line-soft, #e6eaed);
|
|
113
|
+
color: var(--ui-faint, #8a959c);
|
|
114
|
+
font-size: var(--ui-t-small, 11.5px);
|
|
115
|
+
line-height: 20px;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/*
|
|
119
|
+
* The submitter is where the line starts, not a step in it.
|
|
120
|
+
*
|
|
121
|
+
* It used to carry the number 1, which pushed every approver one place along: the popup read
|
|
122
|
+
* 결재선번 1 next to a diagram lighting up step 2. The server counts the 1-based position in
|
|
123
|
+
* approvalLine — submitter excluded, references included (see
|
|
124
|
+
* worklist/server/controllers/activity-approval/approval-line.ts). The diagram now counts the
|
|
125
|
+
* same thing.
|
|
126
|
+
*
|
|
127
|
+
* A filled dot with no digit: the line starts here, and there is no turn to number.
|
|
128
|
+
*/
|
|
129
|
+
[origin] span {
|
|
130
|
+
font-size: 0;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/* A reference has no turn to take, so it gets no number — an empty ring holds the place. */
|
|
134
|
+
[reference] span {
|
|
135
|
+
background-color: transparent;
|
|
136
|
+
border: 2px dashed var(--ui-line, #d5dce0);
|
|
137
|
+
box-sizing: border-box;
|
|
67
138
|
}
|
|
68
139
|
|
|
69
140
|
[approver][current] span {
|
|
70
|
-
background-color: var(--
|
|
71
|
-
|
|
72
|
-
|
|
141
|
+
background-color: var(--ui-accent, #00727e);
|
|
142
|
+
color: var(--ui-on-accent, #ffffff);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/* How this approver was chosen — role, self, supervisor. Secondary to who they are. */
|
|
146
|
+
.kind {
|
|
147
|
+
display: block;
|
|
148
|
+
margin-top: 2px;
|
|
149
|
+
font-size: var(--ui-t-micro, 11px);
|
|
150
|
+
color: var(--ui-faint, #8a959c);
|
|
73
151
|
}
|
|
74
152
|
|
|
75
153
|
[approver][current] {
|
|
76
154
|
font-weight: bold;
|
|
77
155
|
}
|
|
78
156
|
|
|
157
|
+
/* 아직 오지 않은 단계 — 흐리게 둔다. 검은 상자를 얹으면 지나온 단계보다 무거워 보인다. */
|
|
158
|
+
[approver][current] ~ li {
|
|
159
|
+
color: var(--ui-faint, #8a959c);
|
|
160
|
+
}
|
|
161
|
+
|
|
79
162
|
[approver][current] ~ li span {
|
|
80
|
-
|
|
81
|
-
border-color: transparent;
|
|
82
|
-
color: var(--md-sys-color-on-primary);
|
|
163
|
+
color: var(--ui-faint, #8a959c);
|
|
83
164
|
}
|
|
84
165
|
|
|
85
166
|
[approver][current] ~ li:before {
|
|
86
|
-
background-color:
|
|
87
|
-
|
|
167
|
+
background-color: var(--ui-line, #d5dce0);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/* 현재가 없으면(아직 아무 단계도 아니면) 전부 흐리다 — 지나온 구간이 없다. */
|
|
171
|
+
:host([no-current]) li:before {
|
|
172
|
+
background-color: var(--ui-line, #d5dce0);
|
|
173
|
+
}
|
|
174
|
+
/*
|
|
175
|
+
* 참조 — 결재와 다르게, 그리고 **더 조용하게** 그린다. 결재는 길을 막는 자리이고 참조는 알리는
|
|
176
|
+
* 자리다. 같은 무게로 그리면 결재선을 짠 사람이 몇 명의 승인이 필요한지 잘못 읽는다.
|
|
177
|
+
*/
|
|
178
|
+
li[approver][reference] {
|
|
179
|
+
color: var(--ui-muted, #57676f);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
li[approver][reference] em {
|
|
183
|
+
margin-left: 4px;
|
|
184
|
+
padding: 0 5px;
|
|
185
|
+
border: 1px solid var(--ui-line, #d5dce0);
|
|
186
|
+
border-radius: 999px;
|
|
187
|
+
font-size: var(--ui-t-small, 11.5px);
|
|
188
|
+
font-style: normal;
|
|
88
189
|
}
|
|
190
|
+
|
|
89
191
|
`
|
|
90
192
|
]; }
|
|
193
|
+
updated(changes) {
|
|
194
|
+
/* 현재 단계를 못 받았으면 지나온 구간이 없다 — 이음선을 전부 흐리게 둔다. */
|
|
195
|
+
this.toggleAttribute('no-current', !(Number(this.current) > 0));
|
|
196
|
+
}
|
|
91
197
|
render() {
|
|
92
198
|
const items = this.model || [];
|
|
93
199
|
return html `
|
|
94
200
|
<ol>
|
|
95
|
-
${this.model
|
|
201
|
+
${this.model
|
|
202
|
+
? html ` <li approver origin>
|
|
203
|
+
<span></span>
|
|
204
|
+
<div class="who">${i18next.t('label.Myself')}</div>
|
|
205
|
+
</li>`
|
|
206
|
+
: html ``}
|
|
96
207
|
${items.map((item, order) => this.renderItem(item, order + 1))}
|
|
97
208
|
</ol>
|
|
98
209
|
`;
|
|
99
210
|
}
|
|
211
|
+
/**
|
|
212
|
+
* One step of the approval line.
|
|
213
|
+
*
|
|
214
|
+
* A reference is drawn differently from an approval. Drawn the same it reads as "this person has
|
|
215
|
+
* to approve before it moves on", which a reference does not do — whoever assembles the line has
|
|
216
|
+
* to be able to see here what they put in.
|
|
217
|
+
*
|
|
218
|
+
* It carries no number either: a reference takes no turn, so there is no "third" for it to be.
|
|
219
|
+
*
|
|
220
|
+
* The number is the 1-based position in approvalLine, which is exactly what the server means by
|
|
221
|
+
* `order`: submitter excluded, references included, array position as it stands (see
|
|
222
|
+
* worklist/server/controllers/activity-approval/approval-line.ts). A reference holding a slot
|
|
223
|
+
* without showing a digit is therefore right, not a gap.
|
|
224
|
+
*/
|
|
100
225
|
renderItem(item, order) {
|
|
101
226
|
const { type, approver } = item;
|
|
102
227
|
const { name } = approver || {
|
|
@@ -104,10 +229,21 @@ let ApprovalLineView = class ApprovalLineView extends localize(i18next)(LitEleme
|
|
|
104
229
|
? i18next.t(`label.${type}`)
|
|
105
230
|
: ''
|
|
106
231
|
};
|
|
232
|
+
const reference = isReferenceStep(item);
|
|
233
|
+
/*
|
|
234
|
+
* The name is who this is; the kind is how they were chosen (self, supervisor, role). Choosing
|
|
235
|
+
* by self makes the two the same word, and the screen printed 나 twice, stacked. When they
|
|
236
|
+
* match, say it once.
|
|
237
|
+
*/
|
|
238
|
+
const kind = i18next.t('label.' + type);
|
|
239
|
+
const shown = name || kind;
|
|
240
|
+
const note = name && name !== kind ? kind : '';
|
|
107
241
|
return html `
|
|
108
|
-
<li approver ?current=${this.current == order}>
|
|
109
|
-
<span>${
|
|
110
|
-
|
|
242
|
+
<li approver ?current=${this.current == order} ?reference=${reference}>
|
|
243
|
+
<span>${reference ? '' : order}</span>
|
|
244
|
+
<div class="who">${shown}</div>
|
|
245
|
+
${note ? html `<div class="kind">${note}</div>` : ''}
|
|
246
|
+
${reference ? html `<div><em>${i18next.t('label.participation-reference')}</em></div>` : ''}
|
|
111
247
|
</li>
|
|
112
248
|
`;
|
|
113
249
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"approval-line-view.js","sourceRoot":"","sources":["../../client/component/approval-line-view.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAkB,MAAM,KAAK,CAAA;AAC3D,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAS,MAAM,mBAAmB,CAAA;AAElE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAEjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAGlD,IAAM,gBAAgB,GAAtB,MAAM,gBAAiB,SAAQ,QAAQ,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC;IAA5D;;QAmFuB,YAAO,GAAY,CAAC,CAAC,CAAA;IA8BnD,CAAC;aAhHQ,WAAM,GAAG;QACd,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA6EF;KACF,AA/EY,CA+EZ;IAKD,MAAM;QACJ,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAA;QAE9B,OAAO,IAAI,CAAA;;UAEL,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAA,gCAAgC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAA,EAAE;UAC3F,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;;KAEjE,CAAA;IACH,CAAC;IAED,UAAU,CAAC,IAAsB,EAAE,KAAa;QAC9C,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAA;QAC/B,MAAM,EAAE,IAAI,EAAE,GAAG,QAAQ,IAAI;YAC3B,IAAI,EAAE,CAAC,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,CAAC,YAAY,EAAE,mBAAmB,CAAC,YAAY,CAAC,CAAC,QAAQ,CAC7G,IAAK,CACN;gBACC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC;gBAC5B,CAAC,CAAC,EAAE;SACP,CAAA;QAED,OAAO,IAAI,CAAA;8BACe,IAAI,CAAC,OAAO,IAAI,KAAK;gBACnC,OAAO,CAAC,CAAC,CAAC,QAAQ,GAAG,IAAI,CAAC;UAChC,IAAI;;KAET,CAAA;IACH,CAAC;;AA9B0B;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;;+CAA2B;AACzB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;iDAAsB;AAnFtC,gBAAgB;IAD5B,aAAa,CAAC,oBAAoB,CAAC;GACvB,gBAAgB,CAiH5B","sourcesContent":["import { css, html, LitElement, TemplateResult } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\n\nimport { i18next, localize } from '@operato/i18n'\nimport { ApprovalLineItem } from '../types/approval-line'\nimport { OrgMemberTargetType } from '../types/org-member'\n\n@customElement('approval-line-view')\nexport class ApprovalLineView extends localize(i18next)(LitElement) {\n static styles = [\n css`\n :host {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n padding: 10px;\n justify-content: center;\n align-items: center;\n\n --md-icon-size: 3em;\n color: var(--md-sys-color-on-surface);\n background-color: var(--md-sys-color-surface-variant);\n }\n\n ol {\n position: relative;\n margin: 0;\n padding: 0;\n display: flex;\n gap: 25px;\n list-style-type: none;\n }\n\n li {\n text-align: center;\n font-size: var(--fontsize-default);\n }\n\n li:before {\n content: '';\n height: 2px;\n width: 25px;\n display: block;\n position: absolute;\n margin-left: -25px;\n margin-top: 10px;\n background-color: var(--md-sys-color-primary);\n opacity: 0.4;\n }\n\n li:first-child:before {\n display: none;\n }\n\n span {\n display: block;\n margin: auto;\n margin-bottom: var(--spacing-small);\n color: var(--md-sys-color-primary);\n background-color: var(--md-sys-color-surface-variant);\n border-radius: 5px;\n border: 2px solid var(--md-sys-color-primary);\n font-size: var(--fontsize-small);\n line-height: 1;\n padding: var(--spacing-small) var(--spacing-medium);\n }\n\n [approver][current] span {\n background-color: var(--md-sys-color-primary);\n border-color: var(--md-sys-color-primary);\n color: var(--md-sys-color-on-primary);\n }\n\n [approver][current] {\n font-weight: bold;\n }\n\n [approver][current] ~ li span {\n background-color: rgba(0, 0, 0, 0.5);\n border-color: transparent;\n color: var(--md-sys-color-on-primary);\n }\n\n [approver][current] ~ li:before {\n background-color: rgba(0, 0, 0, 0.4);\n opacity: 1;\n }\n `\n ]\n\n @property({ type: Array }) model?: ApprovalLineItem[]\n @property({ type: Number }) current?: number = -1\n\n render() {\n const items = this.model || []\n\n return html`\n <ol>\n ${this.model ? html` <li approver><span>ME</span>${i18next.t('label.myself')}</li> ` : html``}\n ${items.map((item, order) => this.renderItem(item, order + 1))}\n </ol>\n `\n }\n\n renderItem(item: ApprovalLineItem, order: number): TemplateResult {\n const { type, approver } = item\n const { name } = approver || {\n name: [OrgMemberTargetType.Myself, OrgMemberTargetType.MySupervisor, OrgMemberTargetType.MyDepartment].includes(\n type!\n )\n ? i18next.t(`label.${type}`)\n : ''\n }\n\n return html`\n <li approver ?current=${this.current == order}>\n <span>${i18next.t('label.' + type)}</span>\n ${name}\n </li>\n `\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"approval-line-view.js","sourceRoot":"","sources":["../../client/component/approval-line-view.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, LitElement, TemplateResult } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\n\nimport { i18next, localize } from '@operato/i18n'\nimport { ApprovalLineItem, isReferenceStep } from '../types/approval-line'\nimport { OrgMemberTargetType } from '../types/org-member'\n\n@customElement('approval-line-view')\nexport class ApprovalLineView extends localize(i18next)(LitElement) {\n static styles = [\n css`\n /*\n * 면을 갖지 않는다 — 담는 쪽(worklist 의 곁 패널)이 면을 준다. 회색 면을 스스로 칠하면\n * 패널 안에 회색 덩어리가 생긴다.\n */\n /*\n * 이 부품은 넓은 자리(결재선 편집기 · 선택기)와 좁은 자리(worklist 의 정보 팝업)에 함께 쓰인다.\n * 그래서 **어느 폭에서도 무너지지 않아야** 한다 — 좁다고 칸을 짜부라뜨리면 이름이 글자마다\n * 줄바꿈되고, 넓다고 늘어뜨리면 단계 사이가 멀어져 한 줄로 안 읽힌다.\n *\n * 칸마다 최소 폭을 주고, 그 폭도 안 되면 이 안에서 가로로 넘긴다. 담는 화면은 건드릴 것이 없다.\n */\n :host {\n display: block;\n padding: 10px 0;\n overflow-x: auto;\n\n --md-icon-size: 3em;\n color: var(--ui-ink, #17242c);\n }\n\n /*\n * ── 칸은 모두 같은 폭이다 (2026-09-06) ─────────────────────────────\n * approval-line-brief 와 같은 이유다. 이음선을 자기 폭의 50% 로 옆 칸 가운데까지 늘리는데,\n * 그 계산은 칸이 모두 같은 폭일 때만 맞는다. 내용 폭으로 두었더니 「나」는 28px,\n * 「QUALITY-MANAGER」는 140px 이 되어 선이 앞 칸의 가운데를 지나쳤다(실측).\n *\n * grid 로 균등하게 나눈다. 이름은 자기 칸 안에서 줄바꿈하고, 상자는 자기 글자만큼만 넓다.\n * 좁은 팝업에서 4단계도 가로로 넘치지 않는다.\n */\n ol {\n list-style: none;\n margin: 0;\n padding: 0;\n display: grid;\n grid-auto-flow: column;\n grid-auto-columns: minmax(96px, 1fr);\n align-items: start;\n min-width: 100%;\n width: max-content;\n }\n\n li {\n position: relative;\n min-width: 0;\n padding: 0 4px;\n text-align: center;\n font-size: var(--ui-t-small, 11.5px);\n color: var(--ui-muted, #57676f);\n line-height: 1.35;\n overflow-wrap: anywhere;\n }\n\n /*\n * 앞 칸과 잇는 선. 칸이 균등하므로 앞 칸의 가운데는 -50% 자리다. 상자 폭은 글자마다 다르므로\n * 넉넉히 비워 둔다 — 상자에 닿는 것보다 조금 떨어지는 편이 낫다.\n */\n /*\n * 색은 「어디까지 왔나」를 말한다. 지나온 구간은 강조색, 아직 오지 않은 구간은 흐리게.\n *\n * CSS 는 「현재보다 앞」을 고를 수 없다(형제 선택자는 뒤로만 간다). 그래서 **기본을\n * 강조색**으로 두고, 현재 뒤에 오는 것만 흐리게 되돌린다.\n */\n li:before {\n content: '';\n position: absolute;\n top: 10px;\n right: calc(50% + 14px);\n left: calc(-50% + 14px);\n height: 2px;\n background-color: var(--ui-accent, #00727e);\n }\n\n li:first-child:before {\n display: none;\n }\n\n .who {\n display: block;\n line-height: 1.35;\n }\n\n /*\n * The step marker is the step number, as in approval-line-brief.\n *\n * It used to hold how the approver was chosen — a filled pill reading 역할 (role). Two things\n * were wrong with that. The step number vanished, so the detail view carried less than the\n * summary the user opened it from: the ribbon reads 1 나 · 2 QUALITY-MANAGER, this one read\n * 나 · 역할 QUALITY-MANAGER. And the pill outweighed the name, so \"role\" was read before\n * \"QUALITY-MANAGER\" even though the name is what the user came for.\n *\n * How the approver was chosen now sits under the name, in .kind.\n */\n span {\n display: block;\n width: 20px;\n height: 20px;\n margin: 0 auto 4px;\n border-radius: 50%;\n background-color: var(--ui-line-soft, #e6eaed);\n color: var(--ui-faint, #8a959c);\n font-size: var(--ui-t-small, 11.5px);\n line-height: 20px;\n }\n\n /*\n * The submitter is where the line starts, not a step in it.\n *\n * It used to carry the number 1, which pushed every approver one place along: the popup read\n * 결재선번 1 next to a diagram lighting up step 2. The server counts the 1-based position in\n * approvalLine — submitter excluded, references included (see\n * worklist/server/controllers/activity-approval/approval-line.ts). The diagram now counts the\n * same thing.\n *\n * A filled dot with no digit: the line starts here, and there is no turn to number.\n */\n [origin] span {\n font-size: 0;\n }\n\n /* A reference has no turn to take, so it gets no number — an empty ring holds the place. */\n [reference] span {\n background-color: transparent;\n border: 2px dashed var(--ui-line, #d5dce0);\n box-sizing: border-box;\n }\n\n [approver][current] span {\n background-color: var(--ui-accent, #00727e);\n color: var(--ui-on-accent, #ffffff);\n }\n\n /* How this approver was chosen — role, self, supervisor. Secondary to who they are. */\n .kind {\n display: block;\n margin-top: 2px;\n font-size: var(--ui-t-micro, 11px);\n color: var(--ui-faint, #8a959c);\n }\n\n [approver][current] {\n font-weight: bold;\n }\n\n /* 아직 오지 않은 단계 — 흐리게 둔다. 검은 상자를 얹으면 지나온 단계보다 무거워 보인다. */\n [approver][current] ~ li {\n color: var(--ui-faint, #8a959c);\n }\n\n [approver][current] ~ li span {\n color: var(--ui-faint, #8a959c);\n }\n\n [approver][current] ~ li:before {\n background-color: var(--ui-line, #d5dce0);\n }\n\n /* 현재가 없으면(아직 아무 단계도 아니면) 전부 흐리다 — 지나온 구간이 없다. */\n :host([no-current]) li:before {\n background-color: var(--ui-line, #d5dce0);\n }\n /*\n * 참조 — 결재와 다르게, 그리고 **더 조용하게** 그린다. 결재는 길을 막는 자리이고 참조는 알리는\n * 자리다. 같은 무게로 그리면 결재선을 짠 사람이 몇 명의 승인이 필요한지 잘못 읽는다.\n */\n li[approver][reference] {\n color: var(--ui-muted, #57676f);\n }\n\n li[approver][reference] em {\n margin-left: 4px;\n padding: 0 5px;\n border: 1px solid var(--ui-line, #d5dce0);\n border-radius: 999px;\n font-size: var(--ui-t-small, 11.5px);\n font-style: normal;\n }\n\n `\n ]\n\n @property({ type: Array }) model?: ApprovalLineItem[]\n @property({ type: Number }) current?: number = -1\n\n updated(changes) {\n /* 현재 단계를 못 받았으면 지나온 구간이 없다 — 이음선을 전부 흐리게 둔다. */\n this.toggleAttribute('no-current', !(Number(this.current) > 0))\n }\n\n render() {\n const items = this.model || []\n\n return html`\n <ol>\n ${this.model\n ? html` <li approver origin>\n <span></span>\n <div class=\"who\">${i18next.t('label.Myself')}</div>\n </li>`\n : html``}\n ${items.map((item, order) => this.renderItem(item, order + 1))}\n </ol>\n `\n }\n\n /**\n * One step of the approval line.\n *\n * A reference is drawn differently from an approval. Drawn the same it reads as \"this person has\n * to approve before it moves on\", which a reference does not do — whoever assembles the line has\n * to be able to see here what they put in.\n *\n * It carries no number either: a reference takes no turn, so there is no \"third\" for it to be.\n *\n * The number is the 1-based position in approvalLine, which is exactly what the server means by\n * `order`: submitter excluded, references included, array position as it stands (see\n * worklist/server/controllers/activity-approval/approval-line.ts). A reference holding a slot\n * without showing a digit is therefore right, not a gap.\n */\n renderItem(item: ApprovalLineItem, order: number): TemplateResult {\n const { type, approver } = item\n const { name } = approver || {\n name: [OrgMemberTargetType.Myself, OrgMemberTargetType.MySupervisor, OrgMemberTargetType.MyDepartment].includes(\n type!\n )\n ? i18next.t(`label.${type}`)\n : ''\n }\n\n const reference = isReferenceStep(item)\n\n /*\n * The name is who this is; the kind is how they were chosen (self, supervisor, role). Choosing\n * by self makes the two the same word, and the screen printed 나 twice, stacked. When they\n * match, say it once.\n */\n const kind = i18next.t('label.' + type)\n const shown = name || kind\n const note = name && name !== kind ? kind : ''\n\n return html`\n <li approver ?current=${this.current == order} ?reference=${reference}>\n <span>${reference ? '' : order}</span>\n <div class=\"who\">${shown}</div>\n ${note ? html`<div class=\"kind\">${note}</div>` : ''}\n ${reference ? html`<div><em>${i18next.t('label.participation-reference')}</em></div>` : ''}\n </li>\n `\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 { AssigneesEditor } from './assignees-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 { AssigneesEditor } from './assignees-editor';
|
|
9
11
|
/**
|
|
@@ -17,7 +19,25 @@ let AssigneesEditorPopup = class AssigneesEditorPopup 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 AssigneesEditorPopup = class AssigneesEditorPopup extends localize(i18next)(
|
|
|
39
59
|
}}
|
|
40
60
|
></assignees-editor>
|
|
41
61
|
|
|
42
|
-
<div class="
|
|
43
|
-
<button @click=${this.onEmpty.bind(this)}>
|
|
44
|
-
|
|
45
|
-
</button>
|
|
46
|
-
<
|
|
47
|
-
<button @click=${this.
|
|
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":"assignees-editor-popup.js","sourceRoot":"","sources":["../../client/component/assignees-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;
|
|
1
|
+
{"version":3,"file":"assignees-editor-popup.js","sourceRoot":"","sources":["../../client/component/assignees-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,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAGpD;;GAEG;AAEI,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,QAAQ,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC;IAAhE;;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;;mDAAuB;AAErB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;6DAA0D;AAC1D;IAA1B,KAAK,CAAC,kBAAkB,CAAC;8BAAU,eAAe;IAEnD,wEAAwE;;oDAFrB;AAtCxC,oBAAoB;IADhC,aAAa,CAAC,wBAAwB,CAAC;GAC3B,oBAAoB,CAgFhC","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 { AssigneesEditor } from './assignees-editor'\nimport { AssigneeItem } from '../types/org-member'\n\n/**\n * 결재선의 각 결재자 리스트를 편집한다.\n */\n@customElement('assignees-editor-popup')\nexport class AssigneesEditorPopup 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 assignees-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('assignees-editor') editor!: AssigneesEditor\n\n /* this.value는 (원인불명으로) 값이 Reset되므로, 변화값을 유지하도록 별도로 changedValue를 사용함 */\n private changedValue?: AssigneeItem[] = this.value\n\n render() {\n return html`\n <assignees-editor\n .value=${this.value}\n @change=${(e: CustomEvent) => {\n this.changedValue = [...e.detail]\n }}\n ></assignees-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"]}
|