@things-factory/meta-ui 5.0.0-zeta.1
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/CHANGELOG.md +8 -0
- package/LICENSE.md +21 -0
- package/client/actions/main.js +1 -0
- package/client/bootstrap.js +8 -0
- package/client/index.js +23 -0
- package/client/mixin/handler-basic-button-mixin.js +202 -0
- package/client/mixin/handler-common-button-mixin.js +90 -0
- package/client/mixin/handler-custom-button-mixin.js +127 -0
- package/client/mixin/handler-graphql-mixin.js +297 -0
- package/client/mixin/handler-grist-button-mixin.js +119 -0
- package/client/mixin/meta-set-mixin.js +69 -0
- package/client/mixin/meta-util-mixin.js +577 -0
- package/client/mixin/render-basic-form-mixin.js +264 -0
- package/client/mixin/render-basic-grist-mixin.js +85 -0
- package/client/mixin/render-button-mixin.js +163 -0
- package/client/mixin/render-grist-mixin.js +478 -0
- package/client/mixin/render-search-mixin.js +37 -0
- package/client/pages/basic-form-element.js +9 -0
- package/client/pages/basic-grist-element.js +11 -0
- package/client/pages/basic-grist-page.js +12 -0
- package/client/pages/main.js +27 -0
- package/client/reducers/main.js +17 -0
- package/client/route.js +7 -0
- package/dist-server/controllers/index.js +1 -0
- package/dist-server/controllers/index.js.map +1 -0
- package/dist-server/index.js +20 -0
- package/dist-server/index.js.map +1 -0
- package/dist-server/middlewares/index.js +8 -0
- package/dist-server/middlewares/index.js.map +1 -0
- package/dist-server/migrations/index.js +12 -0
- package/dist-server/migrations/index.js.map +1 -0
- package/dist-server/routes.js +25 -0
- package/dist-server/routes.js.map +1 -0
- package/package.json +30 -0
- package/server/controllers/index.ts +0 -0
- package/server/index.ts +4 -0
- package/server/middlewares/index.ts +3 -0
- package/server/migrations/index.ts +9 -0
- package/server/routes.ts +28 -0
- package/things-factory.config.js +13 -0
- package/translations/en.json +1 -0
- package/translations/ko.json +1 -0
- package/translations/ms.json +1 -0
- package/translations/zh.json +1 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,577 @@
|
|
|
1
|
+
import { i18next } from '@operato/i18n'
|
|
2
|
+
import { navigate, CustomAlert } from '@things-factory/shell'
|
|
3
|
+
import { getCodeByName } from '@things-factory/code-base'
|
|
4
|
+
import { openPopup } from '@things-factory/layout-base'
|
|
5
|
+
import isEqual from 'lodash-es/isEqual'
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* 유틸리티
|
|
10
|
+
******************************************************
|
|
11
|
+
* @param {Object} baseElement
|
|
12
|
+
* @returns
|
|
13
|
+
*/
|
|
14
|
+
export const MetaUtilMixin = (baseElement) => class extends baseElement {
|
|
15
|
+
|
|
16
|
+
static get properties() {
|
|
17
|
+
return {
|
|
18
|
+
/* 메뉴 메타 정보 */
|
|
19
|
+
menuInfo: Object, // 메뉴 기본 정보
|
|
20
|
+
gridConfig: Object, // 그리드 구성 정보
|
|
21
|
+
gridColumnConfig: Array, // 그리드 컬럼 정보
|
|
22
|
+
formColumnConfig: Array, // form 컬럼 정보
|
|
23
|
+
buttonConfig: Array, // 버튼 구성 정보
|
|
24
|
+
searchConfig: Array, // 서치폼 구성 정보
|
|
25
|
+
gqlInfo: String, // GraphQL 정보
|
|
26
|
+
gqlFetchField: String, // GraphQL 조회 필드
|
|
27
|
+
searchFormElement: String, // 화면에서 사용 되는 서치폼 (grist, filter, not)
|
|
28
|
+
|
|
29
|
+
/* 화면 구성 */
|
|
30
|
+
gristConfigSet: Object, // 메타정보에서 변환된 그리드 구성 정보
|
|
31
|
+
formConfigSet: Array, // 메타정보에서 변환된 폼 구성 정보
|
|
32
|
+
use_button_export: Boolean, // 내보내기 버튼 사용 여부
|
|
33
|
+
use_button_import: Boolean, // 가져오기 버튼 사용 여부
|
|
34
|
+
use_button_add: Boolean, // 추가 버튼 사용 여부
|
|
35
|
+
grid_mobile_mode: String, // 모바일 기기에서 그리드 뷰
|
|
36
|
+
grid_desk_mode: String, // 데스크탑에서 그리드 뷰
|
|
37
|
+
grid_view_options: Array, // 그리드 뷰 옵션
|
|
38
|
+
grid_mode: String, // 현재 그리드 뷰 모드
|
|
39
|
+
infinity_page: true, // 페이지 사용시 false
|
|
40
|
+
|
|
41
|
+
/* 속성 ? */
|
|
42
|
+
is_detail: { // 페이지내 컴포넌트 여부
|
|
43
|
+
type: Boolean,
|
|
44
|
+
converter(value) {
|
|
45
|
+
let retVal = Boolean(value);
|
|
46
|
+
return retVal;
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
is_popup: { // 팝업 여부
|
|
50
|
+
type: Boolean,
|
|
51
|
+
converter(value) {
|
|
52
|
+
let retVal = Boolean(value);
|
|
53
|
+
return retVal;
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
parent_id: String, // 상세 폼뷰 상위 데이터 ID
|
|
58
|
+
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* 페이지내 컴포넌트 이거나 팝업으로 오픈된 경우
|
|
64
|
+
*/
|
|
65
|
+
get isElement() {
|
|
66
|
+
return (this.isDetail === true || this.isPopup === true);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* isDetail 여부 리턴 (페이지내 포함된 하나의 컴포넌트)
|
|
71
|
+
*/
|
|
72
|
+
get isDetail() {
|
|
73
|
+
return this.isEmpty(this.is_detail) ? false : this.is_detail;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Popup 오픈 여부 리턴
|
|
78
|
+
*/
|
|
79
|
+
get isPopup() {
|
|
80
|
+
return this.isEmpty(this.is_popup) ? false : this.is_popup;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* 페이지 여부 리턴
|
|
85
|
+
*/
|
|
86
|
+
get isPage() {
|
|
87
|
+
return (this.isDetail === false && this.isPopup === false);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Document 내의 attribute 변화를 감지 및 로깅 (개발용)
|
|
93
|
+
**************************************
|
|
94
|
+
* @param {String} name
|
|
95
|
+
* @param {*} oldVal
|
|
96
|
+
* @param {*} newVal
|
|
97
|
+
*/
|
|
98
|
+
attributeChangedCallback(name, oldVal, newVal) {
|
|
99
|
+
console.log(this.tagName, 'attribute change: ', name, oldVal, newVal);
|
|
100
|
+
super.attributeChangedCallback(name, oldVal, newVal);
|
|
101
|
+
|
|
102
|
+
if (name === 'context-path' && this.active === true && this.isNotEmpty(this.contextPath)) {
|
|
103
|
+
// 페이지 링크 URL 을 서치폼에 셋팅한다.
|
|
104
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
105
|
+
|
|
106
|
+
if (this.isNotEmpty(urlParams)) {
|
|
107
|
+
urlParams.forEach((value, key) => {
|
|
108
|
+
this.setSearchFormEditorValue(key, value);
|
|
109
|
+
})
|
|
110
|
+
this.grist.fetch();
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* 서치폼 ( grist or filter or undefined) 을 찾아 에디터에 값을 셋팅
|
|
118
|
+
*****************************************************
|
|
119
|
+
* @param {String} name
|
|
120
|
+
* @param {Object} value
|
|
121
|
+
*/
|
|
122
|
+
setSearchFormEditorValue(name, value) {
|
|
123
|
+
let filterForm = this.filterForm;
|
|
124
|
+
|
|
125
|
+
if (this.isNotEmpty(filterForm)) {
|
|
126
|
+
let filterEditor = filterForm.renderRoot?.querySelector(`[name='${name}']`);
|
|
127
|
+
|
|
128
|
+
if (this.isNotEmpty(filterEditor)) {
|
|
129
|
+
filterEditor.value = value;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* 메시지 코드 변환
|
|
136
|
+
* @param {String} code
|
|
137
|
+
* @returns
|
|
138
|
+
*/
|
|
139
|
+
convertMsgCode(code) {
|
|
140
|
+
return i18next.t(code);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* logic 에 포함된 element 정보를 이용해 팝업을 연다
|
|
146
|
+
*************************************************
|
|
147
|
+
* @description
|
|
148
|
+
* @param {String} title 팝업 이름
|
|
149
|
+
* @param {Object} logic { "module": '', "location": '', "tagname": '', size : '', popup_field: '', parent_field: ''}
|
|
150
|
+
* @param {Object} paramData
|
|
151
|
+
*/
|
|
152
|
+
async openDynamicPopup(title, logic, paramData) {
|
|
153
|
+
|
|
154
|
+
// import
|
|
155
|
+
await this.dynamicImport(logic.module, logic.location);
|
|
156
|
+
|
|
157
|
+
let parentValue = undefined;
|
|
158
|
+
|
|
159
|
+
if (this.isNotEmpty(logic.parent_field)) {
|
|
160
|
+
parentValue = paramData[logic.parent_field];
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// element 생성
|
|
164
|
+
let htmlText = `<${logic.tagname} route_name='${logic.menu}' parent_id='${parentValue}' is_popup=true></${logic.tagname}>`;
|
|
165
|
+
let htmlElemnts = this.htmlToElement(htmlText);
|
|
166
|
+
|
|
167
|
+
// 파라미터 설정
|
|
168
|
+
if (this.isNotEmpty(logic.popup_field)) {
|
|
169
|
+
htmlElemnts[logic.popup_field] = paramData;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// 팝업 오픈
|
|
173
|
+
let popup = openPopup(htmlElemnts, {
|
|
174
|
+
backdrop: true,
|
|
175
|
+
size: logic.size,
|
|
176
|
+
title: title
|
|
177
|
+
})
|
|
178
|
+
popup.onclosed = async (e) => {
|
|
179
|
+
// 팝업이 닫히면 조회
|
|
180
|
+
await this.fetch();
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* js 다이다믹 임포트
|
|
189
|
+
* module 이 미리 지정 되어 있어야 한다.
|
|
190
|
+
**************************************
|
|
191
|
+
* @param {String} module
|
|
192
|
+
* @param {String} url
|
|
193
|
+
*/
|
|
194
|
+
async dynamicImport(module, url) {
|
|
195
|
+
// 페이지 import 요청 이벤트 전파
|
|
196
|
+
document.dispatchEvent(new CustomEvent('dynamic-page-import-request', {
|
|
197
|
+
detail: {
|
|
198
|
+
module: module,
|
|
199
|
+
url: url
|
|
200
|
+
}
|
|
201
|
+
}))
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* 페이지를 이동 한다 .
|
|
206
|
+
**************************************
|
|
207
|
+
* @param {String} url
|
|
208
|
+
* @param {Object} params undefined or Object
|
|
209
|
+
*/
|
|
210
|
+
pageNavite(url, params) {
|
|
211
|
+
if (params) {
|
|
212
|
+
let paramStr = '';
|
|
213
|
+
|
|
214
|
+
Object.keys(params).forEach(x => {
|
|
215
|
+
paramStr += `${x}=${params[x]}&`
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
navigate(`${url}?${paramStr}`)
|
|
219
|
+
} else {
|
|
220
|
+
navigate(url);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* 공통 코드를 조회해 서치폼, 그리드에서 표현 가능한 데이터로 변환 한다.
|
|
226
|
+
************************************************************
|
|
227
|
+
* @param {String} name
|
|
228
|
+
* @returns
|
|
229
|
+
*/
|
|
230
|
+
async getCommonCodesByName(name) {
|
|
231
|
+
let codes = await getCodeByName(name);
|
|
232
|
+
let options = [
|
|
233
|
+
{ value: '', display: '' }
|
|
234
|
+
]
|
|
235
|
+
|
|
236
|
+
codes.forEach(x => {
|
|
237
|
+
options.push({
|
|
238
|
+
value: x.name,
|
|
239
|
+
display: x.description
|
|
240
|
+
})
|
|
241
|
+
})
|
|
242
|
+
|
|
243
|
+
return options;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* 시나리오를 호출해 코드 정보를 가져온다.
|
|
249
|
+
****************************************
|
|
250
|
+
* @description 시나리오에서는 name, description 필드를 리턴해 줘야 한다.
|
|
251
|
+
* @param {String} name
|
|
252
|
+
* @param {Array} args
|
|
253
|
+
*/
|
|
254
|
+
async getCodeByScenario(name, args) {
|
|
255
|
+
let codes = await this.gqlCallScenario(name, args);
|
|
256
|
+
let options = [
|
|
257
|
+
{ value: '', display: '' }
|
|
258
|
+
]
|
|
259
|
+
|
|
260
|
+
codes.forEach(x => {
|
|
261
|
+
options.push({
|
|
262
|
+
value: x.name,
|
|
263
|
+
display: x.description
|
|
264
|
+
})
|
|
265
|
+
})
|
|
266
|
+
|
|
267
|
+
return options;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* dataObject 에서 key 값을 찾아 isTransMsg 옵션을 적용해 retObjct 에 반영 한다. *
|
|
272
|
+
* *********************************************************************
|
|
273
|
+
* @param {Object} retObj
|
|
274
|
+
* @param {Object} dataObj
|
|
275
|
+
* @param {String} key
|
|
276
|
+
* @param {Boolean} isTransMsg
|
|
277
|
+
* @returns
|
|
278
|
+
*/
|
|
279
|
+
setParams(retObj, dataObj, key, isTransMsg) {
|
|
280
|
+
let value = this.getParams(dataObj, key);
|
|
281
|
+
|
|
282
|
+
if (this.isNotEmpty(value)) {
|
|
283
|
+
retObj[key] = isTransMsg === true ? this.convertMsgCode(value) : value;
|
|
284
|
+
}
|
|
285
|
+
return retObj;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* data 에서 key(Array) 를 찾아 리턴
|
|
290
|
+
************************************
|
|
291
|
+
* @param {Object} data
|
|
292
|
+
* @param {...String} keys
|
|
293
|
+
* @returns
|
|
294
|
+
*/
|
|
295
|
+
getParams(data, ...keys) {
|
|
296
|
+
// keys 파라미터가 없으면 return
|
|
297
|
+
if (arguments.length <= 1) {
|
|
298
|
+
return undefined;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
let key = keys[0];
|
|
302
|
+
// data 에 key 가 없으면 return
|
|
303
|
+
if (this.isEmpty(data[key])) {
|
|
304
|
+
return undefined;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
let paramData = data[key];
|
|
308
|
+
|
|
309
|
+
if (keys.length > 1) {
|
|
310
|
+
// 현재 이후에 키가 더 있으면 재귀 호출
|
|
311
|
+
return this.getParams(paramData, ...keys.slice(1));
|
|
312
|
+
} else {
|
|
313
|
+
return paramData;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* 버튼관 연결될 핸들러를 리턴 한다.
|
|
319
|
+
***********************
|
|
320
|
+
* @description 없으면 message 처리 .
|
|
321
|
+
* @param {String} type
|
|
322
|
+
* @param {String} action
|
|
323
|
+
* @param {Object} logic
|
|
324
|
+
*/
|
|
325
|
+
getButtonActionHandler(type, action, logic) {
|
|
326
|
+
if (type == 'basic') {
|
|
327
|
+
if (this[action]) {
|
|
328
|
+
return this[action].bind(this);
|
|
329
|
+
}
|
|
330
|
+
} else {
|
|
331
|
+
return () => this.customButtonHandler(logic);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// TODO 메시지 코드 처리
|
|
335
|
+
return () => {
|
|
336
|
+
this.showCustomAlert('label.info', '버튼과 연결된 함수가 없습니다.')
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* 토스트 메시지
|
|
343
|
+
* @param {String} textCode
|
|
344
|
+
*/
|
|
345
|
+
showToast(textCode) {
|
|
346
|
+
let message = this.convertMsgCode(textCode);
|
|
347
|
+
document.dispatchEvent(new CustomEvent('notify', { detail: { message } }))
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* alert 박스 보기
|
|
353
|
+
**************************************
|
|
354
|
+
* @param {String} titleCode
|
|
355
|
+
* @param {String} textCode
|
|
356
|
+
* @param {String} type
|
|
357
|
+
* @param {String} confirmButtonCode
|
|
358
|
+
* @param {String} cancelButtonCode
|
|
359
|
+
* @returns {Object}
|
|
360
|
+
*/
|
|
361
|
+
async showCustomAlert(titleCode, textCode, type, confirmButtonCode, cancelButtonCode) {
|
|
362
|
+
|
|
363
|
+
// alert 정보 생성
|
|
364
|
+
let alertObj = {
|
|
365
|
+
title: this.convertMsgCode(titleCode),
|
|
366
|
+
text: this.convertMsgCode(textCode)
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
if (this.isNotEmpty(type)) {
|
|
370
|
+
alertObj['type'] = type;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
if (this.isNotEmpty(confirmButtonCode)) {
|
|
374
|
+
alertObj['confirmButton'] = { text: this.convertMsgCode(confirmButtonCode) };
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
if (this.isNotEmpty(cancelButtonCode)) {
|
|
378
|
+
alertObj['cancelButton'] = { text: this.convertMsgCode(cancelButtonCode) };
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
return await CustomAlert(alertObj);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* object, string, number, array 빈 값 여부 검사
|
|
386
|
+
**************************************
|
|
387
|
+
* @param {Object} param
|
|
388
|
+
* @returns {Boolean}
|
|
389
|
+
*/
|
|
390
|
+
isEmpty(param) {
|
|
391
|
+
if (param === undefined) {
|
|
392
|
+
return true;
|
|
393
|
+
} else if (param === null) {
|
|
394
|
+
return true;
|
|
395
|
+
} else if (typeof param === 'boolean') {
|
|
396
|
+
return false;
|
|
397
|
+
} else if (typeof param === 'string' || typeof param === 'number') {
|
|
398
|
+
if (param == '') return true;
|
|
399
|
+
} else if (Array.isArray(param)) {
|
|
400
|
+
if (param.length == 0) return true;
|
|
401
|
+
} else if (typeof param === 'object') {
|
|
402
|
+
if (Object.keys(param).length == 0) return true;
|
|
403
|
+
}
|
|
404
|
+
return false;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* object, string, number, array 빈 값 isNot 여부 검사
|
|
409
|
+
**************************************
|
|
410
|
+
* @param {Object} param
|
|
411
|
+
* @returns {Boolean}
|
|
412
|
+
*/
|
|
413
|
+
isNotEmpty(param) {
|
|
414
|
+
if (param === undefined) {
|
|
415
|
+
return false;
|
|
416
|
+
} else if (param === null) {
|
|
417
|
+
return false;
|
|
418
|
+
} else if (typeof param === 'boolean') {
|
|
419
|
+
return true;
|
|
420
|
+
} else if (typeof param === 'string' || typeof param === 'number') {
|
|
421
|
+
if (param != '') return true;
|
|
422
|
+
} else if (Array.isArray(param)) {
|
|
423
|
+
if (param.length > 0) return true;
|
|
424
|
+
} else if (typeof param === 'object') {
|
|
425
|
+
if (Object.keys(param).length > 0) return true;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
return false;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* HTML 문자열을 elements 로 반환
|
|
434
|
+
**************************************
|
|
435
|
+
* @param {String} htmlString
|
|
436
|
+
* @returns {HTMLElement}
|
|
437
|
+
*/
|
|
438
|
+
htmlToElement(htmlString) {
|
|
439
|
+
var template = document.createElement('template');
|
|
440
|
+
template.innerHTML = htmlString;
|
|
441
|
+
var elements = template.content.childNodes;
|
|
442
|
+
var element = elements[0];
|
|
443
|
+
|
|
444
|
+
template.content.removeChild(element);
|
|
445
|
+
|
|
446
|
+
return element;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* 두 객체가 동일한지 비교
|
|
451
|
+
* @param {*} data1
|
|
452
|
+
* @param {*} data2
|
|
453
|
+
* @returns
|
|
454
|
+
*/
|
|
455
|
+
isEquals(data1, data2) {
|
|
456
|
+
return isEqual(data1, data2);
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* config, data 의 key 값을 비교 해 결과를 리턴한다.
|
|
462
|
+
* 값에 * 는 체크 하지 않는다.
|
|
463
|
+
****************************************
|
|
464
|
+
* @param {Object} config
|
|
465
|
+
* @param {Object} data
|
|
466
|
+
* @param {String Array} keys
|
|
467
|
+
* @returns
|
|
468
|
+
*/
|
|
469
|
+
compareObjectValues(config, data, keys) {
|
|
470
|
+
let isEquals = true;
|
|
471
|
+
|
|
472
|
+
keys.forEach(key => {
|
|
473
|
+
let compareValue = config[key];
|
|
474
|
+
|
|
475
|
+
if (compareValue === '*') {
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
let recordValue = data[key] || '';
|
|
480
|
+
|
|
481
|
+
if (this.isEmpty(compareValue)) {
|
|
482
|
+
if (this.isNotEmpty(recordValue)) {
|
|
483
|
+
isEquals = false;
|
|
484
|
+
}
|
|
485
|
+
} else {
|
|
486
|
+
if (compareValue != recordValue) {
|
|
487
|
+
isEquals = false;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
})
|
|
491
|
+
|
|
492
|
+
return isEquals;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* 메뉴 메타 정보에서 페이지 Context 정보 추출
|
|
498
|
+
***************************
|
|
499
|
+
* @description 메뉴 타이틀, 도움말, import, export, 각종 버튼들 포함
|
|
500
|
+
* @returns {Object}
|
|
501
|
+
*/
|
|
502
|
+
getContextObject() {
|
|
503
|
+
|
|
504
|
+
// 리턴 오브젝트
|
|
505
|
+
let retContext = { actions: [] };
|
|
506
|
+
// 기본 타이틀 및 도움말 설정
|
|
507
|
+
retContext = this.setParams(retContext, this.menuInfo, 'title', true);
|
|
508
|
+
retContext = this.setParams(retContext, this.menuInfo, 'help');
|
|
509
|
+
|
|
510
|
+
// 버튼 정보 추출
|
|
511
|
+
let buttons = this.getContextButtons();
|
|
512
|
+
|
|
513
|
+
// 버튼 context 오브젝트에 포함
|
|
514
|
+
retContext.actions.push(...buttons);
|
|
515
|
+
|
|
516
|
+
// 내보내기 버튼
|
|
517
|
+
if (this.use_button_export) {
|
|
518
|
+
retContext.exportable = {
|
|
519
|
+
name: retContext.title,
|
|
520
|
+
data: this._exportableData.bind(this)
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
// 임포트 버튼
|
|
525
|
+
if (this.use_button_import) {
|
|
526
|
+
retContext.importable = {
|
|
527
|
+
handler: this._importableData.bind(this)
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
return retContext;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
/**
|
|
537
|
+
* 화면에 구성된 콤포넌트에 따라 조회를 호출 한다.
|
|
538
|
+
*/
|
|
539
|
+
async fetch() {
|
|
540
|
+
if (this.isNotEmpty(this.grist)) {
|
|
541
|
+
this.grist.fetch();
|
|
542
|
+
} else if (this.isNotEmpty(this.filterForm)) {
|
|
543
|
+
await this.fetchHandler();
|
|
544
|
+
} else {
|
|
545
|
+
await this.fetchHandler();
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
|
|
550
|
+
/**********************************
|
|
551
|
+
* LifeCycle
|
|
552
|
+
***********************************/
|
|
553
|
+
|
|
554
|
+
async connectedCallback() {
|
|
555
|
+
if (super.connectedCallback) {
|
|
556
|
+
await super.connectedCallback();
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
async firstUpdated() {
|
|
561
|
+
if (super.firstUpdated) {
|
|
562
|
+
await super.firstUpdated();
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
async pageInitialized() {
|
|
567
|
+
if (super.pageInitialized) {
|
|
568
|
+
await super.pageInitialized();
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
async disconnectedCallback() {
|
|
573
|
+
if (super.disconnectedCallback) {
|
|
574
|
+
await super.disconnectedCallback();
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
}
|