@things-factory/meta-ui 8.0.0-beta.9 → 8.0.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 (115) hide show
  1. package/client/bootstrap.ts +170 -0
  2. package/client/component/filter/filter-form-meta-code-select.ts +102 -0
  3. package/client/component/filter/filter-form-meta-object-select.ts +107 -0
  4. package/client/component/filter/filter-grist-meta-code-select.ts +97 -0
  5. package/client/component/filter/filter-grist-meta-object-select.ts +102 -0
  6. package/client/component/grist/editor/grist-editor-code-input.js +96 -0
  7. package/client/component/grist/editor/grist-editor-meta-code-selector.js +157 -0
  8. package/client/component/grist/editor/grist-editor-meta-object-selector.js +122 -0
  9. package/client/component/grist/renderer/grist-renderer-code-input.js +20 -0
  10. package/client/component/grist/renderer/grist-renderer-meta-code-selector.js +28 -0
  11. package/client/component/grist/renderer/grist-renderer-meta-object-selector.js +25 -0
  12. package/client/component/popup/code-input-editor-popup.js +111 -0
  13. package/client/component/popup/file-upload-popup.js +129 -0
  14. package/client/component/popup/meta-object-selector-popup.ts +356 -0
  15. package/client/component/popup/record-based-code-editor-popup.ts +141 -0
  16. package/client/dynamic-menus.ts +38 -0
  17. package/client/index.ts +18 -0
  18. package/client/load-components.ts +17 -0
  19. package/client/mixin/meta-base-mixin.js +323 -0
  20. package/client/mixin/meta-basic-grist-mixin.js +283 -0
  21. package/client/mixin/meta-button-mixin.js +116 -0
  22. package/client/mixin/meta-form-mixin.js +435 -0
  23. package/client/mixin/meta-grist-tab-mixin.js +335 -0
  24. package/client/mixin/meta-main-tab-mixin.js +267 -0
  25. package/client/mixin/meta-master-detail-mixin.js +395 -0
  26. package/client/mixin/meta-service-mixin.js +306 -0
  27. package/client/mixin/meta-tab-detail-mixin.js +283 -0
  28. package/client/mixin/meta-tab-mixin.js +190 -0
  29. package/client/pages/activity/meta-activity-define-page.js +422 -0
  30. package/client/pages/activity/meta-activity-list-page.js +262 -0
  31. package/client/pages/activity/meta-activity-viewer-element.js +35 -0
  32. package/client/pages/activity/meta-activity-writer-element.js +48 -0
  33. package/client/pages/activity/meta-activiy-mixin.js +79 -0
  34. package/client/pages/button-role/button-role-detail.js +50 -0
  35. package/client/pages/button-role/button-role-page.js +25 -0
  36. package/client/pages/doc-number/doc-number-page.js +24 -0
  37. package/client/pages/doc-number/next-doc-number-popup.js +25 -0
  38. package/client/pages/entity/config-entity.js +955 -0
  39. package/client/pages/entity/main-menu-selector.js +245 -0
  40. package/client/pages/history/history-copy-list-popup.js +145 -0
  41. package/client/pages/history/history-json-list-popup.js +159 -0
  42. package/client/pages/menu/dynamic-menu-template.js +92 -0
  43. package/client/pages/menu/dynamic-menu.ts +744 -0
  44. package/client/pages/menu/export-menu-popup.js +468 -0
  45. package/client/pages/meta-form-element.js +9 -0
  46. package/client/pages/meta-grist-element.js +12 -0
  47. package/client/pages/meta-grist-page.js +16 -0
  48. package/client/pages/meta-grist-tab-element.js +16 -0
  49. package/client/pages/meta-grist-tab-page.js +16 -0
  50. package/client/pages/meta-main-tab-element.js +12 -0
  51. package/client/pages/meta-main-tab-page.js +16 -0
  52. package/client/pages/meta-master-detail-element.js +12 -0
  53. package/client/pages/meta-master-detail-page.js +16 -0
  54. package/client/pages/meta-tab-detail-element.js +12 -0
  55. package/client/pages/meta-tab-detail-page.js +16 -0
  56. package/client/pages/meta-tab-element.js +15 -0
  57. package/client/pages/printer-device/printer-device-page.js +24 -0
  58. package/client/pages/template/doc-template-page.js +24 -0
  59. package/client/pages/template/template-file-page.js +24 -0
  60. package/client/pages/terms/config-terminology.js +214 -0
  61. package/client/pages/work-code/work-code-detail-popup.js +16 -0
  62. package/client/pages/work-code/work-code-page.js +23 -0
  63. package/client/route.ts +36 -0
  64. package/client/tsconfig.json +13 -0
  65. package/client/utils/grist-default-value.js +36 -0
  66. package/client/utils/meta-api.js +811 -0
  67. package/client/utils/meta-crypto.js +52 -0
  68. package/client/utils/meta-ui-util.js +3304 -0
  69. package/client/utils/rest-service-util.js +328 -0
  70. package/client/utils/service-util.js +1327 -0
  71. package/client/utils/terms-util.ts +119 -0
  72. package/client/utils/ui-util.js +338 -0
  73. package/client/utils/value-util.js +234 -0
  74. package/dist-client/tsconfig.tsbuildinfo +1 -1
  75. package/dist-client/utils/service-util.d.ts +2 -2
  76. package/dist-client/utils/service-util.js +4 -4
  77. package/dist-client/utils/service-util.js.map +1 -1
  78. package/dist-server/tsconfig.tsbuildinfo +1 -1
  79. package/package.json +24 -24
  80. package/server/activity/CommonActivity.ts +68 -0
  81. package/server/index.ts +3 -0
  82. package/server/routes.ts +61 -0
  83. package/server/service/button-role/button-role-mutation.ts +105 -0
  84. package/server/service/button-role/button-role-query.ts +53 -0
  85. package/server/service/button-role/button-role-type.ts +39 -0
  86. package/server/service/button-role/button-role.ts +61 -0
  87. package/server/service/button-role/index.ts +7 -0
  88. package/server/service/dynamic-menu/dynamic-menu-query.ts +270 -0
  89. package/server/service/dynamic-menu/dynamic-menu-type.ts +74 -0
  90. package/server/service/dynamic-menu/index.ts +3 -0
  91. package/server/service/entity-event-subscriber/entity-event-subscriber.ts +80 -0
  92. package/server/service/entity-event-subscriber/index.ts +3 -0
  93. package/server/service/index.ts +41 -0
  94. package/server/service/menu-button-auth/index.ts +7 -0
  95. package/server/service/menu-button-auth/menu-button-auth-mutation.ts +133 -0
  96. package/server/service/menu-button-auth/menu-button-auth-query.ts +138 -0
  97. package/server/service/menu-button-auth/menu-button-auth-type.ts +63 -0
  98. package/server/service/menu-button-auth/menu-button-auth.ts +92 -0
  99. package/server/service/meta-activity/index.ts +5 -0
  100. package/server/service/meta-activity/meta-activity-mutation.ts +191 -0
  101. package/server/service/meta-activity/meta-activity-query.ts +43 -0
  102. package/server/service/meta-activity/meta-activity-type.ts +56 -0
  103. package/server/service/set-translations/index.ts +3 -0
  104. package/server/service/set-translations/set-translation-resolver.ts +63 -0
  105. package/server/service/work-code/index.ts +6 -0
  106. package/server/service/work-code/work-code-mutation.ts +147 -0
  107. package/server/service/work-code/work-code-query.ts +67 -0
  108. package/server/service/work-code/work-code-type.ts +60 -0
  109. package/server/service/work-code/work-code.ts +83 -0
  110. package/server/service/work-code-detail/index.ts +6 -0
  111. package/server/service/work-code-detail/work-code-detail-mutation.ts +149 -0
  112. package/server/service/work-code-detail/work-code-detail-query.ts +59 -0
  113. package/server/service/work-code-detail/work-code-detail-type.ts +50 -0
  114. package/server/service/work-code-detail/work-code-detail.ts +82 -0
  115. package/server/tsconfig.json +9 -0
