@things-factory/meta-ui 7.0.1-alpha.57 → 7.0.1-alpha.59

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.
@@ -2,7 +2,7 @@ import gql from 'graphql-tag'
2
2
 
3
3
  import { asyncReplace } from 'lit/directives/async-replace.js'
4
4
 
5
- import { store, gqlContext } from '@things-factory/shell'
5
+ import { store } from '@things-factory/shell'
6
6
  import { getCodeByName } from '@things-factory/code-base'
7
7
  import { EXPORT } from '@things-factory/export-base'
8
8
  import { gqlBuilder } from '@things-factory/utils'
@@ -42,38 +42,7 @@ export class ServiceUtil {
42
42
  }
43
43
 
44
44
  // codeSet이 문자이면 코드 조회
45
- let codes = await ServiceUtil.getWorkCodeByName(codeSet)
46
- return codes && codes.length > 0 ? codes : await getCodeByName(codeSet)
47
- }
48
-
49
- /**
50
- * @description 업무 코드 명으로 업무 코드 리스트 조회 후 리턴
51
- ****************************************************
52
- * @param {String} codeName 업무 코드 명
53
- * @returns {Array} 코드 리스트
54
- */
55
- static async getWorkCodeByName(codeName) {
56
- const response = await client.query({
57
- query: gql`
58
- query workCodeByName($name: String!) {
59
- commonCode: workCodeByName(name: $name) {
60
- details {
61
- rank
62
- name
63
- description
64
- }
65
- }
66
- }
67
- `,
68
- variables: { name: codeName },
69
- context: gqlContext()
70
- })
71
-
72
- if (!response.errors && response.data.workCodeByName && response.data.workCodeByName.details) {
73
- return response.data.workCodeByName.details.sort((a, b) => a.rank - b.rank)
74
- } else {
75
- return []
76
- }
45
+ return await getCodeByName(codeSet)
77
46
  }
78
47
 
79
48
  /**
@@ -517,12 +486,12 @@ export class ServiceUtil {
517
486
  filters: grist.filters
518
487
  }
519
488
  })
520
-
489
+
521
490
  // 2. 응답 처리
522
491
  const data = response.data.responses
523
492
  const bufferData = Buffer.from(data, 'base64')
524
493
  const blob = new Blob([bufferData], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
525
-
494
+
526
495
  const a = document.createElement('a')
527
496
  a.href = window.URL.createObjectURL(blob)
528
497
  a.download = `${exportFileName}.xlsx`
@@ -908,7 +877,7 @@ export class ServiceUtil {
908
877
  static async callService(pageView, action, filterParam, dataParams) {
909
878
  if (action.graphql_type == 'query') {
910
879
  return await ServiceUtil.callQueryService(action, filterParam, dataParams)
911
- } else if(action.graphql_type == 'export') {
880
+ } else if (action.graphql_type == 'export') {
912
881
  return await ServiceUtil.exportableDataByServer(action.export_file_name, action.query_name, pageView.grist)
913
882
  } else {
914
883
  return await ServiceUtil.callMutationService(action, filterParam, dataParams)
@@ -9,58 +9,57 @@ import { TermsUtil } from './terms-util'
9
9
  * @description 데이터 핸들링 관련 유틸리티 함수 정의
10
10
  */
