@things-factory/ops-master 10.0.18
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/.dockerignore +31 -0
- package/dist-client/index.d.ts +1 -0
- package/dist-client/index.js +2 -0
- package/dist-client/index.js.map +1 -0
- package/dist-client/pages/master-axes.d.ts +33 -0
- package/dist-client/pages/master-axes.js +176 -0
- package/dist-client/pages/master-axes.js.map +1 -0
- package/dist-client/pages/master-list.d.ts +68 -0
- package/dist-client/pages/master-list.js +267 -0
- package/dist-client/pages/master-list.js.map +1 -0
- package/dist-client/route.d.ts +1 -0
- package/dist-client/route.js +8 -0
- package/dist-client/route.js.map +1 -0
- package/dist-client/tsconfig.tsbuildinfo +1 -0
- package/dist-server/index.d.ts +1 -0
- package/dist-server/index.js +5 -0
- package/dist-server/index.js.map +1 -0
- package/dist-server/service/asset/asset-lifecycle.d.ts +83 -0
- package/dist-server/service/asset/asset-lifecycle.js +99 -0
- package/dist-server/service/asset/asset-lifecycle.js.map +1 -0
- package/dist-server/service/asset/asset-master-resolver.d.ts +44 -0
- package/dist-server/service/asset/asset-master-resolver.js +140 -0
- package/dist-server/service/asset/asset-master-resolver.js.map +1 -0
- package/dist-server/service/asset/asset-master.d.ts +21 -0
- package/dist-server/service/asset/asset-master.js +25 -0
- package/dist-server/service/asset/asset-master.js.map +1 -0
- package/dist-server/service/asset/asset-query.d.ts +8 -0
- package/dist-server/service/asset/asset-query.js +50 -0
- package/dist-server/service/asset/asset-query.js.map +1 -0
- package/dist-server/service/asset/index.d.ts +6 -0
- package/dist-server/service/asset/index.js +10 -0
- package/dist-server/service/asset/index.js.map +1 -0
- package/dist-server/service/asset/physical-asset-class.d.ts +34 -0
- package/dist-server/service/asset/physical-asset-class.js +104 -0
- package/dist-server/service/asset/physical-asset-class.js.map +1 -0
- package/dist-server/service/asset/physical-asset.d.ts +53 -0
- package/dist-server/service/asset/physical-asset.js +123 -0
- package/dist-server/service/asset/physical-asset.js.map +1 -0
- package/dist-server/service/equipment/equipment-class.d.ts +34 -0
- package/dist-server/service/equipment/equipment-class.js +104 -0
- package/dist-server/service/equipment/equipment-class.js.map +1 -0
- package/dist-server/service/equipment/equipment-master-resolver.d.ts +60 -0
- package/dist-server/service/equipment/equipment-master-resolver.js +200 -0
- package/dist-server/service/equipment/equipment-master-resolver.js.map +1 -0
- package/dist-server/service/equipment/equipment-master.d.ts +29 -0
- package/dist-server/service/equipment/equipment-master.js +36 -0
- package/dist-server/service/equipment/equipment-master.js.map +1 -0
- package/dist-server/service/equipment/equipment-query.d.ts +8 -0
- package/dist-server/service/equipment/equipment-query.js +50 -0
- package/dist-server/service/equipment/equipment-query.js.map +1 -0
- package/dist-server/service/equipment/equipment.d.ts +45 -0
- package/dist-server/service/equipment/equipment.js +133 -0
- package/dist-server/service/equipment/equipment.js.map +1 -0
- package/dist-server/service/equipment/index.d.ts +8 -0
- package/dist-server/service/equipment/index.js +12 -0
- package/dist-server/service/equipment/index.js.map +1 -0
- package/dist-server/service/equipment/state-period-rules.d.ts +76 -0
- package/dist-server/service/equipment/state-period-rules.js +88 -0
- package/dist-server/service/equipment/state-period-rules.js.map +1 -0
- package/dist-server/service/equipment/stop-reason-query.d.ts +11 -0
- package/dist-server/service/equipment/stop-reason-query.js +39 -0
- package/dist-server/service/equipment/stop-reason-query.js.map +1 -0
- package/dist-server/service/equipment/stop-reason.d.ts +58 -0
- package/dist-server/service/equipment/stop-reason.js +114 -0
- package/dist-server/service/equipment/stop-reason.js.map +1 -0
- package/dist-server/service/index.d.ts +46 -0
- package/dist-server/service/index.js +80 -0
- package/dist-server/service/index.js.map +1 -0
- package/dist-server/service/location/index.d.ts +5 -0
- package/dist-server/service/location/index.js +9 -0
- package/dist-server/service/location/index.js.map +1 -0
- package/dist-server/service/location/location-master-resolver.d.ts +28 -0
- package/dist-server/service/location/location-master-resolver.js +80 -0
- package/dist-server/service/location/location-master-resolver.js.map +1 -0
- package/dist-server/service/location/location-master.d.ts +24 -0
- package/dist-server/service/location/location-master.js +27 -0
- package/dist-server/service/location/location-master.js.map +1 -0
- package/dist-server/service/location/location-query.d.ts +7 -0
- package/dist-server/service/location/location-query.js +41 -0
- package/dist-server/service/location/location-query.js.map +1 -0
- package/dist-server/service/location/operational-location.d.ts +52 -0
- package/dist-server/service/location/operational-location.js +132 -0
- package/dist-server/service/location/operational-location.js.map +1 -0
- package/dist-server/service/master-axis.d.ts +29 -0
- package/dist-server/service/master-axis.js +39 -0
- package/dist-server/service/master-axis.js.map +1 -0
- package/dist-server/service/master-crud.d.ts +44 -0
- package/dist-server/service/master-crud.js +73 -0
- package/dist-server/service/master-crud.js.map +1 -0
- package/dist-server/service/master-list.d.ts +12 -0
- package/dist-server/service/master-list.js +24 -0
- package/dist-server/service/master-list.js.map +1 -0
- package/dist-server/service/material/index.d.ts +6 -0
- package/dist-server/service/material/index.js +10 -0
- package/dist-server/service/material/index.js.map +1 -0
- package/dist-server/service/material/material-class.d.ts +34 -0
- package/dist-server/service/material/material-class.js +104 -0
- package/dist-server/service/material/material-class.js.map +1 -0
- package/dist-server/service/material/material-definition.d.ts +42 -0
- package/dist-server/service/material/material-definition.js +112 -0
- package/dist-server/service/material/material-definition.js.map +1 -0
- package/dist-server/service/material/material-master-resolver.d.ts +44 -0
- package/dist-server/service/material/material-master-resolver.js +140 -0
- package/dist-server/service/material/material-master-resolver.js.map +1 -0
- package/dist-server/service/material/material-master.d.ts +9 -0
- package/dist-server/service/material/material-master.js +24 -0
- package/dist-server/service/material/material-master.js.map +1 -0
- package/dist-server/service/material/material-query.d.ts +8 -0
- package/dist-server/service/material/material-query.js +50 -0
- package/dist-server/service/material/material-query.js.map +1 -0
- package/dist-server/service/operation/index.d.ts +5 -0
- package/dist-server/service/operation/index.js +9 -0
- package/dist-server/service/operation/index.js.map +1 -0
- package/dist-server/service/operation/operation-definition.d.ts +52 -0
- package/dist-server/service/operation/operation-definition.js +142 -0
- package/dist-server/service/operation/operation-definition.js.map +1 -0
- package/dist-server/service/operation/operation-master-resolver.d.ts +28 -0
- package/dist-server/service/operation/operation-master-resolver.js +80 -0
- package/dist-server/service/operation/operation-master-resolver.js.map +1 -0
- package/dist-server/service/operation/operation-master.d.ts +21 -0
- package/dist-server/service/operation/operation-master.js +28 -0
- package/dist-server/service/operation/operation-master.js.map +1 -0
- package/dist-server/service/operation/operation-query.d.ts +7 -0
- package/dist-server/service/operation/operation-query.js +41 -0
- package/dist-server/service/operation/operation-query.js.map +1 -0
- package/dist-server/service/personnel/index.d.ts +6 -0
- package/dist-server/service/personnel/index.js +10 -0
- package/dist-server/service/personnel/index.js.map +1 -0
- package/dist-server/service/personnel/person.d.ts +51 -0
- package/dist-server/service/personnel/person.js +119 -0
- package/dist-server/service/personnel/person.js.map +1 -0
- package/dist-server/service/personnel/personnel-class.d.ts +54 -0
- package/dist-server/service/personnel/personnel-class.js +114 -0
- package/dist-server/service/personnel/personnel-class.js.map +1 -0
- package/dist-server/service/personnel/personnel-master-resolver.d.ts +44 -0
- package/dist-server/service/personnel/personnel-master-resolver.js +140 -0
- package/dist-server/service/personnel/personnel-master-resolver.js.map +1 -0
- package/dist-server/service/personnel/personnel-master.d.ts +39 -0
- package/dist-server/service/personnel/personnel-master.js +34 -0
- package/dist-server/service/personnel/personnel-master.js.map +1 -0
- package/dist-server/service/personnel/personnel-query.d.ts +21 -0
- package/dist-server/service/personnel/personnel-query.js +57 -0
- package/dist-server/service/personnel/personnel-query.js.map +1 -0
- package/dist-server/service/personnel/qualification.d.ts +97 -0
- package/dist-server/service/personnel/qualification.js +122 -0
- package/dist-server/service/personnel/qualification.js.map +1 -0
- package/dist-server/service/resource/resource-class.d.ts +25 -0
- package/dist-server/service/resource/resource-class.js +29 -0
- package/dist-server/service/resource/resource-class.js.map +1 -0
- package/dist-server/service/status/axis-stamp.d.ts +16 -0
- package/dist-server/service/status/axis-stamp.js +22 -0
- package/dist-server/service/status/axis-stamp.js.map +1 -0
- package/dist-server/service/status/index.d.ts +3 -0
- package/dist-server/service/status/index.js +7 -0
- package/dist-server/service/status/index.js.map +1 -0
- package/dist-server/service/status/master-status.d.ts +45 -0
- package/dist-server/service/status/master-status.js +129 -0
- package/dist-server/service/status/master-status.js.map +1 -0
- package/dist-server/service/test-spec/index.d.ts +5 -0
- package/dist-server/service/test-spec/index.js +9 -0
- package/dist-server/service/test-spec/index.js.map +1 -0
- package/dist-server/service/test-spec/test-spec-master-resolver.d.ts +28 -0
- package/dist-server/service/test-spec/test-spec-master-resolver.js +80 -0
- package/dist-server/service/test-spec/test-spec-master-resolver.js.map +1 -0
- package/dist-server/service/test-spec/test-spec-master.d.ts +6 -0
- package/dist-server/service/test-spec/test-spec-master.js +18 -0
- package/dist-server/service/test-spec/test-spec-master.js.map +1 -0
- package/dist-server/service/test-spec/test-spec-query.d.ts +7 -0
- package/dist-server/service/test-spec/test-spec-query.js +41 -0
- package/dist-server/service/test-spec/test-spec-query.js.map +1 -0
- package/dist-server/service/test-spec/test-specification.d.ts +41 -0
- package/dist-server/service/test-spec/test-specification.js +106 -0
- package/dist-server/service/test-spec/test-specification.js.map +1 -0
- package/dist-server/tsconfig.tsbuildinfo +1 -0
- package/package.json +50 -0
- package/things-factory.config.js +12 -0
- package/translations/en.json +53 -0
- package/translations/ja.json +1 -0
- package/translations/ko.json +53 -0
- package/translations/ms.json +1 -0
- package/translations/zh.json +1 -0
package/.dockerignore
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
node_modules/
|
|
2
|
+
client/
|
|
3
|
+
server/
|
|
4
|
+
dist-client/
|
|
5
|
+
installer/
|
|
6
|
+
attachments/
|
|
7
|
+
cache/
|
|
8
|
+
logs/
|
|
9
|
+
Dockerfile*
|
|
10
|
+
docker-compose.yml
|
|
11
|
+
db.sqlite
|
|
12
|
+
db*.sqlite
|
|
13
|
+
license.json
|
|
14
|
+
config.development.js
|
|
15
|
+
config.production.js
|
|
16
|
+
!config/config.development.js
|
|
17
|
+
!config/config.production.js
|
|
18
|
+
\_index.html
|
|
19
|
+
|
|
20
|
+
npm-debug.log
|
|
21
|
+
yarn-error.log
|
|
22
|
+
|
|
23
|
+
.env
|
|
24
|
+
.env.local
|
|
25
|
+
.env.production
|
|
26
|
+
.git/
|
|
27
|
+
.gitignore
|
|
28
|
+
.dockerignore
|
|
29
|
+
.vscode/
|
|
30
|
+
.idea/
|
|
31
|
+
.DS_Store
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './pages/master-list';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../client/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA","sourcesContent":["export * from './pages/master-list'\n"]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 마스터 열두 축의 **화면 쪽 선언** — 축마다 다른 것만 적는다.
|
|
3
|
+
*
|
|
4
|
+
* ── 왜 화면이 하나인가 ─────────────────────────────────────────────────────
|
|
5
|
+
* 열두 축의 화면이 하는 일이 같다: 목록을 보이고, 그리드에서 고치고, 저장한다. 화면을 열둘 만들면
|
|
6
|
+
* 규칙 하나를 고칠 때 열두 곳을 고쳐야 하고, 한 곳을 빠뜨리면 그 축만 다르게 동작한다.
|
|
7
|
+
*
|
|
8
|
+
* ── 왜 서버의 축 표와 따로 두나 ────────────────────────────────────────────
|
|
9
|
+
* 서버가 아는 것은 「어느 표에서 읽나 · 무엇으로 찾나」이고, 화면이 아는 것은 「어느 칸을 어떤 모양으로
|
|
10
|
+
* 보이나」다. 서로 다른 물음이라 한 표에 담으면 양쪽 다 지저분해진다. 축의 이름(`key`)만 같게 둔다.
|
|
11
|
+
*/
|
|
12
|
+
export type ColumnType = 'string' | 'number' | 'boolean' | 'date' | 'json' | 'list';
|
|
13
|
+
export interface AxisColumn {
|
|
14
|
+
name: string;
|
|
15
|
+
/** 화면 문구 키. `field.<이것>`. */
|
|
16
|
+
label: string;
|
|
17
|
+
type: ColumnType;
|
|
18
|
+
width?: number;
|
|
19
|
+
/** 고칠 수 없는 칸. 자동으로 붙는 값이 여기 온다. */
|
|
20
|
+
readonly?: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface MasterAxisView {
|
|
23
|
+
key: string;
|
|
24
|
+
/** GraphQL 조회 이름 — 서버가 낸 그대로. */
|
|
25
|
+
query: string;
|
|
26
|
+
/** GraphQL 저장 이름. */
|
|
27
|
+
mutation: string;
|
|
28
|
+
/** 제목 문구 키. `title.<이것>`. */
|
|
29
|
+
title: string;
|
|
30
|
+
columns: AxisColumn[];
|
|
31
|
+
}
|
|
32
|
+
export declare const MASTER_AXIS_VIEWS: readonly MasterAxisView[];
|
|
33
|
+
export declare function masterAxisViewOf(key: string): MasterAxisView | undefined;
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 마스터 열두 축의 **화면 쪽 선언** — 축마다 다른 것만 적는다.
|
|
3
|
+
*
|
|
4
|
+
* ── 왜 화면이 하나인가 ─────────────────────────────────────────────────────
|
|
5
|
+
* 열두 축의 화면이 하는 일이 같다: 목록을 보이고, 그리드에서 고치고, 저장한다. 화면을 열둘 만들면
|
|
6
|
+
* 규칙 하나를 고칠 때 열두 곳을 고쳐야 하고, 한 곳을 빠뜨리면 그 축만 다르게 동작한다.
|
|
7
|
+
*
|
|
8
|
+
* ── 왜 서버의 축 표와 따로 두나 ────────────────────────────────────────────
|
|
9
|
+
* 서버가 아는 것은 「어느 표에서 읽나 · 무엇으로 찾나」이고, 화면이 아는 것은 「어느 칸을 어떤 모양으로
|
|
10
|
+
* 보이나」다. 서로 다른 물음이라 한 표에 담으면 양쪽 다 지저분해진다. 축의 이름(`key`)만 같게 둔다.
|
|
11
|
+
*/
|
|
12
|
+
/** 열두 축이 공통으로 갖는 끝 칸들 — ISA-95 유효 기간. */
|
|
13
|
+
const EFFECTIVE = [
|
|
14
|
+
{ name: 'effectiveStart', label: 'effective-start', type: 'date', width: 150 },
|
|
15
|
+
{ name: 'effectiveEnd', label: 'effective-end', type: 'date', width: 150 }
|
|
16
|
+
];
|
|
17
|
+
/** 이름과 설명은 열두 축이 모두 갖는다. */
|
|
18
|
+
const IDENTITY = [
|
|
19
|
+
{ name: 'name', label: 'name', type: 'string', width: 160 },
|
|
20
|
+
{ name: 'description', label: 'description', type: 'string', width: 200 }
|
|
21
|
+
];
|
|
22
|
+
export const MASTER_AXIS_VIEWS = [
|
|
23
|
+
{
|
|
24
|
+
key: 'personnelClass',
|
|
25
|
+
query: 'personnelClasses',
|
|
26
|
+
mutation: 'updateMultiplePersonnelClass',
|
|
27
|
+
title: 'personnel-class',
|
|
28
|
+
columns: [
|
|
29
|
+
...IDENTITY,
|
|
30
|
+
{ name: 'baseIds', label: 'base-classes', type: 'list', width: 180 },
|
|
31
|
+
/* 이 등급이 요구하는 검사. 자격 인터록이 이 칸을 읽는다 — 비어 있으면 아무 검사도 요구하지 않는다. */
|
|
32
|
+
{ name: 'testSpecificationIds', label: 'required-tests', type: 'list', width: 200 },
|
|
33
|
+
...EFFECTIVE
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
key: 'person',
|
|
38
|
+
query: 'persons',
|
|
39
|
+
mutation: 'updateMultiplePerson',
|
|
40
|
+
title: 'person',
|
|
41
|
+
columns: [
|
|
42
|
+
...IDENTITY,
|
|
43
|
+
{ name: 'personnelClassIds', label: 'personnel-classes', type: 'list', width: 200 },
|
|
44
|
+
{ name: 'homeLocation', label: 'home-location', type: 'string', width: 140 },
|
|
45
|
+
{ name: 'workCalendar', label: 'work-calendar', type: 'json', width: 200 },
|
|
46
|
+
{ name: 'testResults', label: 'test-results', type: 'json', width: 200 },
|
|
47
|
+
...EFFECTIVE
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
key: 'equipmentClass',
|
|
52
|
+
query: 'equipmentClasses',
|
|
53
|
+
mutation: 'updateMultipleEquipmentClass',
|
|
54
|
+
title: 'equipment-class',
|
|
55
|
+
columns: [...IDENTITY, { name: 'baseIds', label: 'base-classes', type: 'list', width: 180 }, ...EFFECTIVE]
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
key: 'equipment',
|
|
59
|
+
query: 'equipmentList',
|
|
60
|
+
mutation: 'updateMultipleEquipment',
|
|
61
|
+
title: 'equipment',
|
|
62
|
+
columns: [
|
|
63
|
+
...IDENTITY,
|
|
64
|
+
{ name: 'equipmentClassIds', label: 'equipment-classes', type: 'list', width: 200 },
|
|
65
|
+
{ name: 'identity', label: 'identity', type: 'string', width: 200 },
|
|
66
|
+
{ name: 'homeLocation', label: 'home-location', type: 'string', width: 140 },
|
|
67
|
+
/* 계획 조업 시간의 바탕. 비어 있으면 OEE 의 가동률이 「모름」이 된다. */
|
|
68
|
+
{ name: 'workCalendar', label: 'work-calendar', type: 'json', width: 200 },
|
|
69
|
+
...EFFECTIVE
|
|
70
|
+
]
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
key: 'stopReason',
|
|
74
|
+
query: 'stopReasonList',
|
|
75
|
+
mutation: 'updateMultipleStopReason',
|
|
76
|
+
title: 'stop-reason',
|
|
77
|
+
columns: [
|
|
78
|
+
...IDENTITY,
|
|
79
|
+
/* 어느 상태의 사유인가. 이 칸이 가동률을 깎느냐 마느냐를 가른다. */
|
|
80
|
+
{ name: 'status', label: 'state', type: 'string', width: 130 },
|
|
81
|
+
{ name: 'parentName', label: 'parent-reason', type: 'string', width: 150 },
|
|
82
|
+
{ name: 'detailRequired', label: 'detail-required', type: 'boolean', width: 110 },
|
|
83
|
+
...EFFECTIVE
|
|
84
|
+
]
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
key: 'physicalAssetClass',
|
|
88
|
+
query: 'physicalAssetClasses',
|
|
89
|
+
mutation: 'updateMultiplePhysicalAssetClass',
|
|
90
|
+
title: 'asset-class',
|
|
91
|
+
columns: [
|
|
92
|
+
...IDENTITY,
|
|
93
|
+
{ name: 'baseIds', label: 'base-classes', type: 'list', width: 180 },
|
|
94
|
+
{ name: 'testSpecificationIds', label: 'required-tests', type: 'list', width: 200 },
|
|
95
|
+
...EFFECTIVE
|
|
96
|
+
]
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
key: 'physicalAsset',
|
|
100
|
+
query: 'physicalAssets',
|
|
101
|
+
mutation: 'updateMultiplePhysicalAsset',
|
|
102
|
+
title: 'asset',
|
|
103
|
+
columns: [
|
|
104
|
+
...IDENTITY,
|
|
105
|
+
{ name: 'assetClassIds', label: 'asset-classes', type: 'list', width: 180 },
|
|
106
|
+
{ name: 'identity', label: 'grai', type: 'string', width: 200 },
|
|
107
|
+
/* 정격 사용 횟수. 비어 있으면 횟수로 막지 않는다. */
|
|
108
|
+
{ name: 'cycleLimit', label: 'cycle-limit', type: 'number', width: 110 },
|
|
109
|
+
{ name: 'testResults', label: 'calibrations', type: 'json', width: 200 },
|
|
110
|
+
...EFFECTIVE
|
|
111
|
+
]
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
key: 'materialClass',
|
|
115
|
+
query: 'materialClasses',
|
|
116
|
+
mutation: 'updateMultipleMaterialClass',
|
|
117
|
+
title: 'material-class',
|
|
118
|
+
columns: [...IDENTITY, { name: 'baseIds', label: 'base-classes', type: 'list', width: 180 }, ...EFFECTIVE]
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
key: 'materialDefinition',
|
|
122
|
+
query: 'materialDefinitions',
|
|
123
|
+
mutation: 'updateMultipleMaterialDefinition',
|
|
124
|
+
title: 'material',
|
|
125
|
+
columns: [
|
|
126
|
+
...IDENTITY,
|
|
127
|
+
{ name: 'materialClassIds', label: 'material-classes', type: 'list', width: 180 },
|
|
128
|
+
{ name: 'identity', label: 'gtin', type: 'string', width: 200 },
|
|
129
|
+
{ name: 'uom', label: 'uom', type: 'string', width: 90 },
|
|
130
|
+
{ name: 'locationType', label: 'location-type', type: 'string', width: 140 },
|
|
131
|
+
...EFFECTIVE
|
|
132
|
+
]
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
key: 'operationalLocation',
|
|
136
|
+
query: 'operationalLocations',
|
|
137
|
+
mutation: 'updateMultipleOperationalLocation',
|
|
138
|
+
title: 'location',
|
|
139
|
+
columns: [
|
|
140
|
+
...IDENTITY,
|
|
141
|
+
{ name: 'equipmentLevel', label: 'equipment-level', type: 'string', width: 140 },
|
|
142
|
+
{ name: 'parentName', label: 'parent-location', type: 'string', width: 150 },
|
|
143
|
+
{ name: 'identity', label: 'sgln', type: 'string', width: 200 },
|
|
144
|
+
...EFFECTIVE
|
|
145
|
+
]
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
key: 'operationDefinition',
|
|
149
|
+
query: 'operationDefinitions',
|
|
150
|
+
mutation: 'updateMultipleOperationDefinition',
|
|
151
|
+
title: 'operation',
|
|
152
|
+
columns: [
|
|
153
|
+
...IDENTITY,
|
|
154
|
+
{ name: 'intent', label: 'intent', type: 'string', width: 110 },
|
|
155
|
+
{ name: 'locationType', label: 'location-type', type: 'string', width: 140 },
|
|
156
|
+
{ name: 'resourceType', label: 'resource-type', type: 'string', width: 140 },
|
|
157
|
+
/* 품목당 표준 시간. 없으면 OEE 의 성능률이 「모름」이 된다. ISO 8601 기간 표기다. */
|
|
158
|
+
{ name: 'duration', label: 'duration', type: 'string', width: 110 },
|
|
159
|
+
/* 요구 인원. 자격 인터록이 이 칸을 읽는다. */
|
|
160
|
+
{ name: 'personnelSpecification', label: 'personnel-spec', type: 'json', width: 200 },
|
|
161
|
+
{ name: 'bizStep', label: 'biz-step', type: 'string', width: 200 },
|
|
162
|
+
...EFFECTIVE
|
|
163
|
+
]
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
key: 'testSpecification',
|
|
167
|
+
query: 'testSpecifications',
|
|
168
|
+
mutation: 'updateMultipleTestSpecification',
|
|
169
|
+
title: 'test-specification',
|
|
170
|
+
columns: [...IDENTITY, ...EFFECTIVE]
|
|
171
|
+
}
|
|
172
|
+
];
|
|
173
|
+
export function masterAxisViewOf(key) {
|
|
174
|
+
return MASTER_AXIS_VIEWS.find(axis => axis.key === key);
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=master-axes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"master-axes.js","sourceRoot":"","sources":["../../client/pages/master-axes.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * 마스터 열두 축의 **화면 쪽 선언** — 축마다 다른 것만 적는다.\n *\n * ── 왜 화면이 하나인가 ─────────────────────────────────────────────────────\n * 열두 축의 화면이 하는 일이 같다: 목록을 보이고, 그리드에서 고치고, 저장한다. 화면을 열둘 만들면\n * 규칙 하나를 고칠 때 열두 곳을 고쳐야 하고, 한 곳을 빠뜨리면 그 축만 다르게 동작한다.\n *\n * ── 왜 서버의 축 표와 따로 두나 ────────────────────────────────────────────\n * 서버가 아는 것은 「어느 표에서 읽나 · 무엇으로 찾나」이고, 화면이 아는 것은 「어느 칸을 어떤 모양으로\n * 보이나」다. 서로 다른 물음이라 한 표에 담으면 양쪽 다 지저분해진다. 축의 이름(`key`)만 같게 둔다.\n */\n\nexport type ColumnType = 'string' | 'number' | 'boolean' | 'date' | 'json' | 'list'\n\nexport interface AxisColumn {\n name: string\n /** 화면 문구 키. `field.<이것>`. */\n label: string\n type: ColumnType\n width?: number\n /** 고칠 수 없는 칸. 자동으로 붙는 값이 여기 온다. */\n readonly?: boolean\n}\n\nexport interface MasterAxisView {\n key: string\n /** GraphQL 조회 이름 — 서버가 낸 그대로. */\n query: string\n /** GraphQL 저장 이름. */\n mutation: string\n /** 제목 문구 키. `title.<이것>`. */\n title: string\n columns: AxisColumn[]\n}\n\n/** 열두 축이 공통으로 갖는 끝 칸들 — ISA-95 유효 기간. */\nconst EFFECTIVE: AxisColumn[] = [\n { name: 'effectiveStart', label: 'effective-start', type: 'date', width: 150 },\n { name: 'effectiveEnd', label: 'effective-end', type: 'date', width: 150 }\n]\n\n/** 이름과 설명은 열두 축이 모두 갖는다. */\nconst IDENTITY: AxisColumn[] = [\n { name: 'name', label: 'name', type: 'string', width: 160 },\n { name: 'description', label: 'description', type: 'string', width: 200 }\n]\n\nexport const MASTER_AXIS_VIEWS: readonly MasterAxisView[] = [\n {\n key: 'personnelClass',\n query: 'personnelClasses',\n mutation: 'updateMultiplePersonnelClass',\n title: 'personnel-class',\n columns: [\n ...IDENTITY,\n { name: 'baseIds', label: 'base-classes', type: 'list', width: 180 },\n /* 이 등급이 요구하는 검사. 자격 인터록이 이 칸을 읽는다 — 비어 있으면 아무 검사도 요구하지 않는다. */\n { name: 'testSpecificationIds', label: 'required-tests', type: 'list', width: 200 },\n ...EFFECTIVE\n ]\n },\n {\n key: 'person',\n query: 'persons',\n mutation: 'updateMultiplePerson',\n title: 'person',\n columns: [\n ...IDENTITY,\n { name: 'personnelClassIds', label: 'personnel-classes', type: 'list', width: 200 },\n { name: 'homeLocation', label: 'home-location', type: 'string', width: 140 },\n { name: 'workCalendar', label: 'work-calendar', type: 'json', width: 200 },\n { name: 'testResults', label: 'test-results', type: 'json', width: 200 },\n ...EFFECTIVE\n ]\n },\n {\n key: 'equipmentClass',\n query: 'equipmentClasses',\n mutation: 'updateMultipleEquipmentClass',\n title: 'equipment-class',\n columns: [...IDENTITY, { name: 'baseIds', label: 'base-classes', type: 'list', width: 180 }, ...EFFECTIVE]\n },\n {\n key: 'equipment',\n query: 'equipmentList',\n mutation: 'updateMultipleEquipment',\n title: 'equipment',\n columns: [\n ...IDENTITY,\n { name: 'equipmentClassIds', label: 'equipment-classes', type: 'list', width: 200 },\n { name: 'identity', label: 'identity', type: 'string', width: 200 },\n { name: 'homeLocation', label: 'home-location', type: 'string', width: 140 },\n /* 계획 조업 시간의 바탕. 비어 있으면 OEE 의 가동률이 「모름」이 된다. */\n { name: 'workCalendar', label: 'work-calendar', type: 'json', width: 200 },\n ...EFFECTIVE\n ]\n },\n {\n key: 'stopReason',\n query: 'stopReasonList',\n mutation: 'updateMultipleStopReason',\n title: 'stop-reason',\n columns: [\n ...IDENTITY,\n /* 어느 상태의 사유인가. 이 칸이 가동률을 깎느냐 마느냐를 가른다. */\n { name: 'status', label: 'state', type: 'string', width: 130 },\n { name: 'parentName', label: 'parent-reason', type: 'string', width: 150 },\n { name: 'detailRequired', label: 'detail-required', type: 'boolean', width: 110 },\n ...EFFECTIVE\n ]\n },\n {\n key: 'physicalAssetClass',\n query: 'physicalAssetClasses',\n mutation: 'updateMultiplePhysicalAssetClass',\n title: 'asset-class',\n columns: [\n ...IDENTITY,\n { name: 'baseIds', label: 'base-classes', type: 'list', width: 180 },\n { name: 'testSpecificationIds', label: 'required-tests', type: 'list', width: 200 },\n ...EFFECTIVE\n ]\n },\n {\n key: 'physicalAsset',\n query: 'physicalAssets',\n mutation: 'updateMultiplePhysicalAsset',\n title: 'asset',\n columns: [\n ...IDENTITY,\n { name: 'assetClassIds', label: 'asset-classes', type: 'list', width: 180 },\n { name: 'identity', label: 'grai', type: 'string', width: 200 },\n /* 정격 사용 횟수. 비어 있으면 횟수로 막지 않는다. */\n { name: 'cycleLimit', label: 'cycle-limit', type: 'number', width: 110 },\n { name: 'testResults', label: 'calibrations', type: 'json', width: 200 },\n ...EFFECTIVE\n ]\n },\n {\n key: 'materialClass',\n query: 'materialClasses',\n mutation: 'updateMultipleMaterialClass',\n title: 'material-class',\n columns: [...IDENTITY, { name: 'baseIds', label: 'base-classes', type: 'list', width: 180 }, ...EFFECTIVE]\n },\n {\n key: 'materialDefinition',\n query: 'materialDefinitions',\n mutation: 'updateMultipleMaterialDefinition',\n title: 'material',\n columns: [\n ...IDENTITY,\n { name: 'materialClassIds', label: 'material-classes', type: 'list', width: 180 },\n { name: 'identity', label: 'gtin', type: 'string', width: 200 },\n { name: 'uom', label: 'uom', type: 'string', width: 90 },\n { name: 'locationType', label: 'location-type', type: 'string', width: 140 },\n ...EFFECTIVE\n ]\n },\n {\n key: 'operationalLocation',\n query: 'operationalLocations',\n mutation: 'updateMultipleOperationalLocation',\n title: 'location',\n columns: [\n ...IDENTITY,\n { name: 'equipmentLevel', label: 'equipment-level', type: 'string', width: 140 },\n { name: 'parentName', label: 'parent-location', type: 'string', width: 150 },\n { name: 'identity', label: 'sgln', type: 'string', width: 200 },\n ...EFFECTIVE\n ]\n },\n {\n key: 'operationDefinition',\n query: 'operationDefinitions',\n mutation: 'updateMultipleOperationDefinition',\n title: 'operation',\n columns: [\n ...IDENTITY,\n { name: 'intent', label: 'intent', type: 'string', width: 110 },\n { name: 'locationType', label: 'location-type', type: 'string', width: 140 },\n { name: 'resourceType', label: 'resource-type', type: 'string', width: 140 },\n /* 품목당 표준 시간. 없으면 OEE 의 성능률이 「모름」이 된다. ISO 8601 기간 표기다. */\n { name: 'duration', label: 'duration', type: 'string', width: 110 },\n /* 요구 인원. 자격 인터록이 이 칸을 읽는다. */\n { name: 'personnelSpecification', label: 'personnel-spec', type: 'json', width: 200 },\n { name: 'bizStep', label: 'biz-step', type: 'string', width: 200 },\n ...EFFECTIVE\n ]\n },\n {\n key: 'testSpecification',\n query: 'testSpecifications',\n mutation: 'updateMultipleTestSpecification',\n title: 'test-specification',\n columns: [...IDENTITY, ...EFFECTIVE]\n }\n]\n\nexport function masterAxisViewOf(key: string): MasterAxisView | undefined {\n return MASTER_AXIS_VIEWS.find(axis => axis.key === key)\n}\n"]}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import '@material/web/icon/icon.js';
|
|
2
|
+
import '@operato/data-grist/ox-grist.js';
|
|
3
|
+
import '@operato/data-grist/ox-filters-form.js';
|
|
4
|
+
import '@operato/context/ox-context-page-toolbar.js';
|
|
5
|
+
import { FetchOption } from '@operato/data-grist';
|
|
6
|
+
import { PageView } from '@operato/shell';
|
|
7
|
+
declare const OpsMasterList_base: (new (...args: any[]) => {
|
|
8
|
+
__preferenceProviders: {
|
|
9
|
+
[element: string]: import("@operato/p13n").PagePreferenceProvider;
|
|
10
|
+
};
|
|
11
|
+
getPagePreferenceProvider(element: string): import("@operato/p13n").PagePreferenceProvider | undefined;
|
|
12
|
+
}) & (new (...args: any[]) => import("lit").LitElement) & typeof PageView;
|
|
13
|
+
/**
|
|
14
|
+
* 마스터 화면 하나가 **열두 축을 다 맡는다.**
|
|
15
|
+
*
|
|
16
|
+
* 축은 주소의 질의로 받는다(`ops-master-list?axis=person`). 메뉴가 축마다 한 줄씩 걸고, 화면은 그
|
|
17
|
+
* 하나다 — 규칙을 고칠 때 한 곳만 고치면 열두 축이 함께 바뀐다.
|
|
18
|
+
*
|
|
19
|
+
* ── 마스터는 그리드에서 고친다 ─────────────────────────────────────────────
|
|
20
|
+
* 업무 기록(실적 · 검사 · 처분)은 조회 전용이다. 일어난 일을 나중에 고치면 「그때 무엇이 있었나」가
|
|
21
|
+
* 사라진다. 마스터는 **선언**이라 다르다 — 지금의 규정이 무엇인지가 답이고, 규정은 바뀐다.
|
|
22
|
+
*
|
|
23
|
+
* ── 없앨 때 지우지 않는다 ──────────────────────────────────────────────────
|
|
24
|
+
* 지운 행은 서버가 유효 기간의 끝을 채워 오늘부터 유효하지 않게 만든다. 실제로 지우면 그것을 가리키던
|
|
25
|
+
* 지난 실적이 가리킬 것을 잃는다. 화면은 그 사실을 말해 준다 — 지운 줄 알았는데 목록에 남아 있으면
|
|
26
|
+
* 사용자가 저장이 안 된 것으로 읽는다.
|
|
27
|
+
*/
|
|
28
|
+
export declare class OpsMasterList extends OpsMasterList_base {
|
|
29
|
+
static styles: import("lit").CSSResult[];
|
|
30
|
+
active: boolean;
|
|
31
|
+
gristConfig: any;
|
|
32
|
+
mode: 'CARD' | 'LIST' | 'GRID';
|
|
33
|
+
private axis?;
|
|
34
|
+
private total?;
|
|
35
|
+
private loaded;
|
|
36
|
+
private grist;
|
|
37
|
+
get context(): {
|
|
38
|
+
title: string;
|
|
39
|
+
search: {
|
|
40
|
+
handler: (search: string) => void;
|
|
41
|
+
value: string;
|
|
42
|
+
};
|
|
43
|
+
filter: {
|
|
44
|
+
handler: () => void;
|
|
45
|
+
};
|
|
46
|
+
actions: {
|
|
47
|
+
title: string;
|
|
48
|
+
action: () => Promise<void>;
|
|
49
|
+
icon: string;
|
|
50
|
+
}[];
|
|
51
|
+
exportable: {
|
|
52
|
+
name: string;
|
|
53
|
+
data: () => any[];
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
57
|
+
private scaleNotice;
|
|
58
|
+
/** 주소가 바뀌면 축이 바뀐다. 셸이 이 훅으로 알려 준다. */
|
|
59
|
+
pageUpdated(changes: any, lifecycle: any): Promise<void>;
|
|
60
|
+
private configOf;
|
|
61
|
+
private columnOf;
|
|
62
|
+
fetchHandler({ page, limit, sortings, filters }: FetchOption): Promise<{
|
|
63
|
+
total: any;
|
|
64
|
+
records: any;
|
|
65
|
+
}>;
|
|
66
|
+
private save;
|
|
67
|
+
}
|
|
68
|
+
export {};
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import { __decorate, __metadata } from "tslib";
|
|
2
|
+
import '@material/web/icon/icon.js';
|
|
3
|
+
import '@operato/data-grist/ox-grist.js';
|
|
4
|
+
import '@operato/data-grist/ox-filters-form.js';
|
|
5
|
+
import '@operato/context/ox-context-page-toolbar.js';
|
|
6
|
+
import gql from 'graphql-tag';
|
|
7
|
+
import { css, html } from 'lit';
|
|
8
|
+
import { customElement, property, query, state } from 'lit/decorators.js';
|
|
9
|
+
import { DataGrist } from '@operato/data-grist';
|
|
10
|
+
import { client } from '@operato/graphql';
|
|
11
|
+
import { i18next, localize } from '@operato/i18n';
|
|
12
|
+
import { notify } from '@operato/layout';
|
|
13
|
+
import { p13n } from '@operato/p13n';
|
|
14
|
+
import { PageView } from '@operato/shell';
|
|
15
|
+
import { CommonGristStyles, CommonHeaderStyles, ScrollbarStyles } from '@operato/styles';
|
|
16
|
+
import { isMobileDevice } from '@operato/utils';
|
|
17
|
+
import { MASTER_AXIS_VIEWS, masterAxisViewOf } from './master-axes';
|
|
18
|
+
/**
|
|
19
|
+
* 마스터 화면 하나가 **열두 축을 다 맡는다.**
|
|
20
|
+
*
|
|
21
|
+
* 축은 주소의 질의로 받는다(`ops-master-list?axis=person`). 메뉴가 축마다 한 줄씩 걸고, 화면은 그
|
|
22
|
+
* 하나다 — 규칙을 고칠 때 한 곳만 고치면 열두 축이 함께 바뀐다.
|
|
23
|
+
*
|
|
24
|
+
* ── 마스터는 그리드에서 고친다 ─────────────────────────────────────────────
|
|
25
|
+
* 업무 기록(실적 · 검사 · 처분)은 조회 전용이다. 일어난 일을 나중에 고치면 「그때 무엇이 있었나」가
|
|
26
|
+
* 사라진다. 마스터는 **선언**이라 다르다 — 지금의 규정이 무엇인지가 답이고, 규정은 바뀐다.
|
|
27
|
+
*
|
|
28
|
+
* ── 없앨 때 지우지 않는다 ──────────────────────────────────────────────────
|
|
29
|
+
* 지운 행은 서버가 유효 기간의 끝을 채워 오늘부터 유효하지 않게 만든다. 실제로 지우면 그것을 가리키던
|
|
30
|
+
* 지난 실적이 가리킬 것을 잃는다. 화면은 그 사실을 말해 준다 — 지운 줄 알았는데 목록에 남아 있으면
|
|
31
|
+
* 사용자가 저장이 안 된 것으로 읽는다.
|
|
32
|
+
*/
|
|
33
|
+
let OpsMasterList = class OpsMasterList extends p13n(localize(i18next)(PageView)) {
|
|
34
|
+
constructor() {
|
|
35
|
+
super(...arguments);
|
|
36
|
+
this.active = false;
|
|
37
|
+
this.mode = isMobileDevice() ? 'CARD' : 'GRID';
|
|
38
|
+
this.loaded = 0;
|
|
39
|
+
}
|
|
40
|
+
static { this.styles = [
|
|
41
|
+
CommonGristStyles,
|
|
42
|
+
CommonHeaderStyles,
|
|
43
|
+
ScrollbarStyles,
|
|
44
|
+
css `
|
|
45
|
+
:host {
|
|
46
|
+
display: flex;
|
|
47
|
+
flex-direction: column;
|
|
48
|
+
overflow: hidden;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
ox-grist {
|
|
52
|
+
overflow-y: auto;
|
|
53
|
+
flex: 1;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.scale {
|
|
57
|
+
padding: var(--spacing-small) var(--spacing-large);
|
|
58
|
+
color: var(--md-sys-color-on-surface-variant);
|
|
59
|
+
font-size: 0.85rem;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.scale[data-capped] {
|
|
63
|
+
color: var(--status-warning-color);
|
|
64
|
+
}
|
|
65
|
+
`
|
|
66
|
+
]; }
|
|
67
|
+
get context() {
|
|
68
|
+
return {
|
|
69
|
+
title: this.axis ? i18next.t(`title.${this.axis.title}`) : i18next.t('title.master'),
|
|
70
|
+
search: {
|
|
71
|
+
handler: (search) => {
|
|
72
|
+
this.grist.searchText = search;
|
|
73
|
+
},
|
|
74
|
+
value: this.grist?.searchText || ''
|
|
75
|
+
},
|
|
76
|
+
filter: {
|
|
77
|
+
handler: () => {
|
|
78
|
+
this.grist.toggleHeadroom();
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
actions: [
|
|
82
|
+
{
|
|
83
|
+
title: i18next.t('button.save'),
|
|
84
|
+
action: this.save.bind(this),
|
|
85
|
+
icon: 'save'
|
|
86
|
+
}
|
|
87
|
+
],
|
|
88
|
+
exportable: {
|
|
89
|
+
name: this.axis ? i18next.t(`title.${this.axis.title}`) : i18next.t('title.master'),
|
|
90
|
+
data: () => this.grist.exportRecords()
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
render() {
|
|
95
|
+
if (!this.axis) {
|
|
96
|
+
/* 어느 축인지 모르면 빈 그리드를 보이지 않는다 — 빈 목록과 「축을 못 찾았다」가 구별되지 않는다. */
|
|
97
|
+
return html `<div class="scale">${i18next.t('text.master-axis-unknown')}</div>`;
|
|
98
|
+
}
|
|
99
|
+
return html `
|
|
100
|
+
<ox-grist .mode=${this.mode} .config=${this.gristConfig} .fetchHandler=${this.fetchHandler.bind(this)}>
|
|
101
|
+
<div slot="headroom" class="header">
|
|
102
|
+
<div class="title">${i18next.t(`title.${this.axis.title}`)}</div>
|
|
103
|
+
<ox-context-page-toolbar class="actions" .context=${this.context}></ox-context-page-toolbar>
|
|
104
|
+
</div>
|
|
105
|
+
</ox-grist>
|
|
106
|
+
|
|
107
|
+
${this.scaleNotice()}
|
|
108
|
+
`;
|
|
109
|
+
}
|
|
110
|
+
scaleNotice() {
|
|
111
|
+
if (this.total === undefined) {
|
|
112
|
+
return html `<div class="scale">${i18next.t('text.loaded-count', { loaded: this.loaded })}</div>`;
|
|
113
|
+
}
|
|
114
|
+
const capped = this.loaded < this.total;
|
|
115
|
+
return html `
|
|
116
|
+
<div class="scale" ?data-capped=${capped}>
|
|
117
|
+
${capped
|
|
118
|
+
? i18next.t('text.loaded-of-total-more', { loaded: this.loaded, total: this.total })
|
|
119
|
+
: i18next.t('text.loaded-of-total', { loaded: this.loaded, total: this.total })}
|
|
120
|
+
</div>
|
|
121
|
+
`;
|
|
122
|
+
}
|
|
123
|
+
/** 주소가 바뀌면 축이 바뀐다. 셸이 이 훅으로 알려 준다. */
|
|
124
|
+
async pageUpdated(changes, lifecycle) {
|
|
125
|
+
const key = new URLSearchParams(lifecycle?.params ?? location.search).get('axis') ?? MASTER_AXIS_VIEWS[0].key;
|
|
126
|
+
const axis = masterAxisViewOf(key);
|
|
127
|
+
if (axis?.key === this.axis?.key) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
this.axis = axis;
|
|
131
|
+
this.total = undefined;
|
|
132
|
+
this.loaded = 0;
|
|
133
|
+
if (axis) {
|
|
134
|
+
this.gristConfig = this.configOf(axis);
|
|
135
|
+
await this.updateComplete;
|
|
136
|
+
this.grist?.fetch();
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
configOf(axis) {
|
|
140
|
+
return {
|
|
141
|
+
list: { fields: ['name', 'description'], details: [] },
|
|
142
|
+
columns: [
|
|
143
|
+
{ type: 'gutter', gutterName: 'sequence' },
|
|
144
|
+
{ type: 'gutter', gutterName: 'row-selector', multiple: true },
|
|
145
|
+
...axis.columns.map(column => this.columnOf(column))
|
|
146
|
+
],
|
|
147
|
+
/* 새 행을 만들 수 있다 — 마스터를 채우는 것이 이 화면의 일이다. */
|
|
148
|
+
rows: { appendable: true, selectable: { multiple: true } },
|
|
149
|
+
sorters: [{ name: 'name', desc: false }]
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
columnOf(column) {
|
|
153
|
+
const header = i18next.t(`field.${column.label}`);
|
|
154
|
+
const editable = !column.readonly;
|
|
155
|
+
switch (column.type) {
|
|
156
|
+
case 'number':
|
|
157
|
+
return { type: 'float', name: column.name, header, record: { editable }, sortable: true, width: column.width };
|
|
158
|
+
case 'boolean':
|
|
159
|
+
return { type: 'boolean', name: column.name, header, record: { editable }, width: column.width };
|
|
160
|
+
case 'date':
|
|
161
|
+
return { type: 'datetime', name: column.name, header, record: { editable }, sortable: true, width: column.width };
|
|
162
|
+
/*
|
|
163
|
+
* 목록과 JSON 은 **글자로 고친다.** 전용 편집기를 만들면 축마다 다른 편집기가 생기고, 그 편집기가
|
|
164
|
+
* 모르는 칸이 들어오면 값이 오류 보고 없이 사라진다. 지금은 있는 그대로 보이고 그대로 고친다.
|
|
165
|
+
*/
|
|
166
|
+
case 'list':
|
|
167
|
+
case 'json':
|
|
168
|
+
return { type: 'string', name: column.name, header, record: { editable }, width: column.width };
|
|
169
|
+
default:
|
|
170
|
+
return {
|
|
171
|
+
type: 'string',
|
|
172
|
+
name: column.name,
|
|
173
|
+
header,
|
|
174
|
+
record: { editable },
|
|
175
|
+
filter: 'search',
|
|
176
|
+
sortable: true,
|
|
177
|
+
width: column.width
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
async fetchHandler({ page = 1, limit = 50, sortings = [], filters = [] }) {
|
|
182
|
+
if (!this.axis) {
|
|
183
|
+
return { total: 0, records: [] };
|
|
184
|
+
}
|
|
185
|
+
const fields = this.axis.columns.map(column => column.name).join('\n');
|
|
186
|
+
const response = await client.query({
|
|
187
|
+
query: gql `
|
|
188
|
+
query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
|
|
189
|
+
${this.axis.query}(filters: $filters, pagination: $pagination, sortings: $sortings) {
|
|
190
|
+
items {
|
|
191
|
+
id
|
|
192
|
+
${fields}
|
|
193
|
+
}
|
|
194
|
+
total
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
`,
|
|
198
|
+
variables: { filters, pagination: { page, limit }, sortings },
|
|
199
|
+
fetchPolicy: 'no-cache'
|
|
200
|
+
});
|
|
201
|
+
const payload = response.data?.[this.axis.query];
|
|
202
|
+
const items = payload?.items ?? [];
|
|
203
|
+
const total = payload?.total;
|
|
204
|
+
this.loaded = items.length;
|
|
205
|
+
this.total = typeof total === 'number' ? total : undefined;
|
|
206
|
+
return { total: total ?? 0, records: items };
|
|
207
|
+
}
|
|
208
|
+
async save() {
|
|
209
|
+
if (!this.axis) {
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
const patches = this.grist.dirtyRecords;
|
|
213
|
+
if (!patches?.length) {
|
|
214
|
+
notify({ message: i18next.t('text.nothing-changed'), level: 'info' });
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
await client.mutate({
|
|
218
|
+
mutation: gql `
|
|
219
|
+
mutation ($patches: [ScalarObject!]!) {
|
|
220
|
+
${this.axis.mutation}(patches: $patches) {
|
|
221
|
+
id
|
|
222
|
+
name
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
`,
|
|
226
|
+
variables: { patches }
|
|
227
|
+
});
|
|
228
|
+
/* 지운 행은 사라지지 않고 유효 기간의 끝이 채워진다. 말해 주지 않으면 저장이 안 된 것으로 읽는다. */
|
|
229
|
+
if (patches.some((patch) => String(patch.cuFlag).toUpperCase() === '-')) {
|
|
230
|
+
notify({ message: i18next.t('text.retired-not-deleted'), level: 'info' });
|
|
231
|
+
}
|
|
232
|
+
this.grist.fetch();
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
__decorate([
|
|
236
|
+
property({ type: Boolean }),
|
|
237
|
+
__metadata("design:type", Boolean)
|
|
238
|
+
], OpsMasterList.prototype, "active", void 0);
|
|
239
|
+
__decorate([
|
|
240
|
+
property({ type: Object }),
|
|
241
|
+
__metadata("design:type", Object)
|
|
242
|
+
], OpsMasterList.prototype, "gristConfig", void 0);
|
|
243
|
+
__decorate([
|
|
244
|
+
property({ type: String }),
|
|
245
|
+
__metadata("design:type", String)
|
|
246
|
+
], OpsMasterList.prototype, "mode", void 0);
|
|
247
|
+
__decorate([
|
|
248
|
+
state(),
|
|
249
|
+
__metadata("design:type", Object)
|
|
250
|
+
], OpsMasterList.prototype, "axis", void 0);
|
|
251
|
+
__decorate([
|
|
252
|
+
state(),
|
|
253
|
+
__metadata("design:type", Number)
|
|
254
|
+
], OpsMasterList.prototype, "total", void 0);
|
|
255
|
+
__decorate([
|
|
256
|
+
state(),
|
|
257
|
+
__metadata("design:type", Object)
|
|
258
|
+
], OpsMasterList.prototype, "loaded", void 0);
|
|
259
|
+
__decorate([
|
|
260
|
+
query('ox-grist'),
|
|
261
|
+
__metadata("design:type", DataGrist)
|
|
262
|
+
], OpsMasterList.prototype, "grist", void 0);
|
|
263
|
+
OpsMasterList = __decorate([
|
|
264
|
+
customElement('ops-master-list')
|
|
265
|
+
], OpsMasterList);
|
|
266
|
+
export { OpsMasterList };
|
|
267
|
+
//# sourceMappingURL=master-list.js.map
|