@things-factory/meta-ui 8.0.0-beta.9 → 8.0.2
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/client/bootstrap.ts +170 -0
- package/client/component/filter/filter-form-meta-code-select.ts +102 -0
- package/client/component/filter/filter-form-meta-object-select.ts +107 -0
- package/client/component/filter/filter-grist-meta-code-select.ts +97 -0
- package/client/component/filter/filter-grist-meta-object-select.ts +102 -0
- package/client/component/grist/editor/grist-editor-code-input.js +96 -0
- package/client/component/grist/editor/grist-editor-meta-code-selector.js +157 -0
- package/client/component/grist/editor/grist-editor-meta-object-selector.js +122 -0
- package/client/component/grist/renderer/grist-renderer-code-input.js +20 -0
- package/client/component/grist/renderer/grist-renderer-meta-code-selector.js +28 -0
- package/client/component/grist/renderer/grist-renderer-meta-object-selector.js +25 -0
- package/client/component/popup/code-input-editor-popup.js +111 -0
- package/client/component/popup/file-upload-popup.js +129 -0
- package/client/component/popup/meta-object-selector-popup.ts +356 -0
- package/client/component/popup/record-based-code-editor-popup.ts +141 -0
- package/client/dynamic-menus.ts +38 -0
- package/client/index.ts +18 -0
- package/client/load-components.ts +17 -0
- package/client/mixin/meta-base-mixin.js +323 -0
- package/client/mixin/meta-basic-grist-mixin.js +283 -0
- package/client/mixin/meta-button-mixin.js +116 -0
- package/client/mixin/meta-form-mixin.js +435 -0
- package/client/mixin/meta-grist-tab-mixin.js +335 -0
- package/client/mixin/meta-main-tab-mixin.js +267 -0
- package/client/mixin/meta-master-detail-mixin.js +395 -0
- package/client/mixin/meta-service-mixin.js +306 -0
- package/client/mixin/meta-tab-detail-mixin.js +283 -0
- package/client/mixin/meta-tab-mixin.js +190 -0
- package/client/pages/activity/meta-activity-define-page.js +422 -0
- package/client/pages/activity/meta-activity-list-page.js +262 -0
- package/client/pages/activity/meta-activity-viewer-element.js +35 -0
- package/client/pages/activity/meta-activity-writer-element.js +48 -0
- package/client/pages/activity/meta-activiy-mixin.js +79 -0
- package/client/pages/button-role/button-role-detail.js +50 -0
- package/client/pages/button-role/button-role-page.js +25 -0
- package/client/pages/doc-number/doc-number-page.js +24 -0
- package/client/pages/doc-number/next-doc-number-popup.js +25 -0
- package/client/pages/entity/config-entity.js +955 -0
- package/client/pages/entity/main-menu-selector.js +245 -0
- package/client/pages/history/history-copy-list-popup.js +145 -0
- package/client/pages/history/history-json-list-popup.js +159 -0
- package/client/pages/menu/dynamic-menu-template.js +92 -0
- package/client/pages/menu/dynamic-menu.ts +744 -0
- package/client/pages/menu/export-menu-popup.js +468 -0
- package/client/pages/meta-form-element.js +9 -0
- package/client/pages/meta-grist-element.js +12 -0
- package/client/pages/meta-grist-page.js +16 -0
- package/client/pages/meta-grist-tab-element.js +16 -0
- package/client/pages/meta-grist-tab-page.js +16 -0
- package/client/pages/meta-main-tab-element.js +12 -0
- package/client/pages/meta-main-tab-page.js +16 -0
- package/client/pages/meta-master-detail-element.js +12 -0
- package/client/pages/meta-master-detail-page.js +16 -0
- package/client/pages/meta-tab-detail-element.js +12 -0
- package/client/pages/meta-tab-detail-page.js +16 -0
- package/client/pages/meta-tab-element.js +15 -0
- package/client/pages/printer-device/printer-device-page.js +24 -0
- package/client/pages/template/doc-template-page.js +24 -0
- package/client/pages/template/template-file-page.js +24 -0
- package/client/pages/terms/config-terminology.js +214 -0
- package/client/pages/work-code/work-code-detail-popup.js +16 -0
- package/client/pages/work-code/work-code-page.js +23 -0
- package/client/route.ts +36 -0
- package/client/tsconfig.json +13 -0
- package/client/utils/grist-default-value.js +36 -0
- package/client/utils/meta-api.js +811 -0
- package/client/utils/meta-crypto.js +52 -0
- package/client/utils/meta-ui-util.js +3304 -0
- package/client/utils/rest-service-util.js +328 -0
- package/client/utils/service-util.js +1327 -0
- package/client/utils/terms-util.ts +119 -0
- package/client/utils/ui-util.js +338 -0
- package/client/utils/value-util.js +234 -0
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-client/utils/service-util.d.ts +2 -2
- package/dist-client/utils/service-util.js +4 -4
- package/dist-client/utils/service-util.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +24 -24
- package/server/activity/CommonActivity.ts +68 -0
- package/server/index.ts +3 -0
- package/server/routes.ts +61 -0
- package/server/service/button-role/button-role-mutation.ts +105 -0
- package/server/service/button-role/button-role-query.ts +53 -0
- package/server/service/button-role/button-role-type.ts +39 -0
- package/server/service/button-role/button-role.ts +61 -0
- package/server/service/button-role/index.ts +7 -0
- package/server/service/dynamic-menu/dynamic-menu-query.ts +270 -0
- package/server/service/dynamic-menu/dynamic-menu-type.ts +74 -0
- package/server/service/dynamic-menu/index.ts +3 -0
- package/server/service/entity-event-subscriber/entity-event-subscriber.ts +80 -0
- package/server/service/entity-event-subscriber/index.ts +3 -0
- package/server/service/index.ts +41 -0
- package/server/service/menu-button-auth/index.ts +7 -0
- package/server/service/menu-button-auth/menu-button-auth-mutation.ts +133 -0
- package/server/service/menu-button-auth/menu-button-auth-query.ts +138 -0
- package/server/service/menu-button-auth/menu-button-auth-type.ts +63 -0
- package/server/service/menu-button-auth/menu-button-auth.ts +92 -0
- package/server/service/meta-activity/index.ts +5 -0
- package/server/service/meta-activity/meta-activity-mutation.ts +191 -0
- package/server/service/meta-activity/meta-activity-query.ts +43 -0
- package/server/service/meta-activity/meta-activity-type.ts +56 -0
- package/server/service/set-translations/index.ts +3 -0
- package/server/service/set-translations/set-translation-resolver.ts +63 -0
- package/server/service/work-code/index.ts +6 -0
- package/server/service/work-code/work-code-mutation.ts +147 -0
- package/server/service/work-code/work-code-query.ts +67 -0
- package/server/service/work-code/work-code-type.ts +60 -0
- package/server/service/work-code/work-code.ts +83 -0
- package/server/service/work-code-detail/index.ts +6 -0
- package/server/service/work-code-detail/work-code-detail-mutation.ts +149 -0
- package/server/service/work-code-detail/work-code-detail-query.ts +59 -0
- package/server/service/work-code-detail/work-code-detail-type.ts +50 -0
- package/server/service/work-code-detail/work-code-detail.ts +82 -0
- package/server/tsconfig.json +9 -0
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import { MetaApi } from './../utils/meta-api'
|
|
2
|
+
import { ValueUtil } from './../utils/value-util'
|
|
3
|
+
import { TermsUtil } from './../utils/terms-util'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @license
|
|
7
|
+
* Copyright © HatioLab Inc. All rights reserved.
|
|
8
|
+
* @author Shortstop shortstop@hatiolab.com
|
|
9
|
+
* @description 메타 기반의 화면 생성을 위한 기본 믹스인
|
|
10
|
+
* 화면에 필요한 프로퍼티 정의, 메타 데이터 조회 및 파싱, 기본 데이터 조회, 변경 이벤트 핸들러 등록 등
|
|
11
|
+
*/
|
|
12
|
+
export const MetaBaseMixin = baseElement =>
|
|
13
|
+
class extends baseElement {
|
|
14
|
+
/**
|
|
15
|
+
* @override properties
|
|
16
|
+
***************************
|
|
17
|
+
* @returns {Object} 프로퍼티 오브젝트
|
|
18
|
+
*/
|
|
19
|
+
static get properties() {
|
|
20
|
+
return {
|
|
21
|
+
/**
|
|
22
|
+
* @description 메뉴 메타 정보
|
|
23
|
+
****************************
|
|
24
|
+
* @type {Object}
|
|
25
|
+
*/
|
|
26
|
+
menuInfo: Object,
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @description 화면 라우팅 정보, 상세 뷰는 호출시에 route_name 변수를 설정하여 넘겨준다.
|
|
30
|
+
****************************
|
|
31
|
+
* @type {String}
|
|
32
|
+
*/
|
|
33
|
+
route_name: String,
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* 상세 폼 뷰 상위 데이터 ID, 상세 뷰는 호출시에 parent_id 변수를 설정하여 넘겨준다.
|
|
37
|
+
****************************
|
|
38
|
+
* @type {String}
|
|
39
|
+
*/
|
|
40
|
+
parent_id: String,
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @description 페이지 내 컴포넌트 여부, 상세 뷰는 호출시에 is_detail 변수를 설정하여 넘겨준다.
|
|
44
|
+
****************************
|
|
45
|
+
* @type {Boolean}
|
|
46
|
+
*/
|
|
47
|
+
is_detail: {
|
|
48
|
+
type: Boolean,
|
|
49
|
+
converter(value) {
|
|
50
|
+
return Boolean(value)
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @description 팝업 여부, 팝업 뷰는 호출시에 is_popup 변수를 설정하여 넘겨준다.
|
|
56
|
+
****************************
|
|
57
|
+
* @type {Boolean}
|
|
58
|
+
*/
|
|
59
|
+
is_popup: {
|
|
60
|
+
type: Boolean,
|
|
61
|
+
converter(value) {
|
|
62
|
+
return Boolean(value)
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @description 작업, 결제 관련 화면에서 호출 된 경우
|
|
68
|
+
****************************
|
|
69
|
+
* @type {Boolean}
|
|
70
|
+
*/
|
|
71
|
+
is_activity: {
|
|
72
|
+
type: Boolean,
|
|
73
|
+
converter(value) {
|
|
74
|
+
return Boolean(value)
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* @description 수정 불가 페이지
|
|
80
|
+
****************************
|
|
81
|
+
* @type {Boolean}
|
|
82
|
+
*/
|
|
83
|
+
is_readonly: {
|
|
84
|
+
type: Boolean,
|
|
85
|
+
converter(value) {
|
|
86
|
+
return Boolean(value)
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* @description 엘리먼트 (페이지 내 컴포넌트 혹은 팝업인 경우) 여부
|
|
94
|
+
********************************************************
|
|
95
|
+
* @returns {Boolean} 엘리먼트 여부
|
|
96
|
+
*/
|
|
97
|
+
get isElement() {
|
|
98
|
+
return this.is_detail === true || this.is_popup === true
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* @description 페이지 내 포함된 하나의 컴포넌트 여부
|
|
103
|
+
*******************************************
|
|
104
|
+
* @returns {Boolean} 컴포넌트 여부
|
|
105
|
+
*/
|
|
106
|
+
get isDetail() {
|
|
107
|
+
return ValueUtil.isEmpty(this.is_detail) ? false : this.is_detail
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* @description 시나리오 기반 데이터 변경 이벤트 핸들러
|
|
112
|
+
**********************************************
|
|
113
|
+
*/
|
|
114
|
+
async dataChangeEventHandler(e) {
|
|
115
|
+
// 이벤트 디테일 추출
|
|
116
|
+
let { after, before, column, record, row } = e.detail
|
|
117
|
+
|
|
118
|
+
// 데이터 변경 컬럼 명
|
|
119
|
+
let columnName = column.name
|
|
120
|
+
// 해당 컬럼에 컬럼 변경 핸들러가 등록되어 있다면 해당 컬럼 변경 이벤트 핸들러 (시나리오)를 실행
|
|
121
|
+
if (Object.keys(this.fieldChangeHandlers || {}).includes(columnName)) {
|
|
122
|
+
let response = await MetaApi.callScenario(
|
|
123
|
+
columnName,
|
|
124
|
+
this.fieldChangeHandlers[columnName],
|
|
125
|
+
{
|
|
126
|
+
columnName,
|
|
127
|
+
column,
|
|
128
|
+
record,
|
|
129
|
+
after,
|
|
130
|
+
before,
|
|
131
|
+
row,
|
|
132
|
+
parentId: this.parent_id ? this.parent_id : ''
|
|
133
|
+
},
|
|
134
|
+
false
|
|
135
|
+
)
|
|
136
|
+
let result = response.data.runScenario.result.result
|
|
137
|
+
if (!result) return
|
|
138
|
+
|
|
139
|
+
// 이벤트 타겟 추출
|
|
140
|
+
let eventTarget = this.grist ? this.grist.grist.body : this
|
|
141
|
+
// 이벤트 타겟에 필드 변경 이벤트 전파
|
|
142
|
+
Object.keys(result).forEach(key => {
|
|
143
|
+
eventTarget.dispatchEvent(
|
|
144
|
+
new CustomEvent('field-change', {
|
|
145
|
+
bubbles: true,
|
|
146
|
+
composed: true,
|
|
147
|
+
detail: {
|
|
148
|
+
record,
|
|
149
|
+
row,
|
|
150
|
+
after: result[key],
|
|
151
|
+
before: record[key],
|
|
152
|
+
column: { name: key }
|
|
153
|
+
}
|
|
154
|
+
})
|
|
155
|
+
)
|
|
156
|
+
})
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// 데이터 변경 이벤트 전파
|
|
160
|
+
this.dispatchEvent(
|
|
161
|
+
new CustomEvent('data-changed', {
|
|
162
|
+
bubbles: true,
|
|
163
|
+
composed: true,
|
|
164
|
+
detail: e.detail
|
|
165
|
+
})
|
|
166
|
+
)
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* @override connectedCallback
|
|
171
|
+
********************************
|
|
172
|
+
*/
|
|
173
|
+
async connectedCallback() {
|
|
174
|
+
if (super.connectedCallback) {
|
|
175
|
+
await super.connectedCallback()
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// meta-form 계열인 경우 form-field-change 이벤트에 대한 핸들러를 등록
|
|
179
|
+
if (this.tagName.toLowerCase().startsWith('meta-form-')) {
|
|
180
|
+
this.addEventListener('form-field-change', async e => {
|
|
181
|
+
await this.dataChangeEventHandler(e)
|
|
182
|
+
})
|
|
183
|
+
// 그렇지 않으면 field-change 이벤트에 대한 핸들러를 등록
|
|
184
|
+
} else {
|
|
185
|
+
this.addEventListener('field-change', async e => {
|
|
186
|
+
await this.dataChangeEventHandler(e)
|
|
187
|
+
})
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* @override pageUpdated : URL 파라미터에 대한 triggering
|
|
193
|
+
******************************************************
|
|
194
|
+
* @returns
|
|
195
|
+
*/
|
|
196
|
+
async pageUpdated(changes, lifecycle, before) {
|
|
197
|
+
let navParams = this.lifecycle?.params ? this.lifecycle.params : {}
|
|
198
|
+
if (this.isPage && this.active && before.active == false && ValueUtil.isNotEmpty(navParams)) {
|
|
199
|
+
this.fetch()
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* @description 팝업으로 오픈되었는지 여부
|
|
205
|
+
*************************************
|
|
206
|
+
* @returns {Boolean} 팝업 오픈 여부
|
|
207
|
+
*/
|
|
208
|
+
get isPopup() {
|
|
209
|
+
return ValueUtil.isEmpty(this.is_popup) ? false : this.is_popup
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* @description 페이지 여부 리턴 (마스터 디테일의 디테일 엘리먼트나 팝업 화면은 페이지가 아니다.)
|
|
214
|
+
* - 페이지란 라우트 정보를 가지는 페이지를 뜻한다.
|
|
215
|
+
******************************************
|
|
216
|
+
* @returns {Boolean} 페이지 여부
|
|
217
|
+
*/
|
|
218
|
+
get isPage() {
|
|
219
|
+
return !this.is_detail && !this.is_popup
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* @description 메뉴 메타 정보 조회 && 화면 생성을 위한 Configuration 구성
|
|
224
|
+
*****************************************************************
|
|
225
|
+
* @returns {Object} 화면 생성을 위한 메타 정보 리턴
|
|
226
|
+
*/
|
|
227
|
+
async getAndParseMenuMeta() {
|
|
228
|
+
let menuMeta = await MetaApi.getMenuMeta(this)
|
|
229
|
+
|
|
230
|
+
if (menuMeta) {
|
|
231
|
+
// 기본 메뉴 정보
|
|
232
|
+
this.menuInfo = menuMeta.menu
|
|
233
|
+
// 기타 설정
|
|
234
|
+
this.etcConfig = menuMeta.etc
|
|
235
|
+
|
|
236
|
+
// 그리드 정보 파싱
|
|
237
|
+
if (this.parseBasicGridConfigs) {
|
|
238
|
+
this.parseBasicGridConfigs(menuMeta)
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// GraphQL 이용을 위한 서비스 Configuration
|
|
242
|
+
if (this.parseBasicServiceConfigs) {
|
|
243
|
+
this.parseBasicServiceConfigs(menuMeta)
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// 폼 정보 구성을 위한 폼 Configuration
|
|
247
|
+
if (this.parseBasicFormConfigs) {
|
|
248
|
+
this.parseBasicFormConfigs(menuMeta)
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// MetaTabMixin
|
|
252
|
+
if (this.parseBasicTabConfigs) {
|
|
253
|
+
this.parseBasicTabConfigs(menuMeta)
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// 버튼 정보 파싱
|
|
257
|
+
if (this.parseBasicButtonConfigs) {
|
|
258
|
+
this.parseBasicButtonConfigs(menuMeta)
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* @description 화면에 구성된 콤포넌트에 따라 조회를 호출
|
|
265
|
+
***********************************************
|
|
266
|
+
*/
|
|
267
|
+
async fetch() {
|
|
268
|
+
if (ValueUtil.isNotEmpty(this.grist)) {
|
|
269
|
+
this.grist.fetch()
|
|
270
|
+
} else if (ValueUtil.isNotEmpty(this.filterForm)) {
|
|
271
|
+
await this.fetchHandler()
|
|
272
|
+
} else if (this.fetchHandler) {
|
|
273
|
+
await this.fetchHandler()
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* @description 팝업 오픈 버튼 처리
|
|
279
|
+
********************************
|
|
280
|
+
* @param {Object} action
|
|
281
|
+
* @param {Object} record
|
|
282
|
+
* @param {Function} closeCallback
|
|
283
|
+
*/
|
|
284
|
+
async excuteOpenPopupButtonClick(action, record, closeCallback) {
|
|
285
|
+
// 타이틀 변환
|
|
286
|
+
let title = TermsUtil.tTitle(action.title)
|
|
287
|
+
|
|
288
|
+
// 타이틀 상세 필드 정의 확인
|
|
289
|
+
if (ValueUtil.isNotEmpty(action.title_detail)) {
|
|
290
|
+
title = `${title}-${ValueUtil.getParams(record, ...action.title_detail.split('.'))}`
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// 팝업 오픈
|
|
294
|
+
MetaApi.openDynamicPopup(title, action, record, closeCallback)
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* @description 시나리오 호출 버튼 처리
|
|
299
|
+
***********************************
|
|
300
|
+
* @param {Object} action
|
|
301
|
+
* @param {Object or Array} params
|
|
302
|
+
* @param {Function} afterCallback
|
|
303
|
+
*/
|
|
304
|
+
async executeCallScenarioButtonClick(action, params, afterCallback) {
|
|
305
|
+
// 시나리오 호출
|
|
306
|
+
let response = await MetaApi.callScenario(action.name, action.name, params)
|
|
307
|
+
|
|
308
|
+
// 처리 중 에러가 발생했으면 시나리오 호출 후 처리가 없으면 return
|
|
309
|
+
if (response !== false && !response.errors && ValueUtil.isNotEmpty(action.after)) {
|
|
310
|
+
afterCallback()
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* @description 상위 페이지 에서 하위 엘리먼트로 전달하는 ID 저장 및 조회 실행
|
|
316
|
+
***********************************
|
|
317
|
+
* @param {String} id
|
|
318
|
+
*/
|
|
319
|
+
setParentId(id) {
|
|
320
|
+
this.parent_id = id
|
|
321
|
+
this.fetch()
|
|
322
|
+
}
|
|
323
|
+
}
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import '@operato/data-grist'
|
|
2
|
+
|
|
3
|
+
import { html } from 'lit'
|
|
4
|
+
|
|
5
|
+
import { MetaApi } from '../utils/meta-api'
|
|
6
|
+
import { MetaUiUtil } from '../utils/meta-ui-util'
|
|
7
|
+
import { ValueUtil } from '../utils/value-util'
|
|
8
|
+
import { TermsUtil } from '../utils/terms-util'
|
|
9
|
+
|
|
10
|
+
import { MetaButtonMixin } from './meta-button-mixin'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @description 메뉴 메타 정보를 이용해 그리드를 렌더링
|
|
14
|
+
******************************************************
|
|
15
|
+
* @param {Object} MetaButtonMixin
|
|
16
|
+
* @returns
|
|
17
|
+
*/
|
|
18
|
+
export const MetaBasicGristMixin = baseElement =>
|
|
19
|
+
class extends MetaButtonMixin(baseElement) {
|
|
20
|
+
/**
|
|
21
|
+
* @description 스타일 정의
|
|
22
|
+
**************************
|
|
23
|
+
* @returns {Array} 스타일
|
|
24
|
+
*/
|
|
25
|
+
static get styles() {
|
|
26
|
+
return MetaApi.getBasicGristStyles()
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @description 프로퍼티 정의
|
|
31
|
+
***************************************
|
|
32
|
+
* @returns {Object} 프로퍼티
|
|
33
|
+
*/
|
|
34
|
+
static get properties() {
|
|
35
|
+
return {
|
|
36
|
+
/**
|
|
37
|
+
* @description 그리드 구성 정보
|
|
38
|
+
*****************************
|
|
39
|
+
* @type {Object}
|
|
40
|
+
*/
|
|
41
|
+
gridConfig: Object,
|
|
42
|
+
/**
|
|
43
|
+
* @description 그리드 컬럼 구성 정보
|
|
44
|
+
*********************************
|
|
45
|
+
* @type {Array}
|
|
46
|
+
*/
|
|
47
|
+
gridColumnConfig: Array,
|
|
48
|
+
/**
|
|
49
|
+
* @description 검색 폼 구성 정보
|
|
50
|
+
*******************************
|
|
51
|
+
* @type {Array}
|
|
52
|
+
*/
|
|
53
|
+
searchConfig: Array,
|
|
54
|
+
/**
|
|
55
|
+
* @description 화면에서 사용되는 서치 폼 : grist, filter, not
|
|
56
|
+
*********************************************************
|
|
57
|
+
* @type {String}
|
|
58
|
+
*/
|
|
59
|
+
searchFormElement: String,
|
|
60
|
+
/**
|
|
61
|
+
* @description 메뉴 메타 정보로 부터 추출한 후 그리스트를 위해 설정 정보 구성
|
|
62
|
+
*****************************************************************
|
|
63
|
+
* @type {Object}
|
|
64
|
+
*/
|
|
65
|
+
gristConfigSet: Object,
|
|
66
|
+
/**
|
|
67
|
+
* @description 필터 폼 사용 여부
|
|
68
|
+
*****************************
|
|
69
|
+
* @type {Boolean}
|
|
70
|
+
*/
|
|
71
|
+
useFilterForm: Boolean,
|
|
72
|
+
/**
|
|
73
|
+
* @description 모바일 기기에서 그리드 모드 : GRID, LIST, CARD
|
|
74
|
+
*********************************************************
|
|
75
|
+
* @type {String}
|
|
76
|
+
*/
|
|
77
|
+
gridMobileMode: String,
|
|
78
|
+
/**
|
|
79
|
+
* @description 데스크탑에서 그리드 모드 : GRID, LIST, CARD
|
|
80
|
+
******************************************************
|
|
81
|
+
* @type {String}
|
|
82
|
+
*/
|
|
83
|
+
gridDeskMode: String,
|
|
84
|
+
/**
|
|
85
|
+
* @description 그리드 뷰 모드 : GRID, LIST, CARD
|
|
86
|
+
**********************************************
|
|
87
|
+
* @type {Array}
|
|
88
|
+
*/
|
|
89
|
+
gridViewOptions: Array,
|
|
90
|
+
/**
|
|
91
|
+
* @description 현재 그리드 뷰 모드 : GRID, LIST, CARD
|
|
92
|
+
***************************************************
|
|
93
|
+
* @type {String}
|
|
94
|
+
*/
|
|
95
|
+
gridMode: String,
|
|
96
|
+
/**
|
|
97
|
+
* @description Infinity Page 사용 여부
|
|
98
|
+
**************************************
|
|
99
|
+
* @type {Boolean}
|
|
100
|
+
*/
|
|
101
|
+
infinityPage: Boolean,
|
|
102
|
+
/**
|
|
103
|
+
* @description 그리스트 엘리먼트 ID
|
|
104
|
+
***************************
|
|
105
|
+
* @type {String}
|
|
106
|
+
*/
|
|
107
|
+
gristId: String,
|
|
108
|
+
/**
|
|
109
|
+
* @description 필터 폼 엘리먼트 ID
|
|
110
|
+
***************************
|
|
111
|
+
* @type {String}
|
|
112
|
+
*/
|
|
113
|
+
filterFormId: String
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* @description 그리스트
|
|
119
|
+
***********************
|
|
120
|
+
* @returns {HTMLElement}
|
|
121
|
+
*/
|
|
122
|
+
get grist() {
|
|
123
|
+
return this.renderRoot?.querySelector(this.gristId)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* @description 필터 폼
|
|
128
|
+
***********************
|
|
129
|
+
* @returns {HTMLElement}
|
|
130
|
+
*/
|
|
131
|
+
get filterForm() {
|
|
132
|
+
return this.shadowRoot?.querySelector(this.filterFormId)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* @description 컨텍스트
|
|
137
|
+
***********************
|
|
138
|
+
* @returns {HTMLElement}
|
|
139
|
+
*/
|
|
140
|
+
get context() {
|
|
141
|
+
return MetaUiUtil.getContextObject(this)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/******************************************************
|
|
145
|
+
* LifeCycle
|
|
146
|
+
******************************************************/
|
|
147
|
+
|
|
148
|
+
async connectedCallback() {
|
|
149
|
+
// 그리스트, 필터 폼 ID 설정
|
|
150
|
+
this.gristId = 'ox-grist'
|
|
151
|
+
this.filterFormId = 'ox-filters-form'
|
|
152
|
+
|
|
153
|
+
// 메뉴 메타 정보 조회 및 기본 파싱
|
|
154
|
+
await this.getAndParseMenuMeta()
|
|
155
|
+
|
|
156
|
+
if (this.isElement) {
|
|
157
|
+
await this.parseGristConfigs()
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (this.activityDataSet) {
|
|
161
|
+
this.dataSet = this.activityDataSet
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (super.connectedCallback) {
|
|
165
|
+
await super.connectedCallback()
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
async firstUpdated() {
|
|
170
|
+
if (super.firstUpdated) {
|
|
171
|
+
await super.firstUpdated()
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
async pageInitialized(lifecycle) {
|
|
176
|
+
if (this.isPage) {
|
|
177
|
+
await this.parseGristConfigs()
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (super.pageInitialized) {
|
|
181
|
+
await super.pageInitialized()
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
async pageUpdated(changes, lifecycle, before) {
|
|
186
|
+
if (this.active) {
|
|
187
|
+
/* this page is activated */
|
|
188
|
+
if (this.gridConfig.grid_refresh_when_page_activated) {
|
|
189
|
+
this.fetch()
|
|
190
|
+
}
|
|
191
|
+
} else {
|
|
192
|
+
/* this page is deactivated */
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
render() {
|
|
197
|
+
return html` ${MetaApi.getBasicGristHtml(this)} ${this.isPage ? html`` : MetaUiUtil.getButtonContainer(this)} `
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* @descrtiption 메뉴 메타에서 기본 그리드 정보 파싱 처리
|
|
202
|
+
************************************************
|
|
203
|
+
* @param {Object} menuMeta 메뉴 메타 정보
|
|
204
|
+
*/
|
|
205
|
+
parseBasicGridConfigs(menuMeta) {
|
|
206
|
+
this.gridConfig = menuMeta.grid
|
|
207
|
+
this.gridColumnConfig = menuMeta.grid_column
|
|
208
|
+
this.searchConfig = menuMeta.search
|
|
209
|
+
this.gridEmphasized = menuMeta.gridEmphasized
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* @descrtiption 그리스트 구성 정보 파싱 처리
|
|
214
|
+
***************************************
|
|
215
|
+
*/
|
|
216
|
+
async parseGristConfigs() {
|
|
217
|
+
this.gristConfigSet = await MetaApi.parseGridConfigSet(this)
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/********************************************************************
|
|
221
|
+
* C R U D Functions
|
|
222
|
+
********************************************************************/
|
|
223
|
+
|
|
224
|
+
async fetch() {
|
|
225
|
+
await this.grist.fetch()
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
back() {
|
|
229
|
+
history.back()
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
async save() {
|
|
233
|
+
let patches = MetaApi.patchesForUpdateMultiple(this.grist)
|
|
234
|
+
let result = ValueUtil.isNotEmpty(patches) ? await this.updateMultiple(patches) : false
|
|
235
|
+
if (result) {
|
|
236
|
+
this.fetch()
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
async find() {
|
|
241
|
+
let ids = MetaApi.getSelectedIdList(this.grist, true)
|
|
242
|
+
return ValueUtil.isNotEmpty(ids) ? await this.findOne(ids[0]) : {}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
async delete() {
|
|
246
|
+
let ids = MetaApi.getSelectedIdList(this.grist, true)
|
|
247
|
+
let result = ValueUtil.isNotEmpty(ids) ? await this.deleteByIds(ids) : false
|
|
248
|
+
if (result) {
|
|
249
|
+
this.fetch()
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
async export() {
|
|
254
|
+
let exportTitle = TermsUtil.tTitle(ValueUtil.getParams(this.menuInfo, 'title'))
|
|
255
|
+
return await MetaApi.exportableData(this.isElement, exportTitle, this.grist)
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
async import() {
|
|
259
|
+
// TODO
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
async clear() {
|
|
263
|
+
if (this.grist) {
|
|
264
|
+
this.grist.data = { page: 0, total: 0, limit: 0, records: [] }
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
getData() {
|
|
269
|
+
let records = this.grist.___data.records
|
|
270
|
+
records = JSON.parse(JSON.stringify(records))
|
|
271
|
+
|
|
272
|
+
records.forEach(record => {
|
|
273
|
+
let keys = Object.keys(record)
|
|
274
|
+
keys.forEach(x => {
|
|
275
|
+
if (x.startsWith('__')) {
|
|
276
|
+
delete record[x]
|
|
277
|
+
}
|
|
278
|
+
})
|
|
279
|
+
})
|
|
280
|
+
|
|
281
|
+
return records
|
|
282
|
+
}
|
|
283
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { html } from 'lit'
|
|
2
|
+
|
|
3
|
+
import { MetaUiUtil } from '../utils/meta-ui-util'
|
|
4
|
+
|
|
5
|
+
import { MetaServiceMixin } from './meta-service-mixin'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @license
|
|
9
|
+
* Copyright © HatioLab Inc. All rights reserved.
|
|
10
|
+
* @author Shortstop shortstop@hatiolab.com
|
|
11
|
+
* @description 메뉴 메타 기반 버튼 렌더링 & 이벤트 처리
|
|
12
|
+
*/
|
|
13
|
+
export const MetaButtonMixin = (baseElement) => class extends MetaServiceMixin(baseElement) {
|
|
14
|
+
/**
|
|
15
|
+
* @description 프로퍼티
|
|
16
|
+
***********************
|
|
17
|
+
*/
|
|
18
|
+
static get properties() {
|
|
19
|
+
return {
|
|
20
|
+
/**
|
|
21
|
+
* @description 버튼 구성 정보
|
|
22
|
+
***************************
|
|
23
|
+
* @type {Array}
|
|
24
|
+
*/
|
|
25
|
+
buttonConfig: Array,
|
|
26
|
+
/**
|
|
27
|
+
* @description 내보내기 버튼 사용 여부
|
|
28
|
+
**********************************
|
|
29
|
+
* @type {Array}
|
|
30
|
+
*/
|
|
31
|
+
useButtonExport: Boolean,
|
|
32
|
+
/**
|
|
33
|
+
* @description 가져오기 버튼 사용 여부
|
|
34
|
+
**********************************
|
|
35
|
+
* @type {Array}
|
|
36
|
+
*/
|
|
37
|
+
useButtonImport: Boolean,
|
|
38
|
+
/**
|
|
39
|
+
* @description 추가 버튼 사용 여부
|
|
40
|
+
*******************************
|
|
41
|
+
* @type {Boolean}
|
|
42
|
+
*/
|
|
43
|
+
useButtonAdd: Boolean
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @description 커스텀 버튼 컨테이너 스타일 리턴
|
|
49
|
+
*****************************************
|
|
50
|
+
*/
|
|
51
|
+
getCustomButtonContainerStyle() {
|
|
52
|
+
return MetaUiUtil.getCustomButtonContainerStyles()
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @description 메뉴 컨텍스트에서 사용할 버튼 정보 추출
|
|
57
|
+
**********************************************
|
|
58
|
+
* @returns {Array}
|
|
59
|
+
*/
|
|
60
|
+
getContextButtons() {
|
|
61
|
+
return MetaUiUtil.getContextButtons(this)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @description 버튼 컨테이너 HTML 리턴
|
|
66
|
+
***********************************
|
|
67
|
+
* @returns {HTML}
|
|
68
|
+
*/
|
|
69
|
+
getButtonContainer() {
|
|
70
|
+
return this.isPage ? html`` : MetaUiUtil.getButtonContainer(this)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* @description 버튼과 연결될 핸들러를 리턴 - TODO 사용 안 하는 거 같으므로 확인 후 삭제 필요
|
|
75
|
+
*************************************
|
|
76
|
+
* @param {String} type
|
|
77
|
+
* @param {String} action
|
|
78
|
+
* @param {Object} logic
|
|
79
|
+
* @returns {Object}
|
|
80
|
+
*/
|
|
81
|
+
async getBasicButtonHandler(type, action, logic) {
|
|
82
|
+
return await MetaUiUtil.getButtonActionHandler(this, type, action, logic)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @description 커스텀 버튼에 대한 액션 분기 - TODO 사용 안 하는 거 같으므로 확인 후 삭제 필요
|
|
87
|
+
**************************************
|
|
88
|
+
* @param {Object} logic
|
|
89
|
+
*/
|
|
90
|
+
async customButtonHandler(logic) {
|
|
91
|
+
await MetaUiUtil.customButtonHandler(this, null, logic)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* @description 그리스트 버튼에 대한 커스텀 액션 분기 - TODO 사용 안 하는 거 같으므로 확인 후 삭제 필요
|
|
96
|
+
********************************************
|
|
97
|
+
* @param {Object} actionInfo
|
|
98
|
+
* @param {Object} record
|
|
99
|
+
*/
|
|
100
|
+
async gristButtonHandler(actionInfo, record) {
|
|
101
|
+
await MetaUiUtil.gristButtonHandler(this, actionInfo, record)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* @description 그리스트 버튼에 대한 파싱 처리
|
|
106
|
+
***************************************
|
|
107
|
+
* @param {Object} menuMeta
|
|
108
|
+
*/
|
|
109
|
+
parseBasicButtonConfigs(menuMeta) {
|
|
110
|
+
this.buttonConfig = menuMeta.button
|
|
111
|
+
|
|
112
|
+
this.useButtonImport = MetaUiUtil.isButtonExist(this.buttonConfig, 'import')
|
|
113
|
+
this.useButtonExport = MetaUiUtil.isButtonExist(this.buttonConfig, 'export')
|
|
114
|
+
this.useButtonAdd = MetaUiUtil.isButtonExist(this.buttonConfig, 'add')
|
|
115
|
+
}
|
|
116
|
+
}
|