11
11
  export class ValueUtil {
12
-
13
12
  /**
14
13
  * @description object, string, number, array 빈 값 여부 검사
15
14
  **********************************************************
16
- * @param {Object} value
15
+ * @param {Object} value
17
16
  * @returns {Boolean}
18
17
  */
19
18
  static isEmpty(value) {
20
19
  if (value === undefined) {
21
- return true;
20
+ return true
22
21
  } else if (value === null) {
23
- return true;
22
+ return true
24
23
  } else if (typeof value === 'boolean') {
25
- return false;
24
+ return false
26
25
  } else if (typeof value === 'string' || typeof value === 'number') {
27
- if (value == '') return true;
26
+ if (value == '') return true
28
27
  } else if (Array.isArray(value)) {
29
- if (value.length == 0) return true;
28
+ if (value.length == 0) return true
30
29
  } else if (typeof value === 'object') {
31
- if (Object.keys(value).length == 0) return true;
30
+ if (Object.keys(value).length == 0) return true
32
31
  }
33
32
 
34
- return false;
33
+ return false
35
34
  }
36
35
 
37
36
  /**
38
37
  * @description object, string, number, array 빈 값이 아닌지 여부 검사
39
38
  *****************************************************************
40
- * @param {Object} value
39
+ * @param {Object} value
41
40
  * @returns {Boolean}
42
41
  */
43
42
  static isNotEmpty(value) {
44
- return !ValueUtil.isEmpty(value);
43
+ return !ValueUtil.isEmpty(value)
45
44
  }
46
45
 
47
46
  /**
48
47
  * @description 두 객체가 동일한지 비교
49
48
  **********************************
50
- * @param {*} data1
51
- * @param {*} data2
52
- * @returns
49
+ * @param {*} data1
50
+ * @param {*} data2
51
+ * @returns
53
52
  */
54
53
  static isEquals(data1, data2) {
55
- return isEqual(data1, data2);
54
+ return isEqual(data1, data2)
56
55
  }
57
56
 
58
57
  /**
59
58
  * @description 값을 정수로 변환
60
59
  **********************************
61
- * @param {*} value
62
- * @param {*} defaultValue
63
- * @returns
60
+ * @param {*} value
61
+ * @param {*} defaultValue
62
+ * @returns
64
63
  */
65
64
  static toInteger(value, defaultValue) {
66
65
  return ValueUtil.isEmpty(value) ? (defaultValue ? defaultValue : 0) : parseInt(value)
@@ -70,95 +69,98 @@ export class ValueUtil {
70
69
  * @description 값을 Boolean으로 변환
71
70
  **********************************
72
71
  * @param {String} value
73
- * @returns
72
+ * @returns
74
73
  */
75
74
  static toBoolean(value) {
76
- return ValueUtil.isEmpty(value) ? false : (value == 'true' || value == 't' || value == 'TRUE' || value == 'T' || value == 'on' || value == 'ON');
75
+ return ValueUtil.isEmpty(value) ? false : value == 'true' || value == 't' || value == 'TRUE' || value == 'T' || value == 'on' || value == 'ON'
77
76
  }
78
77
 
79
78
  /**
80
79
  * @description config, data의 key 값을 비교해 결과를 리턴한다.
81
80
  * 값에 * 는 체크하지 않는다.
82
- ****************************************
83
- * @param {Object} config
84
- * @param {Object} data
85
- * @param {String || Array} keys
86
- * @returns
81
+ ****************************************
82
+ * @param {Object} config
83
+ * @param {Object} data
84
+ * @param {String || Array} keys
85
+ * @returns
87
86
  */
88
87
  static compareObjectValues(config, data, keys) {
89
- let isEquals = true;
88
+ let isEquals = true
90
89
 
91
90
  keys.forEach(key => {
92
- let compareValue = config[key];
91
+ let compareValue = config[key]
93
92
 
94
93
  if (compareValue === '*') {
95
- return;
94
+ return
96
95
  }
97
96
 
98
- let recordValue = data[key] || '';
97
+ let recordValue = data[key] || ''
99
98
 
100
99
  if (ValueUtil.isEmpty(compareValue)) {
101
100
  if (ValueUtil.isNotEmpty(recordValue)) {
102
- isEquals = false;
101
+ isEquals = false
103
102
  }
104
103
  } else {
105
104
  if (compareValue != recordValue) {
106
- isEquals = false;
105
+ isEquals = false
107
106
  }
108
107
  }
109
108
 
110
- if(!isEquals) {
111
- return;
109
+ if (!isEquals) {
110
+ return
112
111
  }
113
112
  })
114
113
 
115
- return isEquals;
114
+ return isEquals
116
115
  }
117
116
 
118
117
  /**
119
118
  * @description dataObject 에서 key 값을 찾아 isTransMsg 옵션을 적용해 retObjct에 반영한다.
120
119
  **********************************************************************************
121
- * @param {Object} retObj
122
- * @param {Object} dataObj
123
- * @param {String} key
124
- * @param {Boolean} isTransMsg
125
- * @returns
120
+ * @param {Object} retObj
121
+ * @param {Object} dataObj
122
+ * @param {String} key
123
+ * @param {Boolean} isTransMsg
124
+ * @returns
126
125
  */
127
126
  static setParams(retObj, dataObj, key, isTransMsg) {
128
- let value = ValueUtil.getParams(dataObj, key);
127
+ let value = ValueUtil.getParams(dataObj, key)
129
128
 
130
129
  if (ValueUtil.isNotEmpty(value)) {
131
- retObj[key] = isTransMsg === true ? TermsUtil.t(value) : value;
130
+ retObj[key] = isTransMsg === true ? TermsUtil.t(value) : value
132
131
  }
133
132
 
134
- return retObj;
133
+ return retObj
135
134
  }
136
135
 
137
136
  /**
138
- * @description data에서 key(Array)를 찾아 리턴
137
+ * @description data에서 key(Array)를 찾아 리턴
139
138
  ********************************************
140
- * @param {Object} data
141
- * @param {...String} keys
142
- * @returns
139
+ * @param {Object} data
140
+ * @param {...String} keys
141
+ * @returns
143
142
  */
144
143
  static getParams(data, ...keys) {
145
- // keys 파라미터가 없으면 return
144
+ // probably same as followings
145
+ // return lodash.get(data, keys.join('.'))
146
+
147
+ // keys 파라미터가 없으면 return
146
148
  if (arguments.length <= 1) {
147
- return undefined;
149
+ return undefined
148
150
  }
149
151
 
150
- let key = keys[0];
151
- // data 에 key가 없으면 return
152
+ let key = keys[0]
153
+ // data 에 key가 없으면 return
152
154
  if (ValueUtil.isEmpty(data[key])) {
153
- return undefined;
155
+ return undefined
154
156
  }
155
157
 
156
- let paramData = data[key];
158
+ let paramData = data[key]
157
159
  if (keys.length > 1) {
158
- // 현재 이후에 키가 더 있으면 재귀 호출
159
- return ValueUtil.getParams(paramData, ...keys.slice(1));
160
+ // 현재 이후에 키가 더 있으면 재귀 호출
161
+ return ValueUtil.getParams(paramData, ...keys.slice(1))
160
162
  } else {
161
- return paramData;
163
+ return paramData
162
164
  }
163
165
  }
164
166
 
@@ -167,21 +169,21 @@ export class ValueUtil {
167
169
  ***********************************************************************
168
170
  * @param {Array} sourceList
169
171
  * @param {Array} targetList
170
- * @param {...String} keys
172
+ * @param {...String} keys
171
173
  * @returns {Array} 복사한 객체 리스트
172
174
  */
173
175
  static populateArray(sourceList, targetList, ...keys) {
174
- targetList = targetList || [];
175
- keys = keys || Object.keys(sourceList);
176
-
177
- if(ValueUtil.isNotEmpty(keys)) {
176
+ targetList = targetList || []
177
+ keys = keys || Object.keys(sourceList)
178
+
179
+ if (ValueUtil.isNotEmpty(keys)) {
178
180
  targetList = sourceList.map((source, index) => {
179
- let target = targetList.length > index ? targetList[index] : {};
180
- return ValueUtil.populateObject(source, target, keys);
181
+ let target = targetList.length > index ? targetList[index] : {}
182
+ return ValueUtil.populateObject(source, target, keys)
181
183
  })
182
184
  }
183
185
 
184
- return targetList;
186
+ return targetList
185
187
  }
186
188
 
187
189
  /**
@@ -189,20 +191,20 @@ export class ValueUtil {
189
191
  ********************************************************
190
192
  * @param {Object} source
191
193
  * @param {Object} target
192
- * @param {...String} keys
194
+ * @param {...String} keys
193
195
  * @returns {Object} 복사한 객체
194
196
  */
195
197
  static populateObject(source, target, ...keys) {
196
- target = target || {};
197
- keys = keys || Object.keys(source);
198
+ target = target || {}
199
+ keys = keys || Object.keys(source)
198
200
 
199
- if(ValueUtil.isNotEmpty(keys)) {
201
+ if (ValueUtil.isNotEmpty(keys)) {
200
202
  keys.forEach(key => {
201
- target[key] = source[key];
203
+ target[key] = source[key]
202
204
  })
203
205
  }
204
206
 
205
- return target;
207
+ return target
206
208
  }
207
209
 
208
210
  /**
@@ -219,9 +221,9 @@ export class ValueUtil {
219
221
  objKeys.forEach(key => {
220
222
  let value = sourceObj[key]
221
223
 
222
- if(typeof value == 'string' && value.startsWith('$')) {
224
+ if (typeof value == 'string' && value.startsWith('$')) {
223
225
  let valueFieldName = value.replace('$', '')
224
- if(targetKeys.includes(valueFieldName)) {
226
+ if (targetKeys.includes(valueFieldName)) {
225
227
  sourceObj[key] = targetObj[valueFieldName]
226
228
  }
227
229
  }
@@ -229,4 +231,4 @@ export class ValueUtil {
229
231
 
230
232
  return sourceObj
231
233
  }
232
- }
234
+ }
@@ -107,7 +107,11 @@ export function MetaFormMixin(baseElement: any): {
107
107
  * @returns {Object}
108
108
  */
109
109
  getData(): any;
110
- getCustomButtonContainerStyle(): any[];
110
+ getCustomButtonContainerStyle(): any[]; /**
111
+ * @description 폼 상세 렌터링 정보
112
+ *******************************
113
+ * @type {Object}
114
+ */
111
115
  getContextButtons(): any[];
112
116
  getButtonContainer(): HTML;
113
117
  getBasicButtonHandler(type: string, action: string, logic: any): any;
@@ -139,10 +143,10 @@ export function MetaFormMixin(baseElement: any): {
139
143
  setParentId(id: string): void;
140
144
  };
141
145
  /**
142
- * @description 스타일 정의
143
- **************************
144
- * @returns {Array} 스타일
145
- */
146
+ * @description 스타일 정의
147
+ **************************
148
+ * @returns {Array} 스타일
149
+ */
146
150
  readonly styles: any[];
147
151
  /**
148
152
  * @description 프로퍼티 정의
@@ -11,12 +11,12 @@ import { MetaButtonMixin } from './meta-button-mixin';
11
11
  * @author Shortstop shortstop@hatiolab.com
12
12
  * @description 메뉴 메타 정보를 이용해 폼 화면 구성
13
13
  */
14
- export const MetaFormMixin = (baseElement) => class extends MetaButtonMixin(baseElement) {
14
+ export const MetaFormMixin = baseElement => class extends MetaButtonMixin(baseElement) {
15
15
  /**
16
- * @description 스타일 정의
17
- **************************
18
- * @returns {Array} 스타일
19
- */
16
+ * @description 스타일 정의
17
+ **************************
18
+ * @returns {Array} 스타일
19
+ */
20
20
  static get styles() {
21
21
  return MetaApi.getBasicFormStyles();
22
22
  }
@@ -86,7 +86,7 @@ export const MetaFormMixin = (baseElement) => class extends MetaButtonMixin(base
86
86
  if (this.isElement) {
87
87
  await this.fetch();
88
88
  }
89
- // 인풋 키 이벤트 처리
89
+ // 인풋 키 이벤트 처리
90
90
  this.renderRoot.addEventListener('keydown', e => {
91
91
  switch (e.key) {
92
92
  case 'Esc':
@@ -120,7 +120,7 @@ export const MetaFormMixin = (baseElement) => class extends MetaButtonMixin(base
120
120
  this.currentTarget = target;
121
121
  target.setAttribute('editing', 'true');
122
122
  });
123
- // 폼 뷰의 인풋에서 발생되는 변경 이벤트 처리
123
+ // 폼 뷰의 인풋에서 발생되는 변경 이벤트 처리
124
124
  this.addEventListener('field-change', e => {
125
125
  let { after, before, column, record, row } = e.detail;
126
126
  // before, after 값으로 달라진 값이 없으면 스킵
@@ -137,7 +137,7 @@ export const MetaFormMixin = (baseElement) => class extends MetaButtonMixin(base
137
137
  // 변경 값 셋팅
138
138
  let colName = column.name;
139
139
  record[colName] = after;
140
- // 변경 필드 정보
140
+ // 변경 필드 정보
141
141
  record.__dirtyfields__ = record.__dirtyfields__ || {};
142
142
  record.__origin__ = record.__origin__ || {};
143
143
  record.__dirtyfields__[colName] = {
@@ -272,7 +272,7 @@ export const MetaFormMixin = (baseElement) => class extends MetaButtonMixin(base
272
272
  if (ValueUtil.isEmpty(dirtyData)) {
273
273
  return undefined;
274
274
  }
275
- // 기존 데이터 존재 여부 - 변경 플래그 판단
275
+ // 기존 데이터 존재 여부 - 변경 플래그 판단
276
276
  if (ValueUtil.isNotEmpty(recordData.id)) {
277
277
  dirtyData.id = recordData.id;
278
278
  dirtyData.cuFlag = 'M';
@@ -280,7 +280,7 @@ export const MetaFormMixin = (baseElement) => class extends MetaButtonMixin(base
280
280
  else {
281
281
  dirtyData.cuFlag = '+';
282
282
  }
283
- // object 타입은 id만 전송되도록 변경
283
+ // object 타입은 id만 전송되도록 변경
284
284
  Object.keys(dirtyData).forEach(key => {
285
285
  if (typeof dirtyData[key] === 'object' && codeInputColumns.includes(key) == false) {
286
286
  dirtyData[key] = { id: dirtyData[key].id };
@@ -321,12 +321,14 @@ export const MetaFormMixin = (baseElement) => class extends MetaButtonMixin(base
321
321
  let patches = this.patchData;
322
322
  // 변경 여부 메시지 처리
323
323
  if (ValueUtil.isEmpty(patches)) {
324
- MetaApi.showAlertPopup('title.info', 'text.NOTHING_CHANGED');
324
+ MetaApi.showAlertPopup('title.info', 'text.NOTHING_CHANGED', 'warning', 'confirm');
325
325
  return;
326
326
  }
327
327
  // 필수 입력 컬럼
328
328
  let mandatoryColumns = {};
329
- (this.formColumnConfig || []).filter(x => x.mandatory === true).forEach(x => {
329
+ (this.formColumnConfig || [])
330
+ .filter(x => x.mandatory === true)
331
+ .forEach(x => {
330
332
  mandatoryColumns[x.name] = x.header;
331
333
  });
332
334
  // 필수 입력 값 체크
@@ -1 +1 @@
1
- {"version":3,"file":"meta-form-mixin.js","sourceRoot":"","sources":["../../client/mixin/meta-form-mixin.js"],"names":[],"mappings":"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","sourcesContent":["import { closePopup } from '@operato/popup'\n\nimport { MetaApi } from '../utils/meta-api'\nimport { MetaUiUtil } from '../utils/meta-ui-util'\nimport { ValueUtil } from '../utils/value-util'\nimport { UiUtil } from '../utils/ui-util'\nimport { TermsUtil } from '../utils/terms-util'\n\nimport { MetaButtonMixin } from './meta-button-mixin'\n\n/**\n * @license\n * Copyright © HatioLab Inc. All rights reserved.\n * @author Shortstop shortstop@hatiolab.com\n * @description 메뉴 메타 정보를 이용해 폼 화면 구성\n */\nexport const MetaFormMixin = (baseElement) => class extends MetaButtonMixin(baseElement) {\n /**\n * @description 스타일 정의\n **************************\n * @returns {Array} 스타일\n */\n static get styles() {\n return MetaApi.getBasicFormStyles();\n }\n\n /**\n * @description 프로퍼티 정의\n ***************************\n * @returns {Object} 프로퍼티\n */\n static get properties() {\n return {\n /**\n * @description 폽 컬럼 구성 정보\n ******************************\n * @type {Array}\n */\n formColumnConfig: Array,\n /**\n * @description 메뉴 메타 정보로 부터 추출한 후 폼을 위해 설정 정보 구성\n ************************************************************\n * @type {Object}\n */\n formConfigSet: Object,\n /**\n * @description 폼 상세 렌터링 정보 \n *******************************\n * @type {Object}\n */\n formRenderConfig: Array,\n /**\n * @description 데이터 레코드 \n ***************************\n * @type {Object}\n */\n record: Object\n }\n }\n\n /**\n * @description 컨텍스트\n ***********************\n * @returns {HTMLElement}\n */\n get context() {\n return MetaUiUtil.getContextObject(this)\n }\n\n /******************************************************\n * LifeCycle\n ******************************************************/\n\n /**\n * @override connectedCallback\n *******************************\n */\n async connectedCallback() {\n // 메뉴 메타 정보 조회 및 기본 파싱\n await this.getAndParseMenuMeta()\n\n if (this.isElement) {\n await this.parseFormConfigs()\n }\n\n if (this.activityDataSet) {\n this.dataSet = this.activityDataSet\n }\n\n if (this.is_activity === true && !this.parent_id) {\n this.parent_id = 'activity'\n }\n\n if (super.connectedCallback) {\n await super.connectedCallback()\n }\n\n if (this.isElement) {\n await this.fetch()\n }\n\n // 인풋 키 이벤트 처리 \n this.renderRoot.addEventListener('keydown', e => {\n switch (e.key) {\n case 'Esc':\n case 'Escape':\n // TODO 편집이 취소되어야 한다.\n case 'Enter':\n // 먼저 focus를 옮겨놓아야 focusout으로 인해서 popup이 닫히는 것을 방지할 수 있다.\n this.focus()\n\n if (this.currentTarget) {\n this.currentTarget.removeAttribute('editing')\n }\n\n this.currentTarget = null\n break\n default:\n }\n })\n\n // 인풋 클릭 처리 (readOnly <> editing)\n this.renderRoot.addEventListener('click', e => {\n e.stopPropagation()\n // target should be 'ox-grid-field'\n let target = e.target;\n\n if (this.currentTarget) {\n this.focus()\n this.currentTarget.removeAttribute('editing')\n }\n\n if (target.tagName !== 'OX-GRID-FIELD' || !target.column.record.editable) {\n this.focus()\n this.currentTarget = null\n return\n }\n\n this.currentTarget = target\n target.setAttribute('editing', 'true');\n })\n\n // 폼 뷰의 인풋에서 발생되는 변경 이벤트 처리 \n this.addEventListener('field-change', e => { \n let { after, before, column, record, row } = e.detail\n\n // before, after 값으로 달라진 값이 없으면 스킵\n if (ValueUtil.isEquals(after, before)) {\n return\n }\n\n // 유효성 체크 함수가 있는 경우 해당 함수 호출\n let validation = column.validation\n if (validation && typeof validation == 'function') {\n if (!validation.call(this, after, before, record, column)) {\n return\n }\n }\n\n // 변경 값 셋팅\n let colName = column.name\n record[colName] = after\n\n // 변경 필드 정보 \n record.__dirtyfields__ = record.__dirtyfields__ || {}\n record.__origin__ = record.__origin__ || {}\n record.__dirtyfields__[colName] = {\n before: record.__origin__[colName],\n after: record[colName]\n }\n\n // 같은 값으로 변경 되었다면\n if (ValueUtil.isEquals(record.__dirtyfields__[colName].before, record.__dirtyfields__[colName].after)) {\n delete record.__dirtyfields__[colName]\n }\n\n // dirty flag 설정\n record.__dirty__ = ValueUtil.isNotEmpty(record.__dirtyfields__) ? 'M' : ''\n\n this.record = { ...record }\n\n // form-field-change 변경 이벤트 전파\n this.dispatchEvent(\n new CustomEvent('form-field-change', {\n bubbles: true,\n composed: true,\n detail: e.detail\n })\n )\n })\n }\n\n /**\n * @override firstUpdated\n ***************************\n */\n async firstUpdated() {\n if (super.firstUpdated) {\n await super.firstUpdated()\n }\n }\n\n /**\n * @override pageInitialized\n *****************************\n */\n async pageInitialized() {\n if (this.isPage) {\n await this.parseFormConfigs()\n }\n\n if (super.pageInitialized) {\n await super.pageInitialized()\n }\n\n if (this.isPage) {\n await this.fetch()\n }\n }\n\n /**\n * @description 화면 그리기 \n *************************\n * @returns {HTMLElement}\n */\n render() {\n return MetaApi.getBasicFormHtml(this)\n }\n\n /**\n * @descrtiption 메뉴 메타 정보로 부터 기본 폼 정보 구성을 위한 Configuration\n *******************************************************************\n * @param {Object} menuMeta 메뉴 메타 정보\n */\n parseBasicFormConfigs(menuMeta) {\n this.formColumnConfig = menuMeta.grid_column\n this.formRenderConfig = menuMeta.form\n }\n\n /**\n * @descrtiption 폼 구성 정보 Configuration\n *****************************************\n */\n async parseFormConfigs() {\n this.formConfigSet = await MetaApi.parseFormConfigSet(this)\n }\n\n /********************************************************************\n * Data Filtering\n ********************************************************************/\n\n /**\n * @description 최초 조회된 원본 데이터 \n ***********************************\n * @returns {Object} 원본 데이터 (변경 값 무시)\n */\n get orgData() {\n return this.removeGarbageData(this.record.__origin__)\n }\n\n /**\n * @description 변경된 데이터 \n **************************\n * @returns {Object} 변경된 데이터만\n */\n get dirtyData() {\n if (ValueUtil.isEmpty((this.record || {}).__dirtyfields__)) {\n return {}\n }\n\n let retData = {};\n\n Object.entries(this.record.__dirtyfields__).map(([key, value]) => {\n if (key.startsWith('__') == false) {\n retData[key] = value.after\n }\n })\n\n return retData\n }\n\n /**\n * @description 현재 데이터 \n *************************\n * @returns {Object} 화면에 표현되어 있는 현재 데이터 (수정된 값 반영)\n */\n get currentData() {\n return this.removeGarbageData(this.record)\n }\n\n /**\n * @description 레코드 데이터에서 쓰레기 데이터 정리 \n ********************************************\n * @returns {Object} __dirty__,__dirtyfields__,__origin__ 등 (__ 로 시작되는 데이터 삭제)\n */\n removeGarbageData(data) {\n if(!data) return undefined\n\n let retData = {};\n\n Object.entries(data).map(([key, value]) => {\n if (key.startsWith('__') == false) {\n retData[key] = value\n }\n })\n\n return retData\n }\n\n /**\n * @description 트랜잭션을 위한 변경 데이터 + cuFlag 가져오기 \n *****************************************************\n * @returns {Object}\n */\n get patchData() {\n let dirtyData = this.dirtyData\n let recordData = this.record\n // 코드 인풋 타입\n let codeInputColumns = (this.formColumnConfig || []).filter(x => x.type === 'code-input').map(x => x.name)\n\n if (ValueUtil.isEmpty(dirtyData)) {\n return undefined\n }\n\n // 기존 데이터 존재 여부 - 변경 플래그 판단 \n if (ValueUtil.isNotEmpty(recordData.id)) {\n dirtyData.id = recordData.id\n dirtyData.cuFlag = 'M'\n } else {\n dirtyData.cuFlag = '+'\n }\n\n // object 타입은 id만 전송되도록 변경 \n Object.keys(dirtyData).forEach(key => {\n if(typeof dirtyData[key] === 'object' && codeInputColumns.includes(key) == false) {\n dirtyData[key] = { id: dirtyData[key].id }\n }\n })\n\n return [dirtyData]\n }\n\n /********************************************************************\n * C R U D Functions\n ********************************************************************/\n /**\n * @description 폼 데이터 조회\n ***************************\n */\n async fetch() {\n // 부모 ID가 없다면 리턴\n if (ValueUtil.isEmpty(this.parent_id)) return\n\n // 단건 조회 함수\n let findOneFunc = ValueUtil.getParams(this.gqlInfo, 'query', 'find_one_func')\n if(!findOneFunc) return;\n\n // 부모 ID로 조회\n let data = await this.findOne(this.parent_id)\n\n // 데이터 형식 맞추기\n data['__seq__'] = 1\n let orgData = {};\n Object.assign(orgData, data)\n data['__origin__'] = orgData\n this.record = { ...data }\n }\n\n /**\n * @description 폼 데이터 저장\n *****************************\n * @returns {Boolean} 저장 여부\n */\n async save() {\n let patches = this.patchData\n\n // 변경 여부 메시지 처리\n if (ValueUtil.isEmpty(patches)) {\n MetaApi.showAlertPopup('title.info', 'text.NOTHING_CHANGED')\n return\n }\n\n // 필수 입력 컬럼\n let mandatoryColumns = {};\n (this.formColumnConfig || []).filter(x => x.mandatory === true).forEach(x => { \n mandatoryColumns[x.name] = x.header\n })\n\n // 필수 입력 값 체크\n let allFields = this.currentData\n for(let key in mandatoryColumns) {\n if(allFields[key] === undefined || allFields[key] == '') {\n UiUtil.showAlertPopup('text.check-mandatory', TermsUtil.tText('check-mandatory-field', { x: TermsUtil.tLabel(mandatoryColumns[key]) }), 'info', 'confirm')\n return\n }\n }\n\n // 저장 서비스 호출\n let isRes = await this.updateMultiple(patches)\n if (isRes) {\n // 폼 데이터 조회\n await this.fetch()\n\n // 저장이 잘 되었고 팝업이라면 팝업 닫기\n if(this.isPopup) {\n closePopup(this)\n }\n }\n\n // 저장 결과 리턴\n return isRes\n }\n\n /**\n * @description 데이터 클리어\n ***************************\n */\n async clear() {\n if(this.record) {\n this.record = {};\n }\n }\n\n /**\n * @description 데이터 리턴\n *************************\n * @returns {Object}\n */\n getData() {\n return this.currentData || {}\n }\n}"]}
1
+ {"version":3,"file":"meta-form-mixin.js","sourceRoot":"","sources":["../../client/mixin/meta-form-mixin.js"],"names":[],"mappings":"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","sourcesContent":["import { closePopup } from '@operato/popup'\n\nimport { MetaApi } from '../utils/meta-api'\nimport { MetaUiUtil } from '../utils/meta-ui-util'\nimport { ValueUtil } from '../utils/value-util'\nimport { UiUtil } from '../utils/ui-util'\nimport { TermsUtil } from '../utils/terms-util'\n\nimport { MetaButtonMixin } from './meta-button-mixin'\n\n/**\n * @license\n * Copyright © HatioLab Inc. All rights reserved.\n * @author Shortstop shortstop@hatiolab.com\n * @description 메뉴 메타 정보를 이용해 폼 화면 구성\n */\nexport const MetaFormMixin = baseElement =>\n class extends MetaButtonMixin(baseElement) {\n /**\n * @description 스타일 정의\n **************************\n * @returns {Array} 스타일\n */\n static get styles() {\n return MetaApi.getBasicFormStyles()\n }\n\n /**\n * @description 프로퍼티 정의\n ***************************\n * @returns {Object} 프로퍼티\n */\n static get properties() {\n return {\n /**\n * @description 폽 컬럼 구성 정보\n ******************************\n * @type {Array}\n */\n formColumnConfig: Array,\n /**\n * @description 메뉴 메타 정보로 부터 추출한 후 폼을 위해 설정 정보 구성\n ************************************************************\n * @type {Object}\n */\n formConfigSet: Object,\n /**\n * @description 폼 상세 렌터링 정보\n *******************************\n * @type {Object}\n */\n formRenderConfig: Array,\n /**\n * @description 데이터 레코드\n ***************************\n * @type {Object}\n */\n record: Object\n }\n }\n\n /**\n * @description 컨텍스트\n ***********************\n * @returns {HTMLElement}\n */\n get context() {\n return MetaUiUtil.getContextObject(this)\n }\n\n /******************************************************\n * LifeCycle\n ******************************************************/\n\n /**\n * @override connectedCallback\n *******************************\n */\n async connectedCallback() {\n // 메뉴 메타 정보 조회 및 기본 파싱\n await this.getAndParseMenuMeta()\n\n if (this.isElement) {\n await this.parseFormConfigs()\n }\n\n if (this.activityDataSet) {\n this.dataSet = this.activityDataSet\n }\n\n if (this.is_activity === true && !this.parent_id) {\n this.parent_id = 'activity'\n }\n\n if (super.connectedCallback) {\n await super.connectedCallback()\n }\n\n if (this.isElement) {\n await this.fetch()\n }\n\n // 인풋 키 이벤트 처리\n this.renderRoot.addEventListener('keydown', e => {\n switch (e.key) {\n case 'Esc':\n case 'Escape':\n // TODO 편집이 취소되어야 한다.\n case 'Enter':\n // 먼저 focus를 옮겨놓아야 focusout으로 인해서 popup이 닫히는 것을 방지할 수 있다.\n this.focus()\n\n if (this.currentTarget) {\n this.currentTarget.removeAttribute('editing')\n }\n\n this.currentTarget = null\n break\n default:\n }\n })\n\n // 인풋 클릭 처리 (readOnly <> editing)\n this.renderRoot.addEventListener('click', e => {\n e.stopPropagation()\n // target should be 'ox-grid-field'\n let target = e.target\n\n if (this.currentTarget) {\n this.focus()\n this.currentTarget.removeAttribute('editing')\n }\n\n if (target.tagName !== 'OX-GRID-FIELD' || !target.column.record.editable) {\n this.focus()\n this.currentTarget = null\n return\n }\n\n this.currentTarget = target\n target.setAttribute('editing', 'true')\n })\n\n // 폼 뷰의 인풋에서 발생되는 변경 이벤트 처리\n this.addEventListener('field-change', e => {\n let { after, before, column, record, row } = e.detail\n\n // before, after 값으로 달라진 값이 없으면 스킵\n if (ValueUtil.isEquals(after, before)) {\n return\n }\n\n // 유효성 체크 함수가 있는 경우 해당 함수 호출\n let validation = column.validation\n if (validation && typeof validation == 'function') {\n if (!validation.call(this, after, before, record, column)) {\n return\n }\n }\n\n // 변경 값 셋팅\n let colName = column.name\n record[colName] = after\n\n // 변경 필드 정보\n record.__dirtyfields__ = record.__dirtyfields__ || {}\n record.__origin__ = record.__origin__ || {}\n record.__dirtyfields__[colName] = {\n before: record.__origin__[colName],\n after: record[colName]\n }\n\n // 같은 값으로 변경 되었다면\n if (ValueUtil.isEquals(record.__dirtyfields__[colName].before, record.__dirtyfields__[colName].after)) {\n delete record.__dirtyfields__[colName]\n }\n\n // dirty flag 설정\n record.__dirty__ = ValueUtil.isNotEmpty(record.__dirtyfields__) ? 'M' : ''\n\n this.record = { ...record }\n\n // form-field-change 변경 이벤트 전파\n this.dispatchEvent(\n new CustomEvent('form-field-change', {\n bubbles: true,\n composed: true,\n detail: e.detail\n })\n )\n })\n }\n\n /**\n * @override firstUpdated\n ***************************\n */\n async firstUpdated() {\n if (super.firstUpdated) {\n await super.firstUpdated()\n }\n }\n\n /**\n * @override pageInitialized\n *****************************\n */\n async pageInitialized() {\n if (this.isPage) {\n await this.parseFormConfigs()\n }\n\n if (super.pageInitialized) {\n await super.pageInitialized()\n }\n\n if (this.isPage) {\n await this.fetch()\n }\n }\n\n /**\n * @description 화면 그리기\n *************************\n * @returns {HTMLElement}\n */\n render() {\n return MetaApi.getBasicFormHtml(this)\n }\n\n /**\n * @descrtiption 메뉴 메타 정보로 부터 기본 폼 정보 구성을 위한 Configuration\n *******************************************************************\n * @param {Object} menuMeta 메뉴 메타 정보\n */\n parseBasicFormConfigs(menuMeta) {\n this.formColumnConfig = menuMeta.grid_column\n this.formRenderConfig = menuMeta.form\n }\n\n /**\n * @descrtiption 폼 구성 정보 Configuration\n *****************************************\n */\n async parseFormConfigs() {\n this.formConfigSet = await MetaApi.parseFormConfigSet(this)\n }\n\n /********************************************************************\n * Data Filtering\n ********************************************************************/\n\n /**\n * @description 최초 조회된 원본 데이터\n ***********************************\n * @returns {Object} 원본 데이터 (변경 값 무시)\n */\n get orgData() {\n return this.removeGarbageData(this.record.__origin__)\n }\n\n /**\n * @description 변경된 데이터\n **************************\n * @returns {Object} 변경된 데이터만\n */\n get dirtyData() {\n if (ValueUtil.isEmpty((this.record || {}).__dirtyfields__)) {\n return {}\n }\n\n let retData = {}\n\n Object.entries(this.record.__dirtyfields__).map(([key, value]) => {\n if (key.startsWith('__') == false) {\n retData[key] = value.after\n }\n })\n\n return retData\n }\n\n /**\n * @description 현재 데이터\n *************************\n * @returns {Object} 화면에 표현되어 있는 현재 데이터 (수정된 값 반영)\n */\n get currentData() {\n return this.removeGarbageData(this.record)\n }\n\n /**\n * @description 레코드 데이터에서 쓰레기 데이터 정리\n ********************************************\n * @returns {Object} __dirty__,__dirtyfields__,__origin__ 등 (__ 로 시작되는 데이터 삭제)\n */\n removeGarbageData(data) {\n if (!data) return undefined\n\n let retData = {}\n\n Object.entries(data).map(([key, value]) => {\n if (key.startsWith('__') == false) {\n retData[key] = value\n }\n })\n\n return retData\n }\n\n /**\n * @description 트랜잭션을 위한 변경 데이터 + cuFlag 가져오기\n *****************************************************\n * @returns {Object}\n */\n get patchData() {\n let dirtyData = this.dirtyData\n let recordData = this.record\n // 코드 인풋 타입\n let codeInputColumns = (this.formColumnConfig || []).filter(x => x.type === 'code-input').map(x => x.name)\n\n if (ValueUtil.isEmpty(dirtyData)) {\n return undefined\n }\n\n // 기존 데이터 존재 여부 - 변경 플래그 판단\n if (ValueUtil.isNotEmpty(recordData.id)) {\n dirtyData.id = recordData.id\n dirtyData.cuFlag = 'M'\n } else {\n dirtyData.cuFlag = '+'\n }\n\n // object 타입은 id만 전송되도록 변경\n Object.keys(dirtyData).forEach(key => {\n if (typeof dirtyData[key] === 'object' && codeInputColumns.includes(key) == false) {\n dirtyData[key] = { id: dirtyData[key].id }\n }\n })\n\n return [dirtyData]\n }\n\n /********************************************************************\n * C R U D Functions\n ********************************************************************/\n /**\n * @description 폼 데이터 조회\n ***************************\n */\n async fetch() {\n // 부모 ID가 없다면 리턴\n if (ValueUtil.isEmpty(this.parent_id)) return\n\n // 단건 조회 함수\n let findOneFunc = ValueUtil.getParams(this.gqlInfo, 'query', 'find_one_func')\n if (!findOneFunc) return\n\n // 부모 ID로 조회\n let data = await this.findOne(this.parent_id)\n\n // 데이터 형식 맞추기\n data['__seq__'] = 1\n let orgData = {}\n Object.assign(orgData, data)\n data['__origin__'] = orgData\n this.record = { ...data }\n }\n\n /**\n * @description 폼 데이터 저장\n *****************************\n * @returns {Boolean} 저장 여부\n */\n async save() {\n let patches = this.patchData\n\n // 변경 여부 메시지 처리\n if (ValueUtil.isEmpty(patches)) {\n MetaApi.showAlertPopup('title.info', 'text.NOTHING_CHANGED', 'warning', 'confirm')\n return\n }\n\n // 필수 입력 컬럼\n let mandatoryColumns = {}\n ;(this.formColumnConfig || [])\n .filter(x => x.mandatory === true)\n .forEach(x => {\n mandatoryColumns[x.name] = x.header\n })\n\n // 필수 입력 값 체크\n let allFields = this.currentData\n for (let key in mandatoryColumns) {\n if (allFields[key] === undefined || allFields[key] == '') {\n UiUtil.showAlertPopup('text.check-mandatory', TermsUtil.tText('check-mandatory-field', { x: TermsUtil.tLabel(mandatoryColumns[key]) }), 'info', 'confirm')\n return\n }\n }\n\n // 저장 서비스 호출\n let isRes = await this.updateMultiple(patches)\n if (isRes) {\n // 폼 데이터 조회\n await this.fetch()\n\n // 저장이 잘 되었고 팝업이라면 팝업 닫기\n if (this.isPopup) {\n closePopup(this)\n }\n }\n\n // 저장 결과 리턴\n return isRes\n }\n\n /**\n * @description 데이터 클리어\n ***************************\n */\n async clear() {\n if (this.record) {\n this.record = {}\n }\n }\n\n /**\n * @description 데이터 리턴\n *************************\n * @returns {Object}\n */\n getData() {\n return this.currentData || {}\n }\n }\n"]}