@things-factory/meta-ui 5.0.14 → 5.0.15
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/assets/images/loading-page.png +0 -0
- package/client/actions/main.js +1 -1
- package/client/bootstrap.js +62 -12
- package/client/index.js +10 -17
- package/client/mixin/meta-base-mixin.js +1 -0
- package/client/mixin/meta-basic-form-mixin.js +4 -0
- package/client/mixin/meta-basic-grist-mixin.js +4 -0
- package/client/mixin/meta-button-mixin.js +1 -0
- package/client/mixin/meta-service-mixin.js +1 -0
- package/client/pages/loading-page.js +51 -0
- package/client/pages/menu/dynamic-menu-template.js +10 -64
- package/client/pages/menu/dynamic-menu.js +25 -387
- package/client/pages/meta-form-element.js +1 -0
- package/client/pages/meta-grist-element.js +1 -0
- package/client/pages/meta-grist-page.js +1 -0
- package/client/pages/terms/config-terminology.js +9 -360
- package/client/reducers/main.js +1 -17
- package/client/route.js +6 -22
- package/client/utils/meta-api.js +1 -0
- package/client/utils/meta-crypto.js +1 -0
- package/client/utils/meta-ui-util.js +213 -0
- package/client/utils/service-util.js +35 -0
- package/client/utils/terms-util.js +2 -177
- package/client/utils/ui-util.js +1 -0
- package/client/utils/value-util.js +1 -42
- package/dist-server/constants/error-code.js +1 -0
- package/dist-server/constants/error-code.js.map +1 -0
- package/dist-server/controllers/index.js.map +1 -1
- package/dist-server/errors/index.js +18 -0
- package/dist-server/errors/index.js.map +1 -0
- package/dist-server/errors/license-error.js +1 -0
- package/dist-server/errors/license-error.js.map +1 -0
- package/dist-server/index.js +17 -3
- package/dist-server/index.js.map +1 -1
- package/dist-server/middlewares/index.js +6 -1
- package/dist-server/middlewares/index.js.map +1 -1
- package/dist-server/migrations/index.js.map +1 -1
- package/dist-server/routes.js +1 -25
- package/dist-server/routes.js.map +1 -1
- package/dist-server/service/index.js +16 -0
- package/dist-server/service/index.js.map +1 -0
- package/dist-server/service/meta-secret/index.js +6 -0
- package/dist-server/service/meta-secret/index.js.map +1 -0
- package/dist-server/service/meta-secret/meta-resolver.js +1 -0
- package/dist-server/service/meta-secret/meta-resolver.js.map +1 -0
- package/package.json +9 -7
- package/translations/en.json +16 -6
- package/translations/ko.json +11 -0
- package/translations/ms.json +10 -0
- package/translations/zh.json +10 -0
- package/client/utils/meta-util.js +0 -773
- package/dist-server/tsconfig.tsbuildinfo +0 -1
- package/server/controllers/index.ts +0 -0
- package/server/index.ts +0 -4
- package/server/middlewares/index.ts +0 -3
- package/server/migrations/index.ts +0 -9
- package/server/routes.ts +0 -28
|
@@ -1,773 +0,0 @@
|
|
|
1
|
-
import gql from 'graphql-tag'
|
|
2
|
-
|
|
3
|
-
import { client } from '@operato/graphql'
|
|
4
|
-
import { openPopup } from '@operato/layout'
|
|
5
|
-
import { getCodeByName } from '@things-factory/code-base'
|
|
6
|
-
import { CustomAlert, store } from '@things-factory/shell'
|
|
7
|
-
import { gqlBuilder, isMobileDevice } from '@things-factory/utils'
|
|
8
|
-
|
|
9
|
-
import { TermsUtil } from './terms-util'
|
|
10
|
-
|
|
11
|
-
// 동적 라우팅 정보
|
|
12
|
-
let META_ROUTES = []
|
|
13
|
-
// 동적 메뉴 정보
|
|
14
|
-
let META_MENUS = []
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* @license
|
|
18
|
-
* Copyright © HatioLab Inc. All rights reserved.
|
|
19
|
-
* @author Shortstop <shortstop@hatiolab.com>
|
|
20
|
-
* @description 메타 UI에서 필요한 유틸리티 함수 정의
|
|
21
|
-
*/
|
|
22
|
-
export class MetaUtil {
|
|
23
|
-
/**
|
|
24
|
-
* @description 현재 디바이스가 모바일 장비인지 체크
|
|
25
|
-
**************************************
|
|
26
|
-
* @returns {Boolean} 모바일 장비 여부
|
|
27
|
-
*/
|
|
28
|
-
static isMobileDevice() {
|
|
29
|
-
return isMobileDevice()
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* @description 현재 로케일 정보 리턴
|
|
34
|
-
**************************************
|
|
35
|
-
* @returns {String} 현재 브라우저의 로케일 정보
|
|
36
|
-
*/
|
|
37
|
-
static currentLocale() {
|
|
38
|
-
// TODO 수정 필요 ....
|
|
39
|
-
let localeCookie = document.cookie
|
|
40
|
-
localeCookie = localeCookie.replace('i18next=', '')
|
|
41
|
-
return localeCookie
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* @description 현재 액티브 된 화면의 라우팅 정보
|
|
46
|
-
**************************************
|
|
47
|
-
* @returns {String} 현재 액티브 된 화면의 라우팅 정보
|
|
48
|
-
*/
|
|
49
|
-
static currentRouting() {
|
|
50
|
-
return store.getState().route.page
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* @description 공통 코드 리턴
|
|
55
|
-
**************************************
|
|
56
|
-
* @param {String} codeName 공통 코드 명
|
|
57
|
-
* @returns {Array} 코드 리스트
|
|
58
|
-
*/
|
|
59
|
-
static async codeItems(codeName) {
|
|
60
|
-
return await getCodeByName(codeName)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* @description selector를 위한 공통 코드 조회
|
|
65
|
-
**************************************
|
|
66
|
-
* @param {String} codeName 공통 코드 명
|
|
67
|
-
* @returns {Array} 코드 리스트
|
|
68
|
-
*/
|
|
69
|
-
static async getCodeSelectorData(codeName) {
|
|
70
|
-
let codeItems = await MetaUtil.codeItems(codeName)
|
|
71
|
-
let codeSelectors = codeItems.map(c => {
|
|
72
|
-
return {
|
|
73
|
-
value: c.name,
|
|
74
|
-
display: c.description
|
|
75
|
-
}
|
|
76
|
-
})
|
|
77
|
-
codeSelectors.unshift({ value: '', display: '' })
|
|
78
|
-
return codeSelectors
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* @description 오픈하고자 하는 엘리먼트를 받아 팝업 오픈
|
|
83
|
-
*************************************************
|
|
84
|
-
* @param {String} popupTitle 팝업 타이틀
|
|
85
|
-
* @param {String} popupSize 'large', 'medium', 'small'
|
|
86
|
-
* @param {String} element 팝업에 표시할 엘리먼트
|
|
87
|
-
* @param {Boolean} backdrop 백드롭 여부
|
|
88
|
-
*/
|
|
89
|
-
static openPopupByElement(popupTitle, popupSize, element, backdrop) {
|
|
90
|
-
openPopup(element, {
|
|
91
|
-
backdrop: true,
|
|
92
|
-
size: popupSize,
|
|
93
|
-
title: popupTitle,
|
|
94
|
-
backdrop: backdrop
|
|
95
|
-
})
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* @description tagname, routing으로 커스텀 엘리먼트 생성
|
|
100
|
-
****************************************************
|
|
101
|
-
* @param {String} tagname 팝업에 포함할 태그 명
|
|
102
|
-
* @param {String} routing 라우팅
|
|
103
|
-
* @returns {Object} 커스텀 엘리먼트
|
|
104
|
-
*/
|
|
105
|
-
static createCustomElement(tagname, routing) {
|
|
106
|
-
var template = document.createElement('template')
|
|
107
|
-
template.innerHTML = `<${tagname} route_name='${routing}'></${tagname}>`
|
|
108
|
-
var elements = template.content.childNodes
|
|
109
|
-
var element = elements[0]
|
|
110
|
-
template.content.removeChild(element)
|
|
111
|
-
return element
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* @description store의 정보 추출
|
|
116
|
-
****************************************************
|
|
117
|
-
* @param {String} accessor1 스토어 액세서 1, 빈 값 가능
|
|
118
|
-
* @param {String} accessor2 스토어 액세서 2, 빈 값 가능
|
|
119
|
-
* @param {String} accessor3 스토어 액세서 3, 빈 값 가능
|
|
120
|
-
* @returns {Object} store 정보
|
|
121
|
-
*/
|
|
122
|
-
static getStore(accessor1, accessor2, accessor3) {
|
|
123
|
-
let store = store.getState()
|
|
124
|
-
|
|
125
|
-
if (accessor1 && accessor2 && accessor3) {
|
|
126
|
-
return store[accessor1][accessor2][accessor3]
|
|
127
|
-
} else if (accessor1 && accessor2) {
|
|
128
|
-
return store[accessor1][accessor2]
|
|
129
|
-
} else if (accessor1) {
|
|
130
|
-
return store[accessor1]
|
|
131
|
-
} else {
|
|
132
|
-
return store
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* @description 커스텀 이벤트 전파
|
|
138
|
-
*************************************
|
|
139
|
-
* @param {String} eventName 이벤트 이름
|
|
140
|
-
* @param {Object} eventDetail 이벤트 상세 정보
|
|
141
|
-
*/
|
|
142
|
-
static fireCustomEvent(eventName, eventDetail) {
|
|
143
|
-
document.dispatchEvent(
|
|
144
|
-
new CustomEvent(eventName, {
|
|
145
|
-
detail: eventDetail
|
|
146
|
-
})
|
|
147
|
-
)
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* @description 토스트 메시지 표시
|
|
152
|
-
*************************************
|
|
153
|
-
* @param {String} type 토스트 타입
|
|
154
|
-
* @param {String} message 메시지
|
|
155
|
-
*/
|
|
156
|
-
static showToast(type, message) {
|
|
157
|
-
document.dispatchEvent(
|
|
158
|
-
new CustomEvent('notify', {
|
|
159
|
-
detail: { type, message }
|
|
160
|
-
})
|
|
161
|
-
)
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* @description Alert 메시지 창 표시
|
|
166
|
-
*************************************
|
|
167
|
-
* @param {String} titleCode Alert 제목 표시를 위한 용어 이름, 예) title.confirm
|
|
168
|
-
* @param {String} textCode Alert 텍스트 표시를 위한 용어 이름 예) text.are_you_sure
|
|
169
|
-
* @param {String} type Alert 창 유형 - info, error, warning ...
|
|
170
|
-
* @param {String} confirmButtonCode 확인 버튼 표시를 위한 용어 이름 예) confirm
|
|
171
|
-
* @param {String} cancelButtonCode 취소 버튼 표시를 위한 용어 이름 예) cancel
|
|
172
|
-
* @returns {Object}
|
|
173
|
-
*/
|
|
174
|
-
static async showAlertPopup(titleCode, textCode, type, confirmButtonCode, cancelButtonCode) {
|
|
175
|
-
let alert = { title: TermsUtil.t(titleCode), text: TermsUtil.t(textCode) }
|
|
176
|
-
|
|
177
|
-
if (type) {
|
|
178
|
-
alert['type'] = type
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
if (confirmButtonCode) {
|
|
182
|
-
alert['confirmButton'] = TermsUtil.tButton(confirmButtonCode)
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
if (cancelButtonCode) {
|
|
186
|
-
alert['cancelButton'] = TermsUtil.tButton(cancelButtonCode)
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
return await CustomAlert(alert)
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* @description 메뉴 틀에 맞게 재 배치
|
|
194
|
-
**************************************
|
|
195
|
-
* @param {Array} menuData 메뉴 정보에서 조회한 메뉴 리스트
|
|
196
|
-
* @returns {Array} 메뉴 바 틀에 맞게 재 배치된 메뉴 & 라우팅 정보
|
|
197
|
-
*/
|
|
198
|
-
static arrangeMenuRoutes(menuData) {
|
|
199
|
-
// 1. routes
|
|
200
|
-
let routes = []
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* 메뉴 데이터 예)
|
|
204
|
-
* name : 메뉴 명 (DynamicMenu)
|
|
205
|
-
* category : 태그 명 (dynamic-menu)
|
|
206
|
-
* routing : 라우팅 (dynamic_menu)
|
|
207
|
-
* detailFormId : 페이지 위치 (./pages/menu/dynamic-menu)
|
|
208
|
-
*/
|
|
209
|
-
// 2. 서버에서 조회한 메뉴 정보 중에 메인 메뉴를 추출
|
|
210
|
-
let mainMenus = menuData
|
|
211
|
-
.map(item => {
|
|
212
|
-
if (item.menuType == 'GROUP' || item.menuType == 'MENU') {
|
|
213
|
-
let title = TermsUtil.tMenu(item.name)
|
|
214
|
-
let mainMenu = { id: item.id, parent: true, name: title, icon: item.iconPath }
|
|
215
|
-
|
|
216
|
-
if (item.menuType == 'GROUP') {
|
|
217
|
-
mainMenu['type'] = 'group'
|
|
218
|
-
} else {
|
|
219
|
-
mainMenu['menus'] = []
|
|
220
|
-
}
|
|
221
|
-
return mainMenu
|
|
222
|
-
} else {
|
|
223
|
-
return { id: '0' }
|
|
224
|
-
}
|
|
225
|
-
})
|
|
226
|
-
.filter(i => i.id != '0')
|
|
227
|
-
|
|
228
|
-
// 3. 메인 메뉴 하위에 서브 메뉴를 추가
|
|
229
|
-
menuData.forEach(item => {
|
|
230
|
-
if (item.menuType == 'SCREEN') {
|
|
231
|
-
let parentMenu = mainMenus.find(main => main.id == item.parent.id)
|
|
232
|
-
if (parentMenu) {
|
|
233
|
-
let title = TermsUtil.tMenu(item.name)
|
|
234
|
-
let tagName = item.category
|
|
235
|
-
|
|
236
|
-
// 좌측 메뉴에 표시되도록 메뉴 트리 구성
|
|
237
|
-
parentMenu.menus.push({
|
|
238
|
-
id: item.id,
|
|
239
|
-
name: title,
|
|
240
|
-
path: item.routing,
|
|
241
|
-
icon: item.iconPath
|
|
242
|
-
})
|
|
243
|
-
|
|
244
|
-
// 애플리케이션 모듈인 경우에만 라우팅 정보에 추가하고 다른 모듈의 화면이라면 라우팅 정보에서 제외
|
|
245
|
-
let template = item.detailFormId
|
|
246
|
-
routes.push({
|
|
247
|
-
id: item.id,
|
|
248
|
-
parent: false,
|
|
249
|
-
parent_id: parentMenu.id,
|
|
250
|
-
title: title,
|
|
251
|
-
tagname: tagName,
|
|
252
|
-
page: item.routing,
|
|
253
|
-
template: item.detailFormId,
|
|
254
|
-
routing_type: item.routingType
|
|
255
|
-
})
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
})
|
|
259
|
-
|
|
260
|
-
// 4. 변수 설정
|
|
261
|
-
META_ROUTES = Object.assign([], routes)
|
|
262
|
-
META_MENUS = Object.assign([], mainMenus)
|
|
263
|
-
|
|
264
|
-
// 5. 메뉴 데이터 리턴
|
|
265
|
-
return { menus: mainMenus, routes: routes }
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
/**
|
|
269
|
-
* @description 현재 사용자의 권한에 맞는 메뉴 정보 요청
|
|
270
|
-
**************************************
|
|
271
|
-
* @returns {Array} 메뉴 바에 표시될 메뉴 리스트
|
|
272
|
-
*/
|
|
273
|
-
static async myDynamicMenus() {
|
|
274
|
-
if (META_ROUTES.length == 0) {
|
|
275
|
-
let menuItems = await MetaUtil.searchMyDynamicMenus()
|
|
276
|
-
return menuItems != null ? MetaUtil.arrangeMenuRoutes(menuItems) : null
|
|
277
|
-
} else {
|
|
278
|
-
return { menus: META_MENUS, routes: META_ROUTES }
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
/**
|
|
283
|
-
* @description 현재 사용자의 권한에 맞는 메뉴 정보 요청
|
|
284
|
-
**************************************
|
|
285
|
-
* @returns {Array} 메뉴 바에 표시될 메뉴 리스트
|
|
286
|
-
*/
|
|
287
|
-
static async searchMyDynamicMenus() {
|
|
288
|
-
let filters = [
|
|
289
|
-
{
|
|
290
|
-
name: 'hiddenFlag',
|
|
291
|
-
operator: 'noteq',
|
|
292
|
-
value: true
|
|
293
|
-
},
|
|
294
|
-
{
|
|
295
|
-
name: 'menuType',
|
|
296
|
-
operator: 'in',
|
|
297
|
-
value: ['MENU', 'GROUP', 'SCREEN']
|
|
298
|
-
}
|
|
299
|
-
]
|
|
300
|
-
let sortings = [{ name: 'menuType' }, { name: 'rank' }]
|
|
301
|
-
let selectFields = `
|
|
302
|
-
id
|
|
303
|
-
parent {
|
|
304
|
-
id
|
|
305
|
-
name
|
|
306
|
-
}
|
|
307
|
-
name
|
|
308
|
-
description
|
|
309
|
-
menuType
|
|
310
|
-
category
|
|
311
|
-
routingType
|
|
312
|
-
routing
|
|
313
|
-
detailFormId
|
|
314
|
-
iconPath
|
|
315
|
-
`
|
|
316
|
-
let data = await MetaUtil.searchByPagination('menus', filters, sortings, 0, 0, selectFields)
|
|
317
|
-
return data.records
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
/**
|
|
321
|
-
* @description 메뉴 ID 정보로 메뉴 메타 정보 조회
|
|
322
|
-
**********************************************
|
|
323
|
-
* @param {String} menuId
|
|
324
|
-
* @returns {Object} 메뉴 메타 정보
|
|
325
|
-
*/
|
|
326
|
-
static async findMenuMeta(menuId) {
|
|
327
|
-
let menu = await MetaUtil.findOne('menu', menuId, 'template')
|
|
328
|
-
if (!menu) {
|
|
329
|
-
throw new Error(TermsUtil.tText('menu_not_found'))
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
if (!menu.template) {
|
|
333
|
-
throw new Error(TermsUtil.tText('menu_template_not_found'))
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
return JSON.parse(menu.template)
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
/**
|
|
340
|
-
* @description 메뉴 라우팅 정보로 메뉴 메타 정보 조회
|
|
341
|
-
**********************************************
|
|
342
|
-
* @param {String} menuRouting
|
|
343
|
-
* @returns {Object} 메뉴 메타 정보
|
|
344
|
-
*/
|
|
345
|
-
static async findMenuMetaByRouting(menuRouting) {
|
|
346
|
-
let filters = [{ name: 'routing', operator: 'eq', value: menuRouting }]
|
|
347
|
-
let selectFields = 'template'
|
|
348
|
-
let data = await MetaUtil.searchByPagination('menus', filters, null, 0, 0, selectFields)
|
|
349
|
-
|
|
350
|
-
if (!data && data.length == 0) {
|
|
351
|
-
throw new Error(TermsUtil.tText('menu_not_found'))
|
|
352
|
-
} else {
|
|
353
|
-
let menu = data.records[0]
|
|
354
|
-
if (!menu.template) {
|
|
355
|
-
throw new Error(TermsUtil.tText('menu_template_not_found'))
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
return JSON.parse(menu.template)
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
/**
|
|
363
|
-
* 최종 애플리케이션 모듈 정보 리턴
|
|
364
|
-
* @returns
|
|
365
|
-
*/
|
|
366
|
-
static getApplicationModuleInfo() {
|
|
367
|
-
let modules = store.getState().app.modules
|
|
368
|
-
return modules[modules.length - 1]
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
/**
|
|
372
|
-
* @description 응답이 처리된 후 Graphql Error 메시지 표시
|
|
373
|
-
*************************************************
|
|
374
|
-
* @param {Object} response 응답
|
|
375
|
-
*/
|
|
376
|
-
static async showGraphqlErrorResponse(response) {
|
|
377
|
-
if (response.errors && response.errors.length > 0) {
|
|
378
|
-
let error = response.errors[0]
|
|
379
|
-
let errContent = error.message
|
|
380
|
-
let errTitle = error.message
|
|
381
|
-
|
|
382
|
-
if (error.extensions) {
|
|
383
|
-
let errExt = error.extensions
|
|
384
|
-
errTitle = errExt.code
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
await MetaUtil.showAlertPopup(errTitle, errContent, 'error', 'confirm')
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
/**
|
|
392
|
-
* @description Graphql 실행 시 Exception 표시
|
|
393
|
-
*************************************************
|
|
394
|
-
* @param {Object} exception 에러
|
|
395
|
-
*/
|
|
396
|
-
static async showGraphqlException(exception) {
|
|
397
|
-
if (exception) {
|
|
398
|
-
if (exception.networkError && exception.networkError.result) {
|
|
399
|
-
await MetaUtil.showGraphqlErrorResponse(exception.networkError.result)
|
|
400
|
-
} else {
|
|
401
|
-
await MetaUtil.showAlertPopup('Graphql Error', exception.message, 'error', 'confirm')
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
/**
|
|
407
|
-
* @description 데이터 리스트 페이지네이션 조회
|
|
408
|
-
******************************************
|
|
409
|
-
* @param {String} queryFunc 쿼리 함수
|
|
410
|
-
* @param {Array} filters 조회 조건
|
|
411
|
-
* @param {Array} sortings 소팅 조건
|
|
412
|
-
* @param {Number} page 현재 페이지
|
|
413
|
-
* @param {Number} limit 페이지 당 표시할 레코드 건수
|
|
414
|
-
* @param {String} selectFields 조회할 필드 리스트
|
|
415
|
-
* @returns {Array} 조회 결과 { records : [{,...}], total : 100 }
|
|
416
|
-
*/
|
|
417
|
-
static async searchByPagination(queryFunc, filters, sortings, page, limit, selectFields) {
|
|
418
|
-
try {
|
|
419
|
-
const response = await client.query({
|
|
420
|
-
query: gql`
|
|
421
|
-
query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
|
|
422
|
-
${queryFunc}(filters: $filters, pagination: $pagination, sortings: $sortings) {
|
|
423
|
-
items {
|
|
424
|
-
${selectFields}
|
|
425
|
-
}
|
|
426
|
-
total
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
`,
|
|
430
|
-
variables: { filters, sortings, pagination: { page, limit } }
|
|
431
|
-
})
|
|
432
|
-
|
|
433
|
-
if (!response.errors) {
|
|
434
|
-
return {
|
|
435
|
-
records: response.data[queryFunc].items,
|
|
436
|
-
total: response.data[queryFunc].total
|
|
437
|
-
}
|
|
438
|
-
} else {
|
|
439
|
-
MetaUtil.showGraphqlError(response)
|
|
440
|
-
}
|
|
441
|
-
} catch (e) {
|
|
442
|
-
MetaUtil.showGraphqlException(e)
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
return null
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
/**
|
|
449
|
-
* @description 레코드의 id를 이용해 데이터 조회
|
|
450
|
-
*********************************************
|
|
451
|
-
* @param {String} queryFunc 조회할 query 함수명
|
|
452
|
-
* @param {String} id 레코드 ID
|
|
453
|
-
* @param {String} selectFields 조회할 필드 리스트
|
|
454
|
-
* @return {Object} 조회한 레코드
|
|
455
|
-
*/
|
|
456
|
-
static async findOne(queryFunc, id, selectFields) {
|
|
457
|
-
try {
|
|
458
|
-
let response = await client.query({
|
|
459
|
-
query: gql`
|
|
460
|
-
query ($id: String!) {
|
|
461
|
-
${queryFunc}(id: $id) {
|
|
462
|
-
${selectFields}
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
`,
|
|
466
|
-
variables: { id: id }
|
|
467
|
-
})
|
|
468
|
-
|
|
469
|
-
if (!response.errors) {
|
|
470
|
-
return response.data[queryFunc] || {}
|
|
471
|
-
} else {
|
|
472
|
-
MetaUtil.showGraphqlError(response)
|
|
473
|
-
}
|
|
474
|
-
} catch (e) {
|
|
475
|
-
MetaUtil.showGraphqlException(e)
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
return null
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
/**
|
|
482
|
-
* @description 그리스트의 선택된 레코드 삭제 처리
|
|
483
|
-
**************************************
|
|
484
|
-
* @param {Object} grist 그리스트
|
|
485
|
-
* @param {Object} mutationFunc 삭제 처리할 함수
|
|
486
|
-
* @returns
|
|
487
|
-
*/
|
|
488
|
-
static async deleteListByGristSelected(grist, mutationFunc) {
|
|
489
|
-
const ids = grist.selected.map(record => record.id)
|
|
490
|
-
|
|
491
|
-
if (ids && ids.length > 0) {
|
|
492
|
-
const anwer = await MetaUtil.showAlertPopup('button.delete', 'text.are_you_sure', 'question', 'delete', 'cancel')
|
|
493
|
-
if (anwer.value) {
|
|
494
|
-
let result = await MetaUtil.deleteListByIds(ids, mutationFunc)
|
|
495
|
-
if (result) {
|
|
496
|
-
grist.fetch()
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
} else {
|
|
500
|
-
await MetaUtil.showAlertPopup('text.nothing_selected', 'text.there_is_nothing_to_delete', 'info', 'confirm')
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
/**
|
|
505
|
-
* @description ID 배열로 레코드 삭제 처리
|
|
506
|
-
**************************************
|
|
507
|
-
* @param {Object} grist 그리스트
|
|
508
|
-
* @param {Object} mutationFunc 삭제 처리할 함수
|
|
509
|
-
* @returns
|
|
510
|
-
*/
|
|
511
|
-
static async deleteListByIds(ids, mutationFunc) {
|
|
512
|
-
try {
|
|
513
|
-
const response = await client.query({
|
|
514
|
-
query: gql`
|
|
515
|
-
mutation {
|
|
516
|
-
${mutationFunc}(${gqlBuilder.buildArgs({ ids })})
|
|
517
|
-
}
|
|
518
|
-
`
|
|
519
|
-
})
|
|
520
|
-
|
|
521
|
-
if (!response.errors) {
|
|
522
|
-
MetaUtil.showToast('info', TermsUtil.tText('Success to Delete'))
|
|
523
|
-
return true
|
|
524
|
-
} else {
|
|
525
|
-
MetaUtil.showGraphqlError(response)
|
|
526
|
-
}
|
|
527
|
-
} catch (e) {
|
|
528
|
-
MetaUtil.showGraphqlException(e)
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
return false
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
/**
|
|
535
|
-
* @description 그리스트에서 변경, 추가된 여러 데이터를 한 꺼번에 업데이트
|
|
536
|
-
***************************************************
|
|
537
|
-
* @param {Object} grist 그리스트
|
|
538
|
-
* @param {String} mutationFunc updateMultiple을 위한 서버 측 mutation 함수 명
|
|
539
|
-
* @returns 업데이트 성공 여부
|
|
540
|
-
*/
|
|
541
|
-
static async updateMultipleData(grist, mutationFunc) {
|
|
542
|
-
let cudRecords = grist.dirtyRecords
|
|
543
|
-
|
|
544
|
-
if (!cudRecords || cudRecords.length == 0) {
|
|
545
|
-
MetaUtil.showAlertPopup('text.nothing_selected', 'text.there_is_nothing_to_delete', 'info', 'confirm')
|
|
546
|
-
} else {
|
|
547
|
-
let patches = MetaUtil.patchForUpdateMultiple(cudRecords)
|
|
548
|
-
let result = await MetaUtil.updateMultiple(mutationFunc, patches)
|
|
549
|
-
if (result) {
|
|
550
|
-
grist.fetch()
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
/**
|
|
556
|
-
* @description 변경, 추가된 여러 데이터를 한 꺼번에 업데이트
|
|
557
|
-
***************************************************
|
|
558
|
-
* @param {String} mutationFunc updateMultiple을 위한 서버 측 mutation 함수 명
|
|
559
|
-
* @param {Array} patches 변경, 추가된 여러 데이터
|
|
560
|
-
* @returns 업데이트 성공 여부
|
|
561
|
-
*/
|
|
562
|
-
static async updateMultiple(mutationFunc, patches) {
|
|
563
|
-
try {
|
|
564
|
-
const response = await client.query({
|
|
565
|
-
query: gql`
|
|
566
|
-
mutation {
|
|
567
|
-
${mutationFunc}(${gqlBuilder.buildArgs({
|
|
568
|
-
patches
|
|
569
|
-
})}) {
|
|
570
|
-
id
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
`,
|
|
574
|
-
context: {
|
|
575
|
-
hasUpload: true
|
|
576
|
-
}
|
|
577
|
-
})
|
|
578
|
-
|
|
579
|
-
if (!response.errors) {
|
|
580
|
-
MetaUtil.showToast('info', TermsUtil.tText('Success to Save'))
|
|
581
|
-
return true
|
|
582
|
-
} else {
|
|
583
|
-
MetaUtil.showGraphqlError(response)
|
|
584
|
-
}
|
|
585
|
-
} catch (e) {
|
|
586
|
-
MetaUtil.showGraphqlException(e)
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
return false
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
/**
|
|
593
|
-
* @description 그리스트에서 변경, 추가된 내용 추출
|
|
594
|
-
********************************************
|
|
595
|
-
* @param {Array} cudRecords
|
|
596
|
-
* @returns 그리스트에서 변경, 추가된 데이터 리스트
|
|
597
|
-
*/
|
|
598
|
-
static patchForUpdateMultiple(cudRecords) {
|
|
599
|
-
return cudRecords.map(record => {
|
|
600
|
-
let patchField = record.id ? { id: record.id } : {}
|
|
601
|
-
const dirtyFields = record.__dirtyfields__
|
|
602
|
-
|
|
603
|
-
for (let key in dirtyFields) {
|
|
604
|
-
patchField[key] = dirtyFields[key].after
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
patchField.cuFlag = record.__dirty__
|
|
608
|
-
return patchField
|
|
609
|
-
})
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
/**
|
|
613
|
-
* @description 페이지네이션 기본 페이지 수 [20, 30, 50, 100]
|
|
614
|
-
********************************************
|
|
615
|
-
* @returns {Object} 페이지네이션 기본 페이지 수
|
|
616
|
-
*/
|
|
617
|
-
static getGristPaginationDefaultConfig() {
|
|
618
|
-
return { pages: [20, 30, 50, 100] }
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
/**
|
|
622
|
-
* @description 페이지네이션 페이지 수 [50, 100, 500, 1000]
|
|
623
|
-
********************************************
|
|
624
|
-
* @returns {Object} 페이지네이션 기본 페이지 수
|
|
625
|
-
*/
|
|
626
|
-
static getGristPagination50Config() {
|
|
627
|
-
return { pages: [50, 100, 500, 1000] }
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
/**
|
|
631
|
-
* @description 페이지네이션 페이지 수 [100, 500, 1000, 50000]
|
|
632
|
-
********************************************
|
|
633
|
-
* @returns {Object} 페이지네이션 기본 페이지 수
|
|
634
|
-
*/
|
|
635
|
-
static getGristPagination100Config() {
|
|
636
|
-
return { pages: [100, 500, 1000, 50000] }
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
/**
|
|
640
|
-
* @description 페이지네이션 페이지 수 [1000, 5000, 10000, 100000]
|
|
641
|
-
********************************************
|
|
642
|
-
* @returns {Object} 페이지네이션 기본 페이지 수
|
|
643
|
-
*/
|
|
644
|
-
static getGristPaginationMaxConfig() {
|
|
645
|
-
return { pages: [1000, 5000, 10000, 100000] }
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
/**
|
|
649
|
-
* @description 그리스트 기본 gutter 설정 리턴
|
|
650
|
-
********************************************
|
|
651
|
-
* @returns {Object} 그리스트 기본 gutter 설정
|
|
652
|
-
*/
|
|
653
|
-
static getGristGuttersDefaultConfig(multiple) {
|
|
654
|
-
return [
|
|
655
|
-
{ type: 'gutter', gutterName: 'dirty' },
|
|
656
|
-
{ type: 'gutter', gutterName: 'sequence' },
|
|
657
|
-
{ type: 'gutter', gutterName: 'row-selector', multiple: multiple }
|
|
658
|
-
]
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
/**
|
|
662
|
-
* @description 그리스트 선택 모드 설정
|
|
663
|
-
****************************************
|
|
664
|
-
* @returns {Object} 그리스트 선택 모드 설정
|
|
665
|
-
*/
|
|
666
|
-
static getGristSelectableConfig(multiple) {
|
|
667
|
-
return { selectable: { multiple: multiple } }
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
/**
|
|
671
|
-
* @description 그리스트 기본 컬럼 설정
|
|
672
|
-
***********************************
|
|
673
|
-
* @param {String} type
|
|
674
|
-
* @param {String} name
|
|
675
|
-
* @param {String} align
|
|
676
|
-
* @param {Boolean} editable
|
|
677
|
-
* @param {Boolean} sortable
|
|
678
|
-
* @param {Number} width
|
|
679
|
-
* @returns {Object} 그리스트 기본 컬럼 설정
|
|
680
|
-
*/
|
|
681
|
-
static getGristColumnConfig(type, name, align, editable, sortable, width) {
|
|
682
|
-
return {
|
|
683
|
-
type: type,
|
|
684
|
-
name: name,
|
|
685
|
-
header: TermsUtil.tLabel(name),
|
|
686
|
-
record: {
|
|
687
|
-
align: align,
|
|
688
|
-
editable: editable
|
|
689
|
-
},
|
|
690
|
-
sortable: sortable,
|
|
691
|
-
width: width
|
|
692
|
-
}
|
|
693
|
-
}
|
|
694
|
-
|
|
695
|
-
/**
|
|
696
|
-
* @description 그리스트 컬럼 설정
|
|
697
|
-
***********************************
|
|
698
|
-
* @param {String} type
|
|
699
|
-
* @param {String} name
|
|
700
|
-
* @param {String} displayName
|
|
701
|
-
* @param {String} align
|
|
702
|
-
* @param {Boolean} editable
|
|
703
|
-
* @param {Boolean} sortable
|
|
704
|
-
* @param {Number} width
|
|
705
|
-
* @returns {Object} 그리스트 기본 컬럼 설정
|
|
706
|
-
*/
|
|
707
|
-
static getGristColumnConfig2(type, name, displayName, align, editable, sortable, width) {
|
|
708
|
-
return {
|
|
709
|
-
type: type,
|
|
710
|
-
name: name,
|
|
711
|
-
header: TermsUtil.tLabel(displayName),
|
|
712
|
-
record: {
|
|
713
|
-
align: align,
|
|
714
|
-
editable: editable
|
|
715
|
-
},
|
|
716
|
-
sortable: sortable,
|
|
717
|
-
width: width
|
|
718
|
-
}
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
/**
|
|
722
|
-
* @description 그리스트 Selector 컬럼 설정
|
|
723
|
-
***********************************
|
|
724
|
-
* @param {String} name
|
|
725
|
-
* @param {String} displayName
|
|
726
|
-
* @param {String} align
|
|
727
|
-
* @param {Boolean} sortable
|
|
728
|
-
* @param {Number} width
|
|
729
|
-
* @param {Boolean} mandatory
|
|
730
|
-
* @param {Array} optionValues
|
|
731
|
-
* @returns {Object} 그리스트 기본 컬럼 설정
|
|
732
|
-
*/
|
|
733
|
-
static getGristSelectorColumnConfig(name, displayName, align, sortable, width, mandatory, optionValues) {
|
|
734
|
-
return {
|
|
735
|
-
type: 'select',
|
|
736
|
-
name: name,
|
|
737
|
-
header: TermsUtil.tLabel(displayName),
|
|
738
|
-
record: {
|
|
739
|
-
align: align,
|
|
740
|
-
editable: true,
|
|
741
|
-
mandatory: mandatory,
|
|
742
|
-
options: optionValues
|
|
743
|
-
},
|
|
744
|
-
sortable: sortable,
|
|
745
|
-
width: width
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
/**
|
|
750
|
-
* @description 그리스트 검색 필드 설정
|
|
751
|
-
************************************
|
|
752
|
-
* @param {String} name
|
|
753
|
-
* @param {String} type
|
|
754
|
-
* @param {String} label
|
|
755
|
-
* @param {String} operator
|
|
756
|
-
* @param {Array} optionValues
|
|
757
|
-
* @returns {Object} 그리스트 검색 필드 설정
|
|
758
|
-
*/
|
|
759
|
-
static getGristSearchColumnConfig(name, type, label, operator, optionValues) {
|
|
760
|
-
let column = {
|
|
761
|
-
name: name,
|
|
762
|
-
type: type,
|
|
763
|
-
label: TermsUtil.tLabel(label),
|
|
764
|
-
operator: operator
|
|
765
|
-
}
|
|
766
|
-
|
|
767
|
-
if (optionValues) {
|
|
768
|
-
column.options = optionValues
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
return column
|
|
772
|
-
}
|
|
773
|
-
}
|