@@ -0,0 +1,356 @@
1
+ import '@material/web/icon/icon.js'
2
+
3
+ import { css, html, LitElement, PropertyValues } from 'lit'
4
+ import { customElement, property, query } from 'lit/decorators.js'
5
+ import { closePopup } from '@operato/popup'
6
+ import { isMobileDevice, adjustFilters } from '@operato/utils'
7
+ import { CommonGristStyles, CommonHeaderStyles } from '@operato/styles'
8
+ import { ColumnConfig, DataGrist, FetchOption, FetchResult, GristRecord, QueryFilter } from '@operato/data-grist'
9
+
10
+ import { TermsUtil } from '../../utils/terms-util'
11
+ import { ValueUtil } from '../../utils/value-util'
12
+ import { ServiceUtil } from '../../utils/service-util'
13
+ import { MetaApi } from '../../utils/meta-api'
14
+ import { MetaUiUtil } from '../../utils/meta-ui-util'
15
+
16
+ @customElement('meta-object-selector-popup')
17
+ export class MetaObjectSelectorPopup extends LitElement {
18
+ static styles = [
19
+ CommonGristStyles,
20
+ CommonHeaderStyles,
21
+ css`
22
+ :host {
23
+ display: flex;
24
+ flex-direction: column;
25
+
26
+ background-color: var(--md-sys-color-surface);
27
+
28
+ width: var(--overlay-center-normal-width, 50%);
29
+ height: var(--overlay-center-normal-height, 50%);
30
+ }
31
+
32
+ ox-grist {
33
+ flex: 1;
34
+ }
35
+
36
+ ox-filters-form {
37
+ flex: 1;
38
+ }
39
+ `
40
+ ]
41
+
42
+ @property({ type: String }) value?: string
43
+ @property({ type: Object }) gridConfig: any
44
+ @property({ type: Object }) basicArgs?: FetchOption
45
+ @property({ type: Object }) options!: FetchOption & {
46
+ menu_template?: any
47
+ filterFields?: any[]
48
+ codeField?: string
49
+ nameField?: string
50
+ dispField?: string
51
+ queryName: string
52
+ select?: (ColumnConfig & {
53
+ options: any
54
+ select_opt: any
55
+ object_opt: any
56
+ })[]
57
+ }
58
+ @property({ type: Object }) confirmCallback?: (record?: Partial<GristRecord>) => void
59
+ @property({ type: Array }) selectedRecords: GristRecord[] = []
60
+
61
+ @query('ox-grist') private grist!: DataGrist
62
+
63
+ private foundationFilters: QueryFilter[] = []
64
+ private record: any
65
+
66
+ async connectedCallback() {
67
+ const {
68
+ select,
69
+ sorters,
70
+ filters,
71
+ codeField,
72
+ nameField,
73
+ dispField,
74
+ filterFields: optionFilterFields,
75
+ menu_template
76
+ } = this.options || {}
77
+
78
+ // 숨김 검색 조건
79
+ this.foundationFilters = filters ? filters : this.basicArgs && this.basicArgs.filters ? this.basicArgs.filters : []
80
+
81
+ this.foundationFilters = this.foundationFilters.map(x => {
82
+ let { name, operator, value } = x
83
+
84
+ if (value.startsWith('::')) {
85
+ value = ValueUtil.getParams(this.record, ...value.substring(2).split('.'))
86
+ }
87
+
88
+ return {
89
+ name,
90
+ operator,
91
+ value
92
+ }
93
+ })
94
+
95
+ // 기본 정렬
96
+ let sortFields = sorters ? sorters : this.basicArgs && this.basicArgs.sorters ? this.basicArgs.sorters : []
97
+
98
+ // 기본 검색 조건
99
+ let filterFields = optionFilterFields
100
+ ? optionFilterFields
101
+ : menu_template?.search && menu_template?.search.length > 0
102
+ ? menu_template.search
103
+ : []
104
+
105
+ // 그리드 컬럼
106
+ let gridColumns = select
107
+
108
+ // 기본 검색 조건이 없으면 코드 (code-selector), 또는 이름 (object-selector)
109
+ if (!filterFields || filterFields.length == 0) {
110
+ let defaultFilter
111
+
112
+ if (codeField) defaultFilter = codeField
113
+ if (nameField) defaultFilter = nameField
114
+
115
+ if (defaultFilter) {
116
+ filterFields.push({
117
+ name: defaultFilter,
118
+ operator: 'eq'
119
+ })
120
+ }
121
+ }
122
+
123
+ let selectFields = [...MetaApi.getGristGuttersConfig(true, false)]
124
+
125
+ if (gridColumns && gridColumns.length > 0) {
126
+ for (let idx = 0; idx < gridColumns.length; idx++) {
127
+ let {
128
+ type = 'string',
129
+ name,
130
+ hidden = false,
131
+ record = { align: 'left' },
132
+ header = undefined,
133
+ sortable = false,
134
+ width = 135,
135
+ options = undefined,
136
+ select_opt = undefined,
137
+ object_opt = undefined
138
+ } = gridColumns[idx]
139
+
140
+ if (select_opt) options = select_opt
141
+ if (object_opt) options = object_opt
142
+
143
+ if (['resource-object', 'object'].includes(type)) {
144
+ type = 'meta-object-selector'
145
+ } else if (['resource-code-selector'].includes(type)) {
146
+ type = 'meta-code-selector'
147
+ }
148
+
149
+ if (name == 'id') {
150
+ selectFields.push({
151
+ type: 'string',
152
+ name: name,
153
+ hidden: true
154
+ })
155
+ } else {
156
+ if (type == 'boolean-all') {
157
+ type = 'boolean'
158
+ }
159
+
160
+ let columnConfig = MetaApi.getGristColumnConfig2(
161
+ type,
162
+ name,
163
+ header ? (header as unknown as string) : name,
164
+ record.align ? record.align : 'left',
165
+ false,
166
+ sortable,
167
+ Number(width)
168
+ )
169
+
170
+ if (type.startsWith('meta-') && object_opt && object_opt.menu) {
171
+ options = await MetaUiUtil.getGristMetaObjectOptions(type, options)
172
+ }
173
+
174
+ if (type === 'select') {
175
+ if (Array.isArray(options)) {
176
+ columnConfig.record.options = options
177
+ } else {
178
+ if (options.type === 'code') {
179
+ // 공통 코드
180
+ columnConfig.record.options = await ServiceUtil.getCodeSelectorData(
181
+ options.values ? options.values : options.name
182
+ )
183
+ } else if (options.type === 'scenario') {
184
+ // 시나리오
185
+ columnConfig.record.options = await ServiceUtil.getCodeByScenario(options.name, options.args)
186
+ } else if (options.type === 'entity') {
187
+ // 엔티티
188
+ columnConfig.record.options = await ServiceUtil.getCodeByEntity(options.args)
189
+ }
190
+ }
191
+ } else if (type === 'meta-object-selector') {
192
+ // object-option
193
+ columnConfig.record.options = { ...options }
194
+ } else if (type == 'meta-code-selector') {
195
+ if (options.dispField) {
196
+ options.codes = await ServiceUtil.getCodeByEntity(options)
197
+ }
198
+
199
+ columnConfig.record.options = { ...options }
200
+ }
201
+
202
+ columnConfig.hidden = hidden
203
+
204
+ selectFields.push(columnConfig)
205
+ }
206
+ }
207
+ } else {
208
+ selectFields.push(MetaApi.getGristColumnConfig2('string', codeField!, codeField!, 'left', false, true, 180))
209
+
210
+ if (dispField) {
211
+ selectFields.push(MetaApi.getGristColumnConfig2('string', dispField, dispField, 'left', false, true, 300))
212
+ }
213
+ }
214
+
215
+ selectFields.forEach(x => {
216
+ let filters = filterFields.filter(y => (typeof y === 'string' ? x.name == y : x.name == y.name))
217
+
218
+ if (filters && filters.length > 0) {
219
+ x.filter = typeof filters[0] === 'string' ? 'search' : filters[0]
220
+ }
221
+ })
222
+
223
+ let gridConfig = {
224
+ rows: MetaApi.getGristSelectableConfig(false),
225
+ pagination: MetaApi.getGristPagination100Config(),
226
+ columns: selectFields,
227
+ sorters: [...sortFields]
228
+ }
229
+
230
+ gridConfig.rows.handlers = {
231
+ click: 'select-row-toggle',
232
+ dblclick: (columns, data, column, record, rowIndex, field) => {
233
+ this.selectRecord(record)
234
+ }
235
+ }
236
+
237
+ gridConfig.rows.appendable = false
238
+
239
+ this.gridConfig = gridConfig
240
+
241
+ await super.connectedCallback()
242
+ }
243
+
244
+ async firstUpdated(changes: PropertyValues<this>) {
245
+ await super.firstUpdated(changes)
246
+ }
247
+
248
+ render() {
249
+ return html`
250
+ <ox-grist
251
+ id="ox-grist"
252
+ .config=${this.gridConfig}
253
+ .mode=${isMobileDevice() ? 'LIST' : 'GRID'}
254
+ auto-fetch
255
+ .fetchHandler=${this.fetchHandler.bind(this)}
256
+ >
257
+ <div slot="headroom" class="header">
258
+ <div class="filters">
259
+ <ox-filters-form></ox-filters-form>
260
+ </div>
261
+ </div>
262
+ </ox-grist>
263
+
264
+ <div class="footer">
265
+ <button @click=${this.clickEmpty.bind(this)}>
266
+ <md-icon>check_box_outline_blank</md-icon>${TermsUtil.tButton('empty')}
267
+ </button>
268
+ <div filler></div>
269
+ <button @click=${this.clickCancel.bind(this)}><md-icon>cancel</md-icon>${TermsUtil.tButton('cancel')}</button>
270
+ <button @click=${this.clickSelect.bind(this)} done>
271
+ <md-icon>done</md-icon>${TermsUtil.tButton('select')}
272
+ </button>
273
+ </div>
274
+ `
275
+ }
276
+
277
+ /**
278
+ * @description 컬럼 조회
279
+ ***************************
280
+ * @returns
281
+ */
282
+ async fetchHandler({ page = 0, limit = 0, sorters = [], filters = [] }: FetchOption): Promise<FetchResult> {
283
+ const { menu_template, queryName } = this.options || {}
284
+
285
+ // let resFilter = [...this.foundationFilters]
286
+
287
+ // filters.forEach((x: any) => {
288
+ // let dupFilter = resFilter.filter(y => x.name == y.name)
289
+ // if (dupFilter && dupFilter.length > 0) {
290
+ // delete resFilter[x.name]
291
+ // }
292
+
293
+ // resFilter.push(x)
294
+ // })
295
+
296
+ let resFilter = adjustFilters([...this.foundationFilters], filters)
297
+
298
+ let queryAfterSetFields = ValueUtil.getParams(
299
+ menu_template ? menu_template.gql || {} : {},
300
+ 'query',
301
+ 'after_set_fields'
302
+ )
303
+ let selectSkipFields = Object.keys(queryAfterSetFields || {})
304
+
305
+ // 조회 컬럼 추출 후 조회
306
+ let selectFields = MetaApi.getSelectColumns(this.gridConfig.columns.filter(x => !selectSkipFields.includes(x.name)))
307
+
308
+ // 조회 실행
309
+ let result = await MetaApi.searchByPagination(queryName, resFilter, sorters, page, limit, selectFields)
310
+
311
+ return result
312
+ }
313
+
314
+ /**
315
+ * @description 비우기
316
+ ***************************
317
+ * @returns
318
+ */
319
+ async clickEmpty(e) {
320
+ this.confirmCallback && this.confirmCallback()
321
+ closePopup(this)
322
+ }
323
+ /**
324
+ * @description 취소
325
+ ***************************
326
+ * @returns
327
+ */
328
+ async clickCancel(e) {
329
+ closePopup(this)
330
+ }
331
+ /**
332
+ * @description 선택
333
+ ***************************
334
+ * @returns
335
+ */
336
+ async clickSelect(e) {
337
+ let selected = this.grist.selected
338
+
339
+ if (!selected || selected.length == 0) {
340
+ MetaApi.showToast('info', TermsUtil.tText('NOTHING_SELECTED'))
341
+ return
342
+ }
343
+
344
+ this.selectRecord(selected[0])
345
+ }
346
+
347
+ /**
348
+ * @description 확정
349
+ ***************************
350
+ * @param {*} record
351
+ */
352
+ async selectRecord(record) {
353
+ this.confirmCallback && this.confirmCallback(record)
354
+ closePopup(this)
355
+ }
356
+ }
@@ -0,0 +1,141 @@
1
+ import '@material/web/icon/icon.js'
2
+ import '@operato/input/ox-input-code.js'
3
+
4
+ import { css, html, LitElement, PropertyValues } from 'lit'
5
+ import { customElement, query, state } from 'lit/decorators.js'
6
+ import { OxInputCode } from '@operato/input'
7
+ import { closePopup } from '@operato/popup'
8
+ import { CommonHeaderStyles } from '@operato/styles'
9
+
10
+ import { TermsUtil } from '../../utils/terms-util'
11
+ import { MetaApi } from '../../utils/meta-api'
12
+ import { ServiceUtil } from '../../utils/service-util'
13
+
14
+ /**
15
+ * 레코드 기반 코드 편집기 팝업
16
+ */
17
+
18
+ @customElement('record-based-code-editor-popup')
19
+ export class RecordBasedCodeEditorPopup extends LitElement {
20
+ static styles = [
21
+ CommonHeaderStyles,
22
+ css`
23
+ :host {
24
+ display: flex;
25
+ flex-direction: column;
26
+
27
+ background-color: var(--md-sys-color-surface);
28
+
29
+ width: var(--overlay-center-normal-width, 50%);
30
+ height: var(--overlay-center-normal-height, 50%);
31
+ }
32
+
33
+ ox-input-code {
34
+ margin: 10px;
35
+ overflow-y: auto;
36
+ flex: 1;
37
+ }
38
+ `
39
+ ]
40
+
41
+ @state() private config?: any
42
+ @state() private record?: any
43
+ @state() private value?: any
44
+ @state() private codeValue?: any
45
+
46
+ @query('ox-input-code') private codeEditor!: OxInputCode
47
+
48
+ /**
49
+ * 그리드 버튼 (grid-custom) 선택시 코드 편집기 팝업을 띄우는 버튼 로직
50
+ {
51
+ "type": "popup", -> 팝업 표시 (고정값)
52
+ "title": "template", -> 코드 에디터에서 팝업 타이틀에 표시할 타이틀 정보 (변수값)
53
+ "title_detail": "name", -> 코드 에디터에서 팝업 타이틀에 표시할 레코드의 필드 정보 (변수값)
54
+ "size": "large", -> 팝업 사이즈 (full, large, medium, small)
55
+ "popup_field": "record", -> 코드 에디터에서 레코드를 받을 필드명 (고정값)
56
+ "parent_field": "id", -> 부모 레코드 ID 필드 값 (고정값)
57
+ "value_field": "template", -> 코드 에디터에 표시할 레코드 필드 정보 (변수값)
58
+ "menu": "code-editor", -> 코드 에디터 이름 정보 (고정값)
59
+ "tagname": "record-code-editor-popup", -> 코드 에디터 태그 명 (고정값)
60
+ "location": "@things-factory/meta-ui/dist-client/component/popup/record-code-editor-popup", -> 코드 에디터 파일 위치 (고정값)
61
+ "save_action": {
62
+ "func_name": "updateDocTemplate", -> 업데이트 함수 명
63
+ "func_type": "DocTemplatePatch"
64
+ },
65
+ "param": [
66
+ "grist_one" -> 파라미터 전달 모드 - 그리드 선택 값 전달 (고정값)
67
+ ],
68
+ "after": "fetch" -> 팝업 닫기 후 액션 (Optional)
69
+ }
70
+ */
71
+ async connectedCallback() {
72
+ this.value = this.record[this.config.value_field] ? this.record[this.config.value_field] : ''
73
+
74
+ if (typeof this.value === 'object') {
75
+ this.codeValue = JSON.stringify(this.value, null, 2)
76
+ } else {
77
+ this.codeValue = this.value
78
+ }
79
+
80
+ await super.connectedCallback()
81
+ }
82
+
83
+ async firstUpdated(changes: PropertyValues<this>) {
84
+ await super.firstUpdated(changes)
85
+ }
86
+
87
+ render() {
88
+ let addSaveBtn = this.config.save_action ? true : false
89
+
90
+ if (addSaveBtn) {
91
+ return html`
92
+ <ox-input-code mode="javascript" value=${this.codeValue} tab-size="2" tab-as-space="true"></ox-input-code>
93
+
94
+ <div class="footer">
95
+ <div filler></div>
96
+ <button @click=${this.clickCancel.bind(this)}><md-icon>cancel</md-icon>${TermsUtil.tButton('cancel')}</button>
97
+ <button @click=${this.clickSave.bind(this)} done><md-icon>save</md-icon>${TermsUtil.tButton('save')}</button>
98
+ </div>
99
+ `
100
+ } else {
101
+ return html`
102
+ <ox-input-code mode="javascript" value=${this.codeValue} tab-size="2" tab-as-space="true"></ox-input-code>
103
+ <div class="footer">
104
+ <div filler></div>
105
+ <button @click=${this.clickCancel.bind(this)} done>
106
+ <md-icon>cancel</md-icon>${TermsUtil.tButton('cancel')}
107
+ </button>
108
+ </div>
109
+ `
110
+ }
111
+ }
112
+
113
+ /**
114
+ * @description 저장
115
+ ***************************
116
+ * @returns
117
+ */
118
+ async clickSave(e) {
119
+ if (this.codeValue === this.codeEditor.value) {
120
+ MetaApi.showToast('info', TermsUtil.tText('NOTHING_CHANGED'))
121
+ } else {
122
+ let saveAction = this.config.save_action
123
+ let saveFuncName = saveAction.func_name
124
+ let patch = { id: this.record.id, cuFlag: 'M' }
125
+ patch[this.config.value_field] = this.codeEditor.value
126
+ let response = await ServiceUtil.updateOne(saveFuncName, this.record.id, patch)
127
+ if (response) {
128
+ closePopup(this)
129
+ }
130
+ }
131
+ }
132
+
133
+ /**
134
+ * @description 취소
135
+ ***************************
136
+ * @returns
137
+ */
138
+ async clickCancel(e) {
139
+ closePopup(this)
140
+ }
141
+ }
@@ -0,0 +1,38 @@
1
+ import { auth } from '@things-factory/auth-base/dist-client/auth.js'
2
+
3
+ import { MetaApi } from './utils/meta-api'
4
+
5
+ type Route = {
6
+ id?: string
7
+ parent?: boolean
8
+ parent_id?: string | null
9
+ title?: string
10
+ tagname?: string
11
+ page?: string
12
+ template?: string
13
+ routing_type?: string
14
+ }
15
+
16
+ var MENUS = getDynamicMenus()
17
+
18
+ export function getDynamicMenus(update: boolean = false) {
19
+ if (!update && MENUS) {
20
+ return MENUS
21
+ }
22
+
23
+ MENUS = new Promise<{
24
+ menus: any
25
+ routes: Route[]
26
+ }>(resolve => {
27
+ auth.on('profile', async () => {
28
+ const menuRoutes: {
29
+ menus: any
30
+ routes: Route[]
31
+ } = await MetaApi.myDynamicMenus()
32
+
33
+ resolve(menuRoutes)
34
+ })
35
+ })
36
+
37
+ return MENUS
38
+ }
@@ -0,0 +1,18 @@
1
+ /** Utilities **/
2
+ export * from './utils/terms-util'
3
+ export * from './utils/value-util'
4
+ export * from './utils/ui-util'
5
+ export * from './utils/meta-ui-util'
6
+ export * from './utils/rest-service-util'
7
+ export * from './utils/meta-api'
8
+
9
+ /** Mix In **/
10
+ export * from './mixin/meta-base-mixin'
11
+ export * from './mixin/meta-service-mixin'
12
+ export * from './mixin/meta-button-mixin'
13
+ export * from './mixin/meta-basic-grist-mixin'
14
+ export * from './mixin/meta-form-mixin'
15
+ export * from './mixin/meta-tab-mixin'
16
+ export * from './mixin/meta-grist-tab-mixin'
17
+ export * from './mixin/meta-tab-detail-mixin'
18
+ export * from './mixin/meta-main-tab-mixin'
@@ -0,0 +1,17 @@
1
+ /** Page **/
2
+ import './pages/meta-form-element'
3
+ import './pages/meta-grist-element'
4
+ import './pages/meta-grist-page'
5
+ import './pages/meta-grist-tab-element'
6
+ import './pages/meta-grist-tab-page'
7
+ import './pages/meta-master-detail-element'
8
+ import './pages/meta-master-detail-page'
9
+ import './pages/meta-tab-element'
10
+ import './pages/meta-tab-detail-element'
11
+ import './pages/meta-tab-detail-page'
12
+ import './pages/meta-main-tab-page'
13
+ import './pages/meta-main-tab-element'
14
+
15
+ /* Component */
16
+ import './component/popup/file-upload-popup'
17
+ import './component/popup/record-based-code-editor-popup'