@things-factory/operato-tools 7.0.0-y.0 → 7.0.1-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/client/index.js +0 -1
  2. package/client/pages/generator/button-config-tab-mixin.js +336 -2
  3. package/client/pages/generator/column-config-tab-mixin.js +647 -2
  4. package/client/pages/generator/etc-config-tab-mixin.js +116 -2
  5. package/client/pages/generator/form-config-tab-mixin.js +164 -2
  6. package/client/pages/generator/graphql-config-tab-mixin.js +281 -15
  7. package/client/pages/generator/grid-config-tab-mixin.js +190 -28
  8. package/client/pages/generator/grid-emphasized-config-tab-mixin.js +295 -6
  9. package/client/pages/generator/menu-config-tab-mixin.js +94 -8
  10. package/client/pages/generator/meta-generator-page.js +512 -12
  11. package/client/pages/generator/search-config-tab-mixin.js +188 -2
  12. package/client/pages/generator/tab-config-tab-mixin.js +226 -2
  13. package/client/pages/main.js +30 -7
  14. package/client/route.js +5 -10
  15. package/config/config.development.js +1 -1
  16. package/config/config.production.js +1 -0
  17. package/{server/errors → dist-server}/index.js +1 -1
  18. package/dist-server/index.js.map +1 -0
  19. package/{server → dist-server}/service/index.js +0 -2
  20. package/dist-server/service/index.js.map +1 -0
  21. package/dist-server/service/tool-entity/create-menu.js +321 -0
  22. package/dist-server/service/tool-entity/create-menu.js.map +1 -0
  23. package/dist-server/service/tool-entity/create-service.js +1053 -0
  24. package/dist-server/service/tool-entity/create-service.js.map +1 -0
  25. package/dist-server/service/tool-entity/index.js.map +1 -0
  26. package/dist-server/tsconfig.tsbuildinfo +1 -0
  27. package/package.json +21 -14
  28. package/server/index.ts +1 -0
  29. package/server/service/index.ts +15 -0
  30. package/server/service/tool-entity/create-menu.ts +338 -0
  31. package/server/service/tool-entity/create-service.ts +1128 -0
  32. package/server/service/tool-entity/index.ts +4 -0
  33. package/server/tsconfig.json +9 -0
  34. package/things-factory.config.js +1 -3
  35. package/tsconfig.json +9 -0
  36. package/views/auth-page.html +1 -7
  37. package/views/public/home.html +1 -6
  38. package/client/actions/main.js +0 -1
  39. package/client/bootstrap.js +0 -8
  40. package/client/reducers/main.js +0 -1
  41. package/client/themes/grist-theme.css +0 -200
  42. package/client/themes/layout-theme.css +0 -92
  43. package/client/themes/report-theme.css +0 -47
  44. package/schema.graphql +0 -3646
  45. package/server/constants/error-code.js +0 -1
  46. package/server/controllers/index.js +0 -1
  47. package/server/errors/license-error.js +0 -1
  48. package/server/index.js +0 -8
  49. package/server/middlewares/index.js +0 -19
  50. package/server/migrations/index.js +0 -12
  51. package/server/routes.js +0 -1
  52. package/server/service/boxtype/boxtype-mutation.js +0 -1
  53. package/server/service/boxtype/boxtype-query.js +0 -1
  54. package/server/service/boxtype/boxtype-type.js +0 -1
  55. package/server/service/boxtype/boxtype.js +0 -1
  56. package/server/service/boxtype/index.js +0 -9
  57. package/server/service/tool-entity/create-menu.js +0 -1
  58. package/server/service/tool-entity/create-service.js +0 -1
  59. package/server/service/tool-secret/index.js +0 -6
  60. package/server/service/tool-secret/tool-permission.js +0 -1
  61. package/server/service/tool-secret/tool-resolver.js +0 -1
  62. package/translations/ja.json +0 -85
  63. /package/{server → dist-server}/service/tool-entity/index.js +0 -0
@@ -1,30 +1,116 @@
1
- import{html}from"lit-element";import{TermsUtil}from"@things-factory/meta-ui/client/utils/terms-util";export const MenuConfigTabMixin=e=>class extends e{setMenuConfigTabValues(e){if(e){var{title:t="",name:l="",desc:i="",help:a=""}=e||{};this.viewMenuData={title:t,name:l,desc:i,help_doc:a},this.getElementById("title").value=t,this.getElementById("name").value=l,this.getElementById("desc").value=i,this.getElementById("help_doc").value=a}else this.setMenuConfigTabDefaultValue()}getMenuConfigTabValues(){let e={menu:{}},t=this.getElementValueById("title"),l=this.getElementValueById("name"),i=this.getElementValueById("desc"),a=this.getElementValueById("help_doc");return t&&(e.menu.title=t),l&&(e.menu.name=l),i&&(e.menu.desc=i),a&&(e.menu.help=a),e}setMenuConfigTabDefaultValue(){this.viewMenuData||(this.viewMenuData={title:"",name:"name",desc:"description",help_doc:""})}menuTitleChange(e){let t=this.getElementById("display");t&&(t.value=TermsUtil.tTitle(e.target.value))}renderMenuConfigTab(){return this.setMenuConfigTabDefaultValue(),html`
1
+ import { html } from 'lit-element'
2
+
3
+ import { TermsUtil } from '@things-factory/meta-ui/client/utils/terms-util'
4
+
5
+
6
+ export const MenuConfigTabMixin = (baseElement) => class extends baseElement {
7
+
8
+ setMenuConfigTabValues(data) {
9
+ if (data) {
10
+ var {
11
+ title = '',
12
+ name = '',
13
+ desc = '',
14
+ help = ''
15
+ } = data || {};
16
+
17
+ this.viewMenuData = {
18
+ title: title,
19
+ name: name,
20
+ desc: desc,
21
+ help_doc: help
22
+ };
23
+
24
+ this.getElementById('title').value = title;
25
+ this.getElementById('name').value = name;
26
+ this.getElementById('desc').value = desc;
27
+ this.getElementById('help_doc').value = help;
28
+
29
+ } else {
30
+ this.setMenuConfigTabDefaultValue();
31
+ }
32
+ }
33
+
34
+ getMenuConfigTabValues() {
35
+ let retObject = {
36
+ menu: {}
37
+ };
38
+
39
+ let title = this.getElementValueById('title');
40
+ let name = this.getElementValueById('name');
41
+ let desc = this.getElementValueById('desc');
42
+ let help_doc = this.getElementValueById('help_doc');
43
+
44
+ if (title) retObject.menu.title = title;
45
+ if (name) retObject.menu.name = name;
46
+ if (desc) retObject.menu.desc = desc;
47
+ if (help_doc) retObject.menu.help = help_doc;
48
+
49
+ return retObject;
50
+ }
51
+
52
+ /**
53
+ * 기본값 셋팅
54
+ */
55
+ setMenuConfigTabDefaultValue() {
56
+ if (!this.viewMenuData) {
57
+ this.viewMenuData = {
58
+ title: '',
59
+ name: 'name',
60
+ desc: 'description',
61
+ help_doc: ''
62
+ }
63
+ }
64
+ }
65
+
66
+ /**
67
+ * 메뉴 타이틀 변경 시 다국어 변환 결과 보기
68
+ * @param {Object} eventObj
69
+ */
70
+ menuTitleChange(eventObj) {
71
+ let transResult = this.getElementById('display');
72
+ if (transResult) {
73
+ transResult.value = TermsUtil.tTitle(eventObj.target.value);
74
+ }
75
+ }
76
+
77
+
78
+
79
+ // 화면
80
+ renderMenuConfigTab() {
81
+ this.setMenuConfigTabDefaultValue();
82
+
83
+ let renderHtml = html`
2
84
  <div field-2column>
3
85
  <div field>
4
- <label>${TermsUtil.tLabel("menu_title")}
5
- <input id="title" name="title" type="text" value=${this.viewMenuData.title} @change=${e=>this.menuTitleChange(e)}/>
86
+ <label>${TermsUtil.tLabel('menu_title')}
87
+ <input id="title" name="title" type="text" value=${this.viewMenuData.title} @change=${e =>
88
+ this.menuTitleChange(e)}/>
6
89
  </label>
7
90
  </div>
8
91
  <div field>
9
- <label>${TermsUtil.tLabel("display")}
92
+ <label>${TermsUtil.tLabel('display')}
10
93
  <input id="display" name="display" value=${TermsUtil.tTitle(this.viewMenuData.title)} type="text" readonly
11
94
  disabled />
12
95
  </label>
13
96
  </div>
14
97
  <div field>
15
- <label>${TermsUtil.tLabel("menu_name_field")}
98
+ <label>${TermsUtil.tLabel('menu_name_field')}
16
99
  <input id="name" name="name" type="text" value=${this.viewMenuData.name} />
17
100
  </label>
18
101
  </div>
19
102
  <div field>
20
- <label>${TermsUtil.tLabel("menu_desc_field")}
103
+ <label>${TermsUtil.tLabel('menu_desc_field')}
21
104
  <input id="desc" name="desc" type="text" value=${this.viewMenuData.desc} />
22
105
  </label>
23
106
  </div>
24
107
  <div field>
25
- <label>${TermsUtil.tLabel("help_doc")}
108
+ <label>${TermsUtil.tLabel('help_doc')}
26
109
  <input id="help_doc" name="help_doc" type="text" value=${this.viewMenuData.help_doc} />
27
110
  </label>
28
111
  </div>
29
112
  </div>
30
- `}};
113
+ `
114
+ return renderHtml;
115
+ }
116
+ }
@@ -1,4 +1,39 @@
1
- import{html,css}from"lit-element";import{merge}from"lodash";import gql from"graphql-tag";import{i18next,localize}from"@things-factory/i18n-base";import{PageView}from"@things-factory/shell";import{client}from"@operato/graphql";import{store}from"@operato/shell";import{CommonButtonStyles}from"@operato/styles";import{ButtonConfigTabMixin}from"./button-config-tab-mixin";import{MenuConfigTabMixin}from"./menu-config-tab-mixin";import{SearchConfigTabMixin}from"./search-config-tab-mixin";import{GridConfigTabMixin}from"./grid-config-tab-mixin";import{ColumnConfigTabMixin}from"./column-config-tab-mixin";import{GraphQlConfigTabMixin}from"./graphql-config-tab-mixin";import{FormConfigTabMixin}from"./form-config-tab-mixin";import{TabConfigTabMixin}from"./tab-config-tab-mixin";import{EtcConfigTabMixin}from"./etc-config-tab-mixin";import{GridEmphasizedConfigTabMixin}from"./grid-emphasized-config-tab-mixin";import{TermsUtil}from"@things-factory/meta-ui/client/utils/terms-util";import{MetaApi}from"@things-factory/meta-ui/client/utils/meta-api";import{MetaCrypto}from"@things-factory/meta-ui/client/utils/meta-crypto";class MetaGeneratorPage extends(MenuConfigTabMixin(GraphQlConfigTabMixin(GridConfigTabMixin(ColumnConfigTabMixin(ButtonConfigTabMixin(SearchConfigTabMixin(FormConfigTabMixin(TabConfigTabMixin(EtcConfigTabMixin(GridEmphasizedConfigTabMixin(localize(i18next)(PageView)))))))))))){static get styles(){return[css`
1
+ import { html, css } from 'lit-element'
2
+ import { merge } from 'lodash'
3
+ import gql from 'graphql-tag'
4
+
5
+ import { i18next, localize } from '@things-factory/i18n-base'
6
+ import { PageView } from '@things-factory/shell'
7
+
8
+ import { client } from '@operato/graphql'
9
+ import { store } from '@operato/shell'
10
+ import { CommonButtonStyles } from '@operato/styles'
11
+
12
+ import { ButtonConfigTabMixin } from './button-config-tab-mixin'
13
+ import { MenuConfigTabMixin } from './menu-config-tab-mixin'
14
+ import { SearchConfigTabMixin } from './search-config-tab-mixin'
15
+ import { GridConfigTabMixin } from './grid-config-tab-mixin'
16
+ import { ColumnConfigTabMixin } from './column-config-tab-mixin'
17
+ import { GraphQlConfigTabMixin } from './graphql-config-tab-mixin'
18
+ import { FormConfigTabMixin } from './form-config-tab-mixin'
19
+ import { TabConfigTabMixin } from './tab-config-tab-mixin'
20
+ import { EtcConfigTabMixin } from './etc-config-tab-mixin'
21
+ import { GridEmphasizedConfigTabMixin } from './grid-emphasized-config-tab-mixin'
22
+
23
+ import { TermsUtil } from '@things-factory/meta-ui/client/utils/terms-util'
24
+ import { MetaApi } from '@things-factory/meta-ui/client/utils/meta-api'
25
+ import { MetaCrypto } from '@things-factory/meta-ui/client/utils/meta-crypto'
26
+
27
+ /**
28
+ * @license
29
+ * Copyright © HatioLab Inc. All rights reserved.
30
+ * @author wryang
31
+ * @description 페이지 생성기 화면
32
+ */
33
+ class MetaGeneratorPage extends MenuConfigTabMixin(GraphQlConfigTabMixin(GridConfigTabMixin(ColumnConfigTabMixin(ButtonConfigTabMixin(SearchConfigTabMixin(FormConfigTabMixin(TabConfigTabMixin(EtcConfigTabMixin(GridEmphasizedConfigTabMixin(localize(i18next)(PageView))))))))))){
34
+ static get styles() {
35
+ return [
36
+ css`
2
37
  :host {
3
38
  display: flex;
4
39
  flex-direction: column;
@@ -139,24 +174,489 @@ import{html,css}from"lit-element";import{merge}from"lodash";import gql from"grap
139
174
  ox-grist {
140
175
  overflow-y: auto;
141
176
  flex: 1;
142
- }`]}static get properties(){return{menuId:String,menuName:String,metaTemplate:Object,currentTabKey:String,tabData:Object,dataStorage:Object,viewMenuData:Object,afterSetFieldsConfig:Object,skipFieldsConfig:Object,viewGraphqlData:Object,gridPageOptions:Array,gridViewModes:Array,viewGridData:Object,columnTabGridConfig:Object,viewColumnData:Array,buttonTabGridConfig:Object,viewButtonData:Array,searchTabGridConfig:Object,viewSearchData:Array}}get context(){return{title:TermsUtil.tTitle("meta_generator"),actions:[{title:TermsUtil.tButton("save"),action:this.save.bind(this),...CommonButtonStyles.save},{title:TermsUtil.tButton("back"),action:this.backToMenu.bind(this),...CommonButtonStyles.back},{title:TermsUtil.tButton("refresh"),action:this.refresh.bind(this),...CommonButtonStyles.refresh}]}}deleteRow(t,e){let a=t.dirtyData;a.records=a.records.filter((t=>t.id!=e.id)),t.data=a}async save(){if(0==store.getState().operatoTools.studioPermission)return void document.dispatchEvent(new CustomEvent("notify",{detail:{level:"error",message:i18next.t("error.invalid license key")}}));if((await client.query({query:gql`
177
+ }`
178
+ ]
179
+ }
180
+
181
+ static get properties() {
182
+ return {
183
+ menuId: String,
184
+ menuName: String,
185
+ metaTemplate: Object,
186
+ currentTabKey: String,
187
+ tabData: Object,
188
+ dataStorage: Object,
189
+
190
+ viewMenuData: Object,
191
+
192
+ afterSetFieldsConfig: Object,
193
+ skipFieldsConfig: Object,
194
+ viewGraphqlData: Object,
195
+
196
+ gridPageOptions: Array,
197
+ gridViewModes: Array,
198
+ viewGridData: Object,
199
+
200
+ columnTabGridConfig: Object,
201
+ viewColumnData: Array,
202
+
203
+ buttonTabGridConfig: Object,
204
+ viewButtonData: Array,
205
+
206
+ searchTabGridConfig: Object,
207
+ viewSearchData: Array,
208
+ }
209
+ }
210
+
211
+ get context() {
212
+ return {
213
+ title: TermsUtil.tTitle('meta_generator'),
214
+ actions: [
215
+ {
216
+ title: TermsUtil.tButton('save'),
217
+ action: this.save.bind(this),
218
+ ...CommonButtonStyles.save
219
+ },
220
+ {
221
+ title: TermsUtil.tButton('back'),
222
+ action: this.backToMenu.bind(this),
223
+ ...CommonButtonStyles.back
224
+ },
225
+ {
226
+ title: TermsUtil.tButton('refresh'),
227
+ action: this.refresh.bind(this),
228
+ ...CommonButtonStyles.refresh
229
+ }
230
+ ]
231
+ }
232
+ }
233
+
234
+ /**
235
+ * @description 화면 내 그리드 데이터 삭제
236
+ *************************************
237
+ * @param {Object} grist
238
+ * @param {Object} record
239
+ */
240
+ deleteRow(grist, record) {
241
+ let gristData = grist.dirtyData;
242
+ gristData.records = gristData.records.filter(x => x.id != record.id);
243
+ grist.data = gristData;
244
+ }
245
+
246
+ /**
247
+ * @description 메타 생성 정보 저장
248
+ *******************************
249
+ */
250
+ async save() {
251
+ if(store.getState().operatoTools.studioPermission == false) {
252
+ document.dispatchEvent(
253
+ new CustomEvent('notify', {
254
+ detail: {
255
+ level: 'error',
256
+ message: i18next.t('error.invalid license key')
257
+ }
258
+ })
259
+ )
260
+ return;
261
+ }
262
+
263
+ let response = await client.query({
264
+ query: gql`
143
265
  query ($id: String!) {
144
266
  studioTemplateIsOverLimit(id: $id)
145
267
  }
146
- `,variables:{id:this.menuId}})).errors)return;let t={},e={};Object.keys(this.tabData).forEach((a=>{let r=this.convertFirstCharUpperCase(a);t[a]=this[`get${r}ConfigTabValues`](),e=merge(e,t[a])})),e=JSON.stringify(e),e=MetaCrypto.enc(e),await MetaApi.updateMultiple("updateMultipleMenu",[{id:this.menuId,template:e,cuFlag:"M"}])&&await this.initData()}clear(){this.setTabData(),this.dataStorage={menu:{},graphql:{},button:[],column:[],grid:{},search:[],form:[],tab:[],etc:{},gridEmphasized:{}},Object.keys(this.tabData).forEach((t=>{let e=this.convertFirstCharUpperCase(t);if(this[`set${e}ConfigTabValues`])return this[`set${e}ConfigTabValues`](this.dataStorage[t])}))}async refresh(){this.clear(),await this.initData()}backToMenu(){history.back()}async initData(){let{menuId:t=""}=this.lifecycle?.params?this.lifecycle.params:{};if(this.menuId=t,!t||""==t)return void this.clear();let e=await MetaApi.findOne("menu",t,"\n id\n name\n template\n ");if(!e)return;try{JSON.parse(MetaCrypto.dec(e.template))}catch(t){return}this.menuName=TermsUtil.tMenu(e.name),this.metaTemplate=e.template?JSON.parse(MetaCrypto.dec(e.template)):{};let{menu:a={},gql:r={},button:i=[],grid_column:o=[],grid:n={},search:s=[],form:l=[],tab:d=[],etc:c={},gridEmphasized:m=[]}=this.metaTemplate?this.metaTemplate:{};this.setTabData(),this.dataStorage={},this.dataStorage.menu=a,this.dataStorage.graphql=r,this.dataStorage.grid=n,this.dataStorage.form=l,this.dataStorage.tab=d,this.dataStorage.etc=c,this.dataStorage.gridEmphasized=m,(n.option?.sorters||[]).forEach(((t,e)=>{t.rank=10*(e+1)})),this.dataStorage.column=o.map((t=>{let e=(n.option?.sorters||[]).filter((e=>e.name==t.name));return e&&e.length>0?(t.sort_rank=e[0].rank,t.sort_desc=!!e[0].desc&&e[0].desc):t.sort_rank=0,t.rep_field=(n.list?.fields||[]).includes(t.name),t.detail_field=(n.list?.details||[]).includes(t.name),t.thumbnail_field=n.list?.thumbnail==t.name,t})),s.push(...(r.query?.filters||[]).map((t=>(t.hidden=!0,t)))),this.dataStorage.search=s,i.push(...(n.button||[]).map((t=>(t.type=`grid-${t.type}`,t.style=t.icon,t)))),this.dataStorage.button=i,Object.keys(this.tabData).forEach((t=>{let e=this.convertFirstCharUpperCase(t);if(this[`set${e}ConfigTabValues`])return this[`set${e}ConfigTabValues`](this.dataStorage[t])}))}async pageInitialized(){this.setTabData();let t=Object.keys(this.tabData);for(let e=0;e<t.length;e++){let a=this.convertFirstCharUpperCase(t[e]);this[`set${a}ConfigTabConfig`]&&await this[`set${a}ConfigTabConfig`]()}}async pageUpdated(t,e,a){!0===this.active?(this.setTabData(),await this.initData(),this.setTabData()):(this.clear(),this.remove())}setTabData(){this.tabData||(this.tabData={menu:TermsUtil.tLabel("menu_config"),graphql:TermsUtil.tLabel("graphql_config"),grid:TermsUtil.tLabel("grid_config"),column:TermsUtil.tLabel("column_config"),gridEmphasized:TermsUtil.tLabel("grid_emphasized_config"),button:TermsUtil.tLabel("button_config"),search:TermsUtil.tLabel("search_config"),form:TermsUtil.tLabel("form_config"),tab:TermsUtil.tLabel("tab_config"),etc:TermsUtil.tLabel("etc_config")})}render(){this.currentTabKey||(this.currentTabKey="menu"),this.setTabData();let t=Object.keys(this.tabData);this.tabData[this.currentTabKey]?this.currentTabKey:t[0];return html`
268
+ `,
269
+ variables: { id: this.menuId }
270
+ })
271
+
272
+ if(response.errors) {
273
+ return;
274
+ }
275
+
276
+ let tabResults = {};
277
+ let template = {};
278
+
279
+ Object.keys(this.tabData).forEach(key => {
280
+ let convKey = this.convertFirstCharUpperCase(key);
281
+ tabResults[key] = this[`get${convKey}ConfigTabValues`]();
282
+ template = merge(template, tabResults[key])
283
+ })
284
+
285
+ template = JSON.stringify(template);
286
+ template = MetaCrypto.enc(template);
287
+
288
+ let result = await MetaApi.updateMultiple('updateMultipleMenu', [{ id: this.menuId , template: template, cuFlag: 'M' }]);
289
+ if (result) {
290
+ await this.initData();
291
+ }
292
+ }
293
+
294
+ /**
295
+ * @description 기존 데이터 clear
296
+ *******************************
297
+ */
298
+ clear() {
299
+ this.setTabData();
300
+
301
+ this.dataStorage = {
302
+ menu: {},
303
+ graphql: {},
304
+ button: [],
305
+ column: [],
306
+ grid: {},
307
+ search: [],
308
+ form: [],
309
+ tab: [],
310
+ etc: {},
311
+ gridEmphasized: {}
312
+ };
313
+
314
+ Object.keys(this.tabData).forEach(key => {
315
+ let convKey = this.convertFirstCharUpperCase(key);
316
+ if(this[`set${convKey}ConfigTabValues`]) {
317
+ return this[`set${convKey}ConfigTabValues`](this.dataStorage[key]);
318
+ }
319
+ })
320
+ }
321
+
322
+ /**
323
+ * @description 초기화
324
+ *********************
325
+ */
326
+ async refresh() {
327
+ this.clear();
328
+ await this.initData();
329
+ }
330
+
331
+ /**
332
+ * @description 메뉴 화면으로 돌아가기
333
+ *********************************
334
+ */
335
+ backToMenu() {
336
+ history.back();
337
+ }
338
+
339
+ /**
340
+ * @description 메뉴 데이터 가져오기
341
+ ********************************
342
+ * @returns
343
+ */
344
+ async initData() {
345
+ // 1. 파라미터에서 menuId 추출
346
+ let { menuId = '' } = this.lifecycle?.params ? this.lifecycle.params : {};
347
+ this.menuId = menuId;
348
+
349
+ // 2. 메뉴 ID가 지정되지 않은 페이지 호출은 무시
350
+ if(!menuId || menuId == '') {
351
+ this.clear();
352
+ return;
353
+ }
354
+
355
+ // 3. 메뉴 데이터 가져오기
356
+ let selectFields = `
357
+ id
358
+ name
359
+ template
360
+ `
361
+ let response = await MetaApi.findOne('menu', menuId, selectFields);
362
+
363
+ if(!response) {
364
+ return;
365
+ }
366
+
367
+ try {
368
+ JSON.parse(MetaCrypto.dec(response.template));
369
+ } catch(e) {
370
+ return;
371
+ }
372
+
373
+ // 4. 조회 값 셋팅
374
+ this.menuName = TermsUtil.tMenu(response.name);
375
+ this.metaTemplate = response.template ? JSON.parse(MetaCrypto.dec(response.template)) : {};
376
+ let {
377
+ menu = {},
378
+ gql = {},
379
+ button = [],
380
+ grid_column = [],
381
+ grid = {},
382
+ search = [],
383
+ form = [],
384
+ tab = [],
385
+ etc = {},
386
+ gridEmphasized = []
387
+ } = this.metaTemplate ? this.metaTemplate : {};
388
+ this.setTabData();
389
+
390
+ // 5. dataStorage 생성
391
+ this.dataStorage = {}
392
+ this.dataStorage.menu = menu;
393
+ this.dataStorage.graphql = gql;
394
+ this.dataStorage.grid = grid;
395
+ this.dataStorage.form = form;
396
+ this.dataStorage.tab = tab;
397
+ this.dataStorage.etc = etc;
398
+ this.dataStorage.gridEmphasized = gridEmphasized;
399
+
400
+ // 6. 정렬 필드에 rank 추가
401
+ (grid.option?.sorters || []).forEach((value, index) => {
402
+ value.rank = ((index + 1) * 10);
403
+ })
404
+
405
+ // 7. 정렬 필드, 리스트, 카드 대표, 상세 필드, 썸네일 필드, 누적 계산 등 설정
406
+ this.dataStorage.column = grid_column.map(x => {
407
+ // 정렬 필드 추가
408
+ let sortField = (grid.option?.sorters || []).filter(y => y.name == x.name);
409
+ if(sortField && sortField.length > 0) {
410
+ x.sort_rank = sortField[0].rank;
411
+ x.sort_desc = sortField[0].desc ? sortField[0].desc : false;
412
+ } else {
413
+ x.sort_rank = 0;
414
+ }
415
+
416
+ // 리스트 / 카드 대표 필드 설정
417
+ x.rep_field = (grid.list?.fields || []).includes(x.name);
418
+
419
+ // 리스트 / 카드 상세 필드 설정
420
+ x.detail_field = (grid.list?.details || []).includes(x.name);
421
+
422
+ // 썸네일 필드
423
+ x.thumbnail_field = (grid.list?.thumbnail == x.name);
424
+ return x;
425
+ });
426
+
427
+ // 8. 검색 설정과 Gql 쿼리의 기본 검색값을 병합
428
+ search.push(...(gql.query?.filters || []).map(x => {
429
+ // GraphQL에 있는 숨겨진 검색 조건 추가
430
+ x.hidden = true;
431
+ return x;
432
+ }));
433
+ this.dataStorage.search = search;
434
+
435
+ // 9. 일반 버튼과 그리드 버튼을 병합
436
+ button.push(...(grid.button || []).map(x => {
437
+ x.type = `grid-${x.type}`;
438
+ x.style = x.icon;
439
+ return x;
440
+ }));
441
+
442
+ this.dataStorage.button = button;
443
+
444
+ Object.keys(this.tabData).forEach(key => {
445
+ let convKey = this.convertFirstCharUpperCase(key);
446
+ if(this[`set${convKey}ConfigTabValues`]) {
447
+ return this[`set${convKey}ConfigTabValues`](this.dataStorage[key]);
448
+ }
449
+ })
450
+ }
451
+
452
+ /**
453
+ * @override lifecycle
454
+ ***********************
455
+ */
456
+ async pageInitialized() {
457
+ // 탭에 데이터 설정
458
+ this.setTabData();
459
+
460
+ // 각 탭 별 config set 설정 호출
461
+ let keys = Object.keys(this.tabData);
462
+ for(let idx = 0 ; idx < keys.length ; idx++) {
463
+ let key = this.convertFirstCharUpperCase(keys[idx]);
464
+ if(this[`set${key}ConfigTabConfig`]) {
465
+ await this[`set${key}ConfigTabConfig`]();
466
+ }
467
+ }
468
+ }
469
+
470
+ /**
471
+ * @override lifecycle
472
+ ***********************
473
+ * @param {*} changes
474
+ * @param {*} lifecycle
475
+ * @param {*} before
476
+ */
477
+ async pageUpdated(changes, lifecycle, before) {
478
+ // 1. 페이지 활성화 시
479
+ if (this.active === true) {
480
+ // 1.1 탭에 데이터 설정
481
+ this.setTabData();
482
+ // 1.2 메뉴 템플릿 정보 조회
483
+ await this.initData();
484
+ // 1.3 메뉴 구성 탭 정보 설정
485
+ this.setTabData();
486
+
487
+ // 2. 페이지 비활성화 시
488
+ } else {
489
+ this.clear();
490
+ this.remove();
491
+ }
492
+ }
493
+
494
+ /**
495
+ * @description 탭 데이터 생성
496
+ ***************************
497
+ */
498
+ setTabData() {
499
+ if (!this.tabData) {
500
+ this.tabData = {
501
+ menu: TermsUtil.tLabel('menu_config'),
502
+ graphql: TermsUtil.tLabel('graphql_config'),
503
+ grid: TermsUtil.tLabel('grid_config'),
504
+ column: TermsUtil.tLabel('column_config'),
505
+ gridEmphasized: TermsUtil.tLabel('grid_emphasized_config'),
506
+ button: TermsUtil.tLabel('button_config'),
507
+ search: TermsUtil.tLabel('search_config'),
508
+ form: TermsUtil.tLabel('form_config'),
509
+ tab: TermsUtil.tLabel('tab_config'),
510
+ etc: TermsUtil.tLabel('etc_config')
511
+ }
512
+ }
513
+ }
514
+
515
+ /**
516
+ * @override render
517
+ ********************
518
+ * @returns {HTML}
519
+ */
520
+ render() {
521
+ if (!this.currentTabKey) this.currentTabKey = 'menu';
522
+ this.setTabData();
523
+
524
+ let tabKeys = Object.keys(this.tabData);
525
+ const currentTabKey = this.tabData[this.currentTabKey] ? this.currentTabKey : tabKeys[0];
526
+
527
+ let renderHtml = html`
147
528
  <h1>${this.menuName}</h1>
148
529
  <div class="tabs">
149
- ${t.map((t=>{let e=this.tabData[t];return html`
150
- <div class="tab" ?activate="${t===this.currentTabKey}" @click="${()=>this.currentTabKey=t}">
151
- <span>${e}</span>
530
+ ${tabKeys.map(key => {
531
+ let label = this.tabData[key]
532
+ return html`
533
+ <div class="tab" ?activate="${key === this.currentTabKey}" @click="${() => (this.currentTabKey = key)}">
534
+ <span>${label}</span>
152
535
  </div>
153
- `}))}
536
+ `
537
+ })}
154
538
  </div>
155
539
  <div class="content-container">
156
- ${t.map((t=>{let e="display:none";return t==this.currentTabKey&&(e="display:flex"),html`
157
- <div class='tab-contents' style="${e}">
158
- ${this.getConfigTab(t)}
540
+ ${tabKeys.map(key => {
541
+ let displayStyle = 'display:none';
542
+ if(key == this.currentTabKey) {
543
+ displayStyle = 'display:flex'
544
+ }
545
+
546
+ return html`
547
+ <div class='tab-contents' style="${ displayStyle }">
548
+ ${this.getConfigTab(key)}
159
549
  </div>
160
- `}))}
550
+ `
551
+ })}
161
552
  </div>
162
- `}getConfigTab(t){let e=this.convertFirstCharUpperCase(t);return this[`render${e}ConfigTab`]?this[`render${e}ConfigTab`]():html``}convertFirstCharUpperCase(t){return t.charAt(0).toUpperCase()+t.slice(1)}getElementById(t){return this.shadowRoot.querySelector(`#${t}`)}getElementValueById(t){let e=this.shadowRoot.querySelector(`#${t}`);if(!e)return;let a="";if("select"==e.tagName.toLowerCase()){if(!e.options||0==e.options.length)return;a=e.options[e.selectedIndex].value}else{if("ox-grist"==e.tagName.toLowerCase()){if(!e.dirtyData)return;if(!e.dirtyData.records)return;if(0==e.dirtyData.records.length)return;return e.dirtyData.records}if("ox-input-code"==e.tagName.toLowerCase())return e.value;if("radio"==e.type.toLowerCase()){let e=this.shadowRoot.querySelector(`#${t}:checked`);if(!e)return;return e.value}a=e.value}return a&&""!=a?a:void 0}sortRecordByRank(t){return t?this.sortRecordByField(t,"rank"):t}sortRecordByField(t,e){return t.sort(((t,a)=>t[e]-a[e])),t}}customElements.define("meta-generator-page",MetaGeneratorPage);
553
+ `
554
+ return renderHtml;
555
+ }
556
+
557
+ /**
558
+ * @description 탭 키로 탭 정보 리턴
559
+ ********************************
560
+ */
561
+ getConfigTab(key) {
562
+ let convKey = this.convertFirstCharUpperCase(key);
563
+
564
+ if(this[`render${convKey}ConfigTab`]) {
565
+ return this[`render${convKey}ConfigTab`]();
566
+ }
567
+
568
+ return html``
569
+ }
570
+
571
+ /**
572
+ * @description 탭 키로 탭 정보 리턴
573
+ ********************************
574
+ * @param {String} word
575
+ */
576
+ convertFirstCharUpperCase(word) {
577
+ let convWord = word.charAt(0).toUpperCase() + word.slice(1);
578
+ return convWord;
579
+ }
580
+
581
+ /**
582
+ * @description id로 엘리먼트 추출 리턴
583
+ ***********************************
584
+ * @param {String} id
585
+ * @returns {HTML}
586
+ */
587
+ getElementById(id) {
588
+ return this.shadowRoot.querySelector(`#${id}`);
589
+ }
590
+
591
+ /**
592
+ * @description id로 엘리먼트 값 추출 리턴
593
+ *************************************
594
+ * @param {String} id
595
+ * @returns {HTML}
596
+ */
597
+ getElementValueById(id) {
598
+ let element = this.shadowRoot.querySelector(`#${id}`);
599
+ if(!element) return undefined;
600
+
601
+ let elementValue = '';
602
+ if(element.tagName.toLowerCase() == 'select') {
603
+ if(!element.options || element.options.length == 0) return undefined;
604
+ elementValue = element.options[element.selectedIndex].value;
605
+
606
+ } else if (element.tagName.toLowerCase() == 'ox-grist') {
607
+ if(!element.dirtyData) return undefined;
608
+ if(!element.dirtyData.records) return undefined;
609
+ if(element.dirtyData.records.length == 0) return undefined;
610
+ return element.dirtyData.records;
611
+
612
+ } else if (element.tagName.toLowerCase() == 'ox-input-code') {
613
+ return element.value;
614
+
615
+ } else {
616
+ if(element.type.toLowerCase() == 'radio') {
617
+ let radioEle = this.shadowRoot.querySelector(`#${id}:checked`);
618
+ if(!radioEle) return undefined;
619
+ return radioEle.value;
620
+
621
+ } else {
622
+ elementValue = element.value;
623
+ }
624
+ }
625
+
626
+ if(!elementValue || elementValue == '') {
627
+ return undefined;
628
+ }
629
+
630
+ return elementValue;
631
+ }
632
+
633
+ /**
634
+ * @description 랭킹으로 소팅 처리
635
+ ******************************
636
+ * @param {Array} list
637
+ * @returns {Array}
638
+ */
639
+ sortRecordByRank(list) {
640
+ if(!list) {
641
+ return list;
642
+ } else {
643
+ return this.sortRecordByField(list, 'rank');
644
+ }
645
+ }
646
+
647
+ /**
648
+ * @description 랭킹으로 소팅 처리 후 리턴
649
+ ************************************
650
+ * @param {Array} list
651
+ * @param {String} field
652
+ * @returns {Array}
653
+ */
654
+ sortRecordByField(list, field) {
655
+ list.sort((a, b) => {
656
+ return a[field] - b[field];
657
+ });
658
+ return list;
659
+ }
660
+ }
661
+
662
+ customElements.define('meta-generator-page', MetaGeneratorPage)