@idooel/components 0.0.1-beta.39 → 0.0.1-beta.40

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 (95) hide show
  1. package/dist/@idooel/components.esm.js +4667 -4273
  2. package/dist/@idooel/components.umd.js +4609 -4191
  3. package/jsconfig.json +8 -0
  4. package/package.json +3 -3
  5. package/packages/alert/index.js +4 -4
  6. package/packages/alert/src/index.vue +45 -45
  7. package/packages/batch-export/index.js +4 -4
  8. package/packages/batch-export/src/index.vue +104 -108
  9. package/packages/business-components/modal-fsm/index.js +5 -0
  10. package/packages/business-components/modal-fsm/src/index.vue +164 -0
  11. package/packages/{composite-components → business-components}/modal-import/index.js +4 -4
  12. package/packages/{composite-components → business-components}/modal-import/src/index.vue +139 -145
  13. package/packages/{composite-components → business-components}/modal-timeline/index.js +4 -4
  14. package/packages/{composite-components → business-components}/modal-timeline/src/index.vue +77 -76
  15. package/packages/button/index.js +4 -4
  16. package/packages/button/src/index.vue +54 -54
  17. package/packages/checkbox/index.js +4 -4
  18. package/packages/checkbox/src/index.vue +52 -52
  19. package/packages/composite-components/button-group/index.js +4 -4
  20. package/packages/composite-components/button-group/src/index.vue +88 -53
  21. package/packages/composite-components/{attachment → form-attachment}/src/index.vue +14 -14
  22. package/packages/composite-components/modal-confirm/index.js +5 -0
  23. package/packages/composite-components/modal-confirm/src/index.vue +69 -0
  24. package/packages/composite-components/modal-form/index.js +4 -4
  25. package/packages/composite-components/modal-form/src/index.vue +202 -202
  26. package/packages/{img-crop → composite-components/modal-img-crop}/index.js +4 -4
  27. package/packages/{img-crop → composite-components/modal-img-crop}/src/index.vue +284 -290
  28. package/packages/composite-components/modal-table/index.js +0 -0
  29. package/packages/composite-components/modal-tree/index.js +4 -4
  30. package/packages/composite-components/modal-tree/src/index.vue +75 -75
  31. package/packages/composite-components/search-area/index.js +4 -4
  32. package/packages/composite-components/search-area/src/index.vue +218 -229
  33. package/packages/composite-components/search-area/src/label.vue +35 -35
  34. package/packages/composite-components/table-transfer/index.js +0 -0
  35. package/packages/date/index.js +4 -4
  36. package/packages/date/src/index.vue +95 -39
  37. package/packages/date-range/index.js +4 -4
  38. package/packages/date-range/src/index.vue +47 -47
  39. package/packages/form/index.js +4 -4
  40. package/packages/form/src/index.vue +236 -240
  41. package/packages/icon/index.js +4 -4
  42. package/packages/icon/src/index.vue +31 -31
  43. package/packages/index.js +132 -99
  44. package/packages/input/index.js +4 -4
  45. package/packages/input/src/index.vue +35 -35
  46. package/packages/input-number/index.js +4 -4
  47. package/packages/input-number/src/index.vue +23 -23
  48. package/packages/modal/index.js +4 -4
  49. package/packages/modal/src/index.vue +184 -162
  50. package/packages/{form-group-model → models/form-group-model}/index.js +4 -4
  51. package/packages/{form-group-model → models/form-group-model}/src/index.vue +273 -279
  52. package/packages/{form-model → models/form-model}/index.js +4 -4
  53. package/packages/{form-model → models/form-model}/src/index.vue +201 -189
  54. package/packages/{step-model → models/step-model}/index.js +4 -4
  55. package/packages/{step-model → models/step-model}/src/index.vue +215 -219
  56. package/packages/models/tree-table-model/README.md +0 -0
  57. package/packages/{tree-table-model → models/tree-table-model}/index.js +4 -4
  58. package/packages/{tree-table-model → models/tree-table-model}/src/index.vue +494 -493
  59. package/packages/radio/index.js +4 -4
  60. package/packages/radio/src/index.vue +56 -56
  61. package/packages/select/index.js +4 -4
  62. package/packages/select/src/index.vue +92 -92
  63. package/packages/select-entity/index.js +4 -4
  64. package/packages/select-entity/src/index.vue +113 -113
  65. package/packages/table/index.js +4 -4
  66. package/packages/table/src/action.vue +164 -134
  67. package/packages/table/src/index.vue +257 -257
  68. package/packages/tabs/index.js +4 -4
  69. package/packages/tabs/src/index.vue +55 -55
  70. package/packages/text/index.js +4 -4
  71. package/packages/text/src/index.vue +47 -47
  72. package/packages/text-editor/index.js +4 -4
  73. package/packages/text-editor/src/index.vue +72 -72
  74. package/packages/textarea/index.js +4 -4
  75. package/packages/textarea/src/index.vue +57 -57
  76. package/packages/theme/form.scss +21 -21
  77. package/packages/theme/index.scss +42 -42
  78. package/packages/theme/overrid.scss +7 -7
  79. package/packages/theme/styleClass.scss +2 -2
  80. package/packages/theme/variables.scss +55 -55
  81. package/packages/timeline/index.js +4 -4
  82. package/packages/timeline/src/index.vue +253 -234
  83. package/packages/tpl/index.js +4 -4
  84. package/packages/tpl/src/index.vue +55 -55
  85. package/packages/tree/index.js +4 -4
  86. package/packages/tree/src/TreeNode.vue +29 -29
  87. package/packages/tree/src/index.vue +101 -101
  88. package/packages/upload/index.js +4 -4
  89. package/packages/upload/src/index.vue +440 -442
  90. package/packages/utils/index.js +48 -47
  91. package/scripts/rollup.config.js +42 -40
  92. package/scripts/rollup.esm.config.js +11 -11
  93. package/scripts/rollup.umd.config.js +14 -14
  94. /package/packages/composite-components/{attachment → form-attachment}/index.js +0 -0
  95. /package/packages/{tree-table-model/README.md → composite-components/modal-table-transfer/index.js} +0 -0
@@ -1,493 +1,494 @@
1
- <template>
2
- <section class="ele model__tree-table">
3
- <section class="model__tree-table--container" v-if="showTree">
4
- <div class="model__tree--title"></div>
5
- <section :ref="modelTreeWrapper" class="model__tree--wrapper" :style="{height: `${treeWrapperHeight}px`}">
6
- <ele-tree
7
- :tree-data="treeData"
8
- :defaultExpandedKeys="defaultExpandedKeys"
9
- :defaultSelectedKeys="defaultSelectedKeys"
10
- @select="selectTreeNode"
11
- :replace-fields="treeMeta.replaceFields || replaceFields">
12
- </ele-tree>
13
- </section>
14
- </section>
15
- <section class="model__table--container" :ref="modelTableContainerRef">
16
- <div class="model__table--title" v-if="title">
17
- <template v-if="titleMode">
18
- <div :class="[`model__table-title--${titleMode}`]"></div>
19
- </template>
20
- <template v-else>
21
- <div class="model__table-title--text">{{ title }}</div>
22
- </template>
23
- </div>
24
- <section :ref="modelTableWrapper" class="model__table--wrapper">
25
- <ele-search-area :ref="searchArea" @search="onSearch" :data-source="searchMeta.elements"></ele-search-area>
26
- <div class="button-row__area">
27
- <ele-button-group class="model-table__button-group" v-on="overrideButtonGroupEvent" :ref="buttonGroup" @click="handleClickButtonGroup" :data-source="getButtonGroupElements"></ele-button-group>
28
- <slot name="tags"></slot>
29
- </div>
30
- <ele-table
31
- v-on="overrideTableEvent"
32
- :ref="tableRef"
33
- :row-selection="rowSelection"
34
- :loading="loading"
35
- :columns="columns"
36
- :total="total"
37
- :height="tableHeight"
38
- :actions="actions"
39
- :pageSize="pageSize"
40
- :pageSizeOptions="pageSizeOptions"
41
- :data-source="tableData"
42
- @change-page="onChangePage"
43
- ></ele-table>
44
- </section>
45
- </section>
46
- <ele-modal-form v-model="modalFormValue" :meta="modalFormMeta"></ele-modal-form>
47
- <ele-modal-timeline v-model="showFsmModal" :contextProp="fsmContextProp" :meta="fsmMeta" @cancel="handleCloseFsmModal"></ele-modal-timeline>
48
- </section>
49
- </template>
50
-
51
- <script>
52
- import EleTree from '../../tree/src/index.vue'
53
- import EleTable from '../../table/src/index.vue'
54
- import EleSearchArea from '../../composite-components/search-area/src/index.vue'
55
- import EleButtonGroup from '../../composite-components/button-group/src/index.vue'
56
- import { type, net } from '@idooel/shared'
57
- import { v4 as uuidv4 } from 'uuid'
58
- import { BUILT_IN_EVENT_NAMES, RESERVE_EVENT_NAMES, parseFieldMap, BUILT_IN_TRIGGER } from '../../utils'
59
- export default {
60
- name: 'ele-tree-table-model',
61
- components: {
62
- EleTree,
63
- EleTable,
64
- EleSearchArea,
65
- EleButtonGroup
66
- },
67
- props: {
68
- title: {
69
- type: [Object, String]
70
- },
71
- treeMeta: {
72
- type: Object,
73
- default: () => ({})
74
- },
75
- searchMeta: {
76
- type: Object,
77
- default: () => ({})
78
- },
79
- buttonGroupMeta: {
80
- typeof: Object,
81
- default: () => ({})
82
- },
83
- tableMeta: {
84
- type: Object,
85
- default: () => ({})
86
- },
87
- createMeta: {
88
- type: Object
89
- },
90
- editMeta: {
91
- type: Object
92
- }
93
- },
94
- provide () {
95
- return {
96
- requestTreeData: this.requestTreeData,
97
- requestTableData: this.requestTableData
98
- }
99
- },
100
- data () {
101
- return {
102
- tableHeight: 0,
103
- modalFormMeta: {},
104
- modalFormValue: false,
105
- treeData: [],
106
- tableData: [],
107
- defaultExpandedKeys: [],
108
- defaultSelectedKeys: [],
109
- replaceFields: {
110
- title: 'title',
111
- children: 'children',
112
- key: 'id'
113
- },
114
- loading: false,
115
- total: 0,
116
- tableQuerys: {},
117
- resizeObserverModelTableWrapper: null,
118
- modelTableWrapperHeight: 0,
119
- currentTreeNodeData: {},
120
- treeWrapperHeight: 0,
121
- currentTableSelection: {},
122
- showFsmModal: false,
123
- fsmMeta: {},
124
- fsmContextProp: {}
125
- }
126
- },
127
- computed: {
128
- rowSelection () {
129
- if (!this.currentTableMode) return void 0
130
- return {
131
- columnTitle: this.currentSelectionColumn.columnTitle,
132
- fixed: true,
133
- type: this.currentTableMode,
134
- onChange: this.onChangeTableSelection
135
- }
136
- },
137
- currentSelectionColumn () {
138
- return this.columns.find(item => Object.keys(item).includes('multiple'))
139
- },
140
- currentTableMode () {
141
- if (!this.currentSelectionColumn) return void 0
142
- const { multiple } = this.currentSelectionColumn
143
- if (type.isBool(multiple)) {
144
- if (multiple) {
145
- return 'checkbox'
146
- } else {
147
- return 'radio'
148
- }
149
- } else {
150
- return void 0
151
- }
152
- },
153
- modelTableContainerRef () {
154
- return uuidv4()
155
- },
156
- titleMode () {
157
- if (type.isObject(this.title)) {
158
- const { mode = '' } = this.title
159
- return mode
160
- }
161
- return void 0
162
- },
163
- tableRef () {
164
- return uuidv4()
165
- },
166
- exposed () {
167
- return {
168
- currentTableSelection: this.currentTableSelection,
169
- currentTreeNode: this.currentTreeNodeData,
170
- requestTableData: this.requestTableData
171
- }
172
- },
173
- overrideTableEvent () {
174
- const events = this.actions.reduce((ret, action) => {
175
- ret[action.eventName] = (e) => {
176
- this.$emit(action.eventName || 'click', { ...e, currentTreeNode: this.currentTreeNodeData, exposed: this.exposed })
177
- }
178
- return ret
179
- }, {})
180
- return {
181
- ...this.$listeners,
182
- ...events,
183
- [BUILT_IN_EVENT_NAMES.EDIT]: this[BUILT_IN_EVENT_NAMES.EDIT]
184
- }
185
- },
186
- overrideButtonGroupEvent () {
187
- const events = this.getButtonGroupElements.reduce((ret, ele) => {
188
- ret[ele.eventName] = (e) => {
189
- this.$emit(ele.eventName || 'click', { ...e, currentTreeNode: this.currentTreeNodeData, exposed: this.exposed })
190
- }
191
- return ret
192
- }, {})
193
- return {
194
- ...this.$listeners,
195
- ...events,
196
- [BUILT_IN_EVENT_NAMES.CREATE]: this[BUILT_IN_EVENT_NAMES.CREATE]
197
- }
198
- },
199
- showTree () {
200
- return !!Object.keys(this.treeMeta).length
201
- },
202
- buttonGroup () {
203
- return uuidv4()
204
- },
205
- searchArea () {
206
- return uuidv4()
207
- },
208
- modelTreeWrapper () {
209
- return uuidv4()
210
- },
211
- modelTableWrapper () {
212
- return uuidv4()
213
- },
214
- actions () {
215
- const { operations } = this.tableMeta
216
- return operations.elements
217
- },
218
- pageSize () {
219
- const { page = {} } = this.tableMeta
220
- return page.pageSize || 10
221
- },
222
- pageSizeOptions () {
223
- const { page = {} } = this.tableMeta
224
- return page.pageSizeOptions || ['10', '20', '30', '40']
225
- },
226
- columns () {
227
- const { columns, operations } = this.tableMeta
228
- if (type.get(columns) === 'array') {
229
- const columnsOptions = columns.map(item => {
230
- const { mode = 'text' } = item
231
- if (item.render) {
232
- return {
233
- ...item,
234
- customRender: (text, record, index) => {
235
- const { $createElement } = this
236
- return item.render.call(this, { h: $createElement, ctx: this }, typeof text == 'string' ? text : text[item.dataIndex], record, index)
237
- }
238
- }
239
- } else if (mode !== BUILT_IN_TRIGGER.TEXT) {
240
- const { [`${mode}Meta`]: modeMeta } = item
241
- return {
242
- ...item,
243
- customRender: (text, record, index) => {
244
- return <span onClick={() => this.dispatchTrigger({ mode, record, modeMeta, index })} class={ mode }>{ text }</span>
245
- }
246
- }
247
- }
248
- return {
249
- ...item
250
- }
251
- })
252
- if (operations) {
253
- return [
254
- ...columnsOptions,
255
- {
256
- title: '操作',
257
- width: operations.width,
258
- key: 'action',
259
- fixed: 'right',
260
- scopedSlots: { customRender: 'action' }
261
- }
262
- ]
263
- }
264
- return columnsOptions
265
- } else {
266
- console.error('Error: columns is invalid, please check it')
267
- return []
268
- }
269
- },
270
- getButtonGroupElements () {
271
- const { elements } = this.buttonGroupMeta
272
- if (type.get(elements) === 'function') {
273
- return elements.call(this)
274
- } else if (type.get(elements) === 'array') {
275
- return elements
276
- } else {
277
- return []
278
- }
279
- }
280
- },
281
- async created () {
282
- if (this.showTree) {
283
- this.treeData = await this.requestTreeData()
284
- const [defaultTreeNode = {}] = this.treeData
285
- this.defaultExpandedKeys = [defaultTreeNode[this.replaceFields.key]]
286
- this.defaultSelectedKeys = [defaultTreeNode[this.replaceFields.key]]
287
- this.currentTreeNodeData = defaultTreeNode
288
- }
289
- const { params = {}, fieldMap = {}, overrideInit = false } = this.tableMeta
290
- const ctx = { ...this.currentTreeNodeData, _route: this.$route.query }
291
- const initQuerys = Object.assign({}, params, parseFieldMap(fieldMap, ctx))
292
- if (overrideInit) {
293
- this.$emit(RESERVE_EVENT_NAMES.INIT, { ...this.exposed })
294
- } else {
295
- this.tableData = await this.requestTableData(initQuerys)
296
- }
297
- },
298
- methods: {
299
- dispatchTrigger ({ mode, record = {}, modeMeta = {} }) {
300
- switch (mode) {
301
- case BUILT_IN_TRIGGER.FSM:
302
- this[`${BUILT_IN_TRIGGER.FSM}Trigger`](record, modeMeta)
303
- break
304
- default:
305
- break
306
- }
307
- },
308
- handleCloseFsmModal () {
309
- this.showFsmModal = false
310
- },
311
- [`${BUILT_IN_TRIGGER.FSM}Trigger`] (record, meta) {
312
- this.fsmMeta = meta
313
- this.fsmContextProp = record
314
- this.showFsmModal = true
315
- },
316
- onChangeTableSelection (_, selectedRows) {
317
- if (this.currentTableMode === 'radio') {
318
- this.currentTableSelection = selectedRows[0]
319
- } else {
320
- this.currentTableSelection = selectedRows
321
- }
322
- },
323
- [BUILT_IN_EVENT_NAMES.EDIT] () {
324
- this.modalFormMeta = this.editMeta
325
- this.modalFormValue = true
326
- },
327
- [BUILT_IN_EVENT_NAMES.CREATE] () {
328
- this.modalFormMeta = this.createMeta
329
- this.modalFormValue = true
330
- },
331
- handleClickButtonGroup (props) {
332
- const { eventName } = props
333
- this.$emit(eventName, { currentTreeNode: this.currentTreeNodeData })
334
- },
335
- watchViewPort () {
336
- const modelTableWrapper = this.$refs[this.modelTableWrapper]
337
- console.log(modelTableWrapper.getBoundingClientRect())
338
- const { top } = modelTableWrapper.getBoundingClientRect()
339
- this.$refs[this.modelTreeWrapper].style.height = `calc(100vh - ${top}px)`
340
- },
341
- async onSearch (props) {
342
- this.tableQuerys = Object.assign(this.tableQuerys, props)
343
- this.tableData = await this.requestTableData()
344
- },
345
- execTableFieldMap (fieldMap = {}, props) {
346
- let ret = {}
347
- const keys = Object.keys(fieldMap)
348
- keys.forEach(key => {
349
- const field = fieldMap[key]
350
- ret[field] = props[key]
351
- })
352
- return ret
353
- },
354
- async selectTreeNode (selectedKeys, e) {
355
- const { fieldMap } = this.tableMeta
356
- this.currentTreeNodeData = e.node.$vnode.data.props.dataRef
357
- const execFieldMapRet = this.execTableFieldMap(fieldMap, e.node.$vnode.data.props.dataRef)
358
- this.tableData = await this.requestTableData(execFieldMapRet)
359
- },
360
- async requestTreeData () {
361
- const { url, requestType = 'GET', params = {}, fieldMap = {} } = this.treeMeta
362
- const fieldMapRet = parseFieldMap(fieldMap, { ...this.currentTreeNodeData, _route: this.$route.query })
363
- const ret = await net[requestType.toLowerCase()](
364
- url,
365
- { ...params, ...fieldMapRet }
366
- ).then(resp => {
367
- const { data } = resp || {}
368
- return data
369
- })
370
- return ret
371
- },
372
- async onChangePage (page, pageSize) {
373
- this.tableData = await this.requestTableData({ currentPage: page, pageSize })
374
- },
375
- async requestTableData (props = {}) {
376
- const { url, requestType = 'GET', page = {} } = this.tableMeta
377
- const { pageSize = 10 } = page
378
- this.tableQuerys = Object.assign(this.tableQuerys, { currentPage: 1, pageSize }, props)
379
- this.loading = true
380
- const ret = await net[requestType.toLowerCase()](
381
- url,
382
- this.tableQuerys
383
- ).then(resp => {
384
- const { data = [], count } = resp || {}
385
- this.total = count
386
- this.loading = false
387
- return data.map(item => {
388
- delete item.children
389
- return {
390
- key: uuidv4(),
391
- ...item
392
- }
393
- })
394
- })
395
- return ret
396
- },
397
- refreshTreeStatus (props = {}) {},
398
- refreshTableStatus (props = {}) {},
399
- calculateTableHeight () {
400
- const currentViewportHeight = window.innerHeight
401
- const tableRef = this.$refs[this.tableRef]
402
- const { top: tableToTop } = tableRef.$el.getBoundingClientRect()
403
- this.tableHeight = currentViewportHeight - tableToTop
404
- },
405
- calculateTreeHeight () {
406
- const modelTableContainerRef = this.$refs[this.modelTableContainerRef]
407
- const { height } = modelTableContainerRef.getBoundingClientRect()
408
- this.treeWrapperHeight = height
409
- }
410
- },
411
- mounted () {
412
- this.calculateTableHeight()
413
- this.$nextTick(() => {
414
- this.calculateTreeHeight()
415
- })
416
- this.resizeObserverModelTableWrapper = new ResizeObserver(entries => {
417
- for (const _ of entries) {
418
- requestAnimationFrame(() => {
419
- this.calculateTableHeight()
420
- })
421
- }
422
- })
423
- this.resizeObserverModelTableWrapper.observe(this.$refs[this.modelTableWrapper])
424
- },
425
- destroyed () {
426
- this.resizeObserverModelTableWrapper.disconnect()
427
- }
428
- }
429
- </script>
430
-
431
- <style lang="scss" scoped>
432
- .ele {
433
- &.model__tree-table {
434
- background: transparent;
435
- display: flex;
436
- flex-direction: row;
437
- width: 100%;
438
- .model__tree-table--container {
439
- .model__tree--wrapper {
440
- width: 240px;
441
- background: #fff;
442
- flex-shrink: 0;
443
- padding: 16px;
444
- box-sizing: border-box;
445
- margin-right: 16px;
446
- overflow-y: auto;
447
- }
448
- }
449
- .model__table--container {
450
- width: 100%;
451
- min-width: 0;
452
- background: #fff;
453
- .model__table--title {
454
- .model__table-title--bar {
455
- width: 100%;
456
- height: 8px;
457
- background: var(--idooel-primary-color);
458
- border-top-left-radius: 4px;
459
- border-top-right-radius: 4px;
460
- }
461
- .model__table-title--text {
462
- text-align: left;
463
- padding: 16px;
464
- font-size: 16px;
465
- font-weight: bold;
466
- background: #fff;
467
- border-bottom: 1px solid;
468
- border-color: var(--idoole-black-016);
469
- }
470
- }
471
- .model__table--wrapper {
472
- background: #fff;
473
- .button-row__area {
474
- width: 100%;
475
- display: flex;
476
- flex-direction: row;
477
- align-items: center;
478
- justify-content: space-between;
479
- padding-top: 16px;
480
- padding-bottom: 8px;
481
- padding-right: 16px;
482
- }
483
- .g-table__wrapper {
484
- .fsm {
485
- cursor: pointer;
486
- color: var(--idooel-primary-color);
487
- }
488
- }
489
- }
490
- }
491
- }
492
- }
493
- </style>
1
+ <template>
2
+ <section class="ele model__tree-table">
3
+ <section class="model__tree-table--container" v-if="showTree">
4
+ <div class="model__tree--title"></div>
5
+ <section :ref="modelTreeWrapper" class="model__tree--wrapper" :style="{height: `${treeWrapperHeight}px`}">
6
+ <ele-tree
7
+ :tree-data="treeData"
8
+ :defaultExpandedKeys="defaultExpandedKeys"
9
+ :defaultSelectedKeys="defaultSelectedKeys"
10
+ @select="selectTreeNode"
11
+ :replace-fields="treeMeta.replaceFields || replaceFields">
12
+ </ele-tree>
13
+ </section>
14
+ </section>
15
+ <section class="model__table--container" :ref="modelTableContainerRef">
16
+ <div class="model__table--title" v-if="title">
17
+ <template v-if="titleMode">
18
+ <div :class="[`model__table-title--${titleMode}`]"></div>
19
+ </template>
20
+ <template v-else>
21
+ <div class="model__table-title--text">{{ title }}</div>
22
+ </template>
23
+ </div>
24
+ <section :ref="modelTableWrapper" class="model__table--wrapper">
25
+ <ele-search-area :ref="searchArea" @search="onSearch" :data-source="searchMeta.elements"></ele-search-area>
26
+ <div class="button-row__area">
27
+ <ele-button-group class="model-table__button-group" v-on="overrideButtonGroupEvent" :ref="buttonGroup" @click="handleClickButtonGroup" :data-source="getButtonGroupElements"></ele-button-group>
28
+ <slot name="tags"></slot>
29
+ </div>
30
+ <ele-table
31
+ v-on="overrideTableEvent"
32
+ :ref="tableRef"
33
+ :row-selection="rowSelection"
34
+ :loading="loading"
35
+ :columns="columns"
36
+ :total="total"
37
+ :height="tableHeight"
38
+ :actions="actions"
39
+ :pageSize="pageSize"
40
+ :pageSizeOptions="pageSizeOptions"
41
+ :data-source="tableData"
42
+ @change-page="onChangePage"
43
+ ></ele-table>
44
+ </section>
45
+ </section>
46
+ <ele-modal-form v-model="modalFormValue" :meta="modalFormMeta"></ele-modal-form>
47
+ <ele-modal-fsm v-model="showFsmModal" :contextProp="fsmContextProp" :meta="fsmMeta" @cancel="handleCloseFsmModal"></ele-modal-fsm>
48
+ </section>
49
+ </template>
50
+
51
+ <script>
52
+ import { type, net } from '@idooel/shared'
53
+ import { v4 as uuidv4 } from 'uuid'
54
+ import { BUILT_IN_EVENT_NAMES, RESERVE_EVENT_NAMES, parseFieldMap, BUILT_IN_TRIGGER } from '../../../utils'
55
+ export default {
56
+ name: 'ele-tree-table-model',
57
+ props: {
58
+ title: {
59
+ type: [Object, String]
60
+ },
61
+ treeMeta: {
62
+ type: Object,
63
+ default: () => ({})
64
+ },
65
+ searchMeta: {
66
+ type: Object,
67
+ default: () => ({})
68
+ },
69
+ buttonGroupMeta: {
70
+ typeof: Object,
71
+ default: () => ({})
72
+ },
73
+ tableMeta: {
74
+ type: Object,
75
+ default: () => ({})
76
+ },
77
+ createMeta: {
78
+ type: Object
79
+ },
80
+ editMeta: {
81
+ type: Object
82
+ }
83
+ },
84
+ provide () {
85
+ return {
86
+ requestTreeData: this.requestTreeData,
87
+ requestTableData: this.requestTableData
88
+ }
89
+ },
90
+ data () {
91
+ return {
92
+ tableHeight: 0,
93
+ modalFormMeta: {},
94
+ modalFormValue: false,
95
+ treeData: [],
96
+ tableData: [],
97
+ defaultExpandedKeys: [],
98
+ defaultSelectedKeys: [],
99
+ replaceFields: {
100
+ title: 'title',
101
+ children: 'children',
102
+ key: 'id'
103
+ },
104
+ loading: false,
105
+ total: 0,
106
+ tableQuerys: {},
107
+ resizeObserverModelTableWrapper: null,
108
+ modelTableWrapperHeight: 0,
109
+ currentTreeNodeData: {},
110
+ treeWrapperHeight: 0,
111
+ currentTableSelection: {},
112
+ showFsmModal: false,
113
+ fsmMeta: {},
114
+ fsmContextProp: {}
115
+ }
116
+ },
117
+ computed: {
118
+ rowSelection () {
119
+ if (!this.currentTableMode) return void 0
120
+ return {
121
+ columnTitle: this.currentSelectionColumn.columnTitle,
122
+ fixed: true,
123
+ type: this.currentTableMode,
124
+ onChange: this.onChangeTableSelection
125
+ }
126
+ },
127
+ currentSelectionColumn () {
128
+ return this.columns.find(item => Object.keys(item).includes('multiple'))
129
+ },
130
+ currentTableMode () {
131
+ if (!this.currentSelectionColumn) return void 0
132
+ const { multiple } = this.currentSelectionColumn
133
+ if (type.isBool(multiple)) {
134
+ if (multiple) {
135
+ return 'checkbox'
136
+ } else {
137
+ return 'radio'
138
+ }
139
+ } else {
140
+ return void 0
141
+ }
142
+ },
143
+ modelTableContainerRef () {
144
+ return uuidv4()
145
+ },
146
+ titleMode () {
147
+ if (type.isObject(this.title)) {
148
+ const { mode = '' } = this.title
149
+ return mode
150
+ }
151
+ return void 0
152
+ },
153
+ tableRef () {
154
+ return uuidv4()
155
+ },
156
+ exposed () {
157
+ return {
158
+ currentTableSelection: this.currentTableSelection,
159
+ currentTreeNode: this.currentTreeNodeData,
160
+ requestTableData: this.requestTableData
161
+ }
162
+ },
163
+ overrideTableEvent () {
164
+ const events = this.actions.reduce((ret, action) => {
165
+ ret[action.eventName] = (e) => {
166
+ this.$emit(action.eventName || 'click', { ...e, currentTreeNode: this.currentTreeNodeData, exposed: this.exposed })
167
+ }
168
+ return ret
169
+ }, {})
170
+ return {
171
+ ...this.$listeners,
172
+ ...events,
173
+ [BUILT_IN_EVENT_NAMES.EDIT]: this[BUILT_IN_EVENT_NAMES.EDIT]
174
+ }
175
+ },
176
+ overrideButtonGroupEvent () {
177
+ const events = this.getButtonGroupElements.reduce((ret, ele) => {
178
+ ret[ele.eventName] = (e) => {
179
+ this.$emit(ele.eventName || 'click', { ...e, currentTreeNode: this.currentTreeNodeData, exposed: this.exposed })
180
+ }
181
+ return ret
182
+ }, {})
183
+ return {
184
+ ...this.$listeners,
185
+ ...events,
186
+ [BUILT_IN_EVENT_NAMES.CREATE]: this[BUILT_IN_EVENT_NAMES.CREATE]
187
+ }
188
+ },
189
+ showTree () {
190
+ return !!Object.keys(this.treeMeta).length
191
+ },
192
+ buttonGroup () {
193
+ return uuidv4()
194
+ },
195
+ searchArea () {
196
+ return uuidv4()
197
+ },
198
+ modelTreeWrapper () {
199
+ return uuidv4()
200
+ },
201
+ modelTableWrapper () {
202
+ return uuidv4()
203
+ },
204
+ actions () {
205
+ const { operations } = this.tableMeta
206
+ if (operations) {
207
+ return operations.elements
208
+ } else {
209
+ return []
210
+ }
211
+ },
212
+ pageSize () {
213
+ const { page = {} } = this.tableMeta
214
+ return page.pageSize || 10
215
+ },
216
+ pageSizeOptions () {
217
+ const { page = {} } = this.tableMeta
218
+ return page.pageSizeOptions || ['10', '20', '30', '40']
219
+ },
220
+ columns () {
221
+ const { columns, operations } = this.tableMeta
222
+ if (type.get(columns) === 'array') {
223
+ const columnsOptions = columns.map(item => {
224
+ const { mode = 'text' } = item
225
+ if (item.render) {
226
+ return {
227
+ ...item,
228
+ customRender: (text, record, index) => {
229
+ const { $createElement } = this
230
+ return item.render.call(this, { h: $createElement, ctx: this }, typeof text == 'string' ? text : text[item.dataIndex], record, index)
231
+ }
232
+ }
233
+ } else if (mode !== BUILT_IN_TRIGGER.TEXT) {
234
+ const { [`${mode}Meta`]: modeMeta } = item
235
+ return {
236
+ ...item,
237
+ customRender: (text, record, index) => {
238
+ return <span onClick={() => this.dispatchTrigger({ mode, record, modeMeta, index })} class={ mode }>{ text }</span>
239
+ }
240
+ }
241
+ }
242
+ return {
243
+ ...item
244
+ }
245
+ })
246
+ if (operations) {
247
+ return [
248
+ ...columnsOptions,
249
+ {
250
+ title: '操作',
251
+ width: operations.width,
252
+ key: 'action',
253
+ fixed: 'right',
254
+ scopedSlots: { customRender: 'action' }
255
+ }
256
+ ]
257
+ }
258
+ return columnsOptions
259
+ } else {
260
+ console.error('Error: columns is invalid, please check it')
261
+ return []
262
+ }
263
+ },
264
+ getButtonGroupElements () {
265
+ const { elements } = this.buttonGroupMeta
266
+ if (type.get(elements) === 'function') {
267
+ return elements.call(this)
268
+ } else if (type.get(elements) === 'array') {
269
+ return elements
270
+ } else {
271
+ return []
272
+ }
273
+ }
274
+ },
275
+ async created () {
276
+ if (this.showTree) {
277
+ this.treeData = await this.requestTreeData()
278
+ const [defaultTreeNode = {}] = this.treeData
279
+ this.defaultExpandedKeys = [defaultTreeNode[this.replaceFields.key]]
280
+ this.defaultSelectedKeys = [defaultTreeNode[this.replaceFields.key]]
281
+ this.currentTreeNodeData = defaultTreeNode
282
+ }
283
+ const { params = {}, fieldMap = {}, overrideInit = false } = this.tableMeta
284
+ const ctx = { ...this.currentTreeNodeData, _route: this.$route.query }
285
+ const initQuerys = Object.assign({}, params, parseFieldMap(fieldMap, ctx))
286
+ if (overrideInit) {
287
+ this.$emit(RESERVE_EVENT_NAMES.INIT, { ...this.exposed })
288
+ } else {
289
+ this.tableData = await this.requestTableData(initQuerys)
290
+ }
291
+ },
292
+ methods: {
293
+ dispatchTrigger ({ mode, record = {}, modeMeta = { } }) {
294
+ switch (mode) {
295
+ case BUILT_IN_TRIGGER.FSM:
296
+ this[`${BUILT_IN_TRIGGER.FSM}Trigger`](record, modeMeta = {
297
+ url: 'api-fsm/workbench/fsm/auditFlow',
298
+ requestType: 'GET',
299
+ fieldMap: {
300
+ modelCode: 'modelCode',
301
+ businessId: 'businessId'
302
+ }
303
+ })
304
+ break
305
+ default:
306
+ break
307
+ }
308
+ },
309
+ handleCloseFsmModal () {
310
+ this.showFsmModal = false
311
+ },
312
+ [`${BUILT_IN_TRIGGER.FSM}Trigger`] (record, meta) {
313
+ this.fsmMeta = meta
314
+ this.fsmContextProp = record
315
+ this.showFsmModal = true
316
+ },
317
+ onChangeTableSelection (_, selectedRows) {
318
+ if (this.currentTableMode === 'radio') {
319
+ this.currentTableSelection = selectedRows[0]
320
+ } else {
321
+ this.currentTableSelection = selectedRows
322
+ }
323
+ },
324
+ [BUILT_IN_EVENT_NAMES.EDIT] () {
325
+ this.modalFormMeta = this.editMeta
326
+ this.modalFormValue = true
327
+ },
328
+ [BUILT_IN_EVENT_NAMES.CREATE] () {
329
+ this.modalFormMeta = this.createMeta
330
+ this.modalFormValue = true
331
+ },
332
+ handleClickButtonGroup (props) {
333
+ const { eventName } = props
334
+ this.$emit(eventName, { currentTreeNode: this.currentTreeNodeData })
335
+ },
336
+ watchViewPort () {
337
+ const modelTableWrapper = this.$refs[this.modelTableWrapper]
338
+ console.log(modelTableWrapper.getBoundingClientRect())
339
+ const { top } = modelTableWrapper.getBoundingClientRect()
340
+ this.$refs[this.modelTreeWrapper].style.height = `calc(100vh - ${top}px)`
341
+ },
342
+ async onSearch (props) {
343
+ this.tableQuerys = Object.assign(this.tableQuerys, props)
344
+ this.tableData = await this.requestTableData()
345
+ },
346
+ execTableFieldMap (fieldMap = {}, props) {
347
+ let ret = {}
348
+ const keys = Object.keys(fieldMap)
349
+ keys.forEach(key => {
350
+ const field = fieldMap[key]
351
+ ret[field] = props[key]
352
+ })
353
+ return ret
354
+ },
355
+ async selectTreeNode (selectedKeys, e) {
356
+ const { fieldMap } = this.tableMeta
357
+ this.currentTreeNodeData = e.node.$vnode.data.props.dataRef
358
+ const execFieldMapRet = this.execTableFieldMap(fieldMap, e.node.$vnode.data.props.dataRef)
359
+ this.tableData = await this.requestTableData(execFieldMapRet)
360
+ },
361
+ async requestTreeData () {
362
+ const { url, requestType = 'GET', params = {}, fieldMap = {} } = this.treeMeta
363
+ const fieldMapRet = parseFieldMap(fieldMap, { ...this.currentTreeNodeData, _route: this.$route.query })
364
+ const ret = await net[requestType.toLowerCase()](
365
+ url,
366
+ { ...params, ...fieldMapRet }
367
+ ).then(resp => {
368
+ const { data } = resp || {}
369
+ return data
370
+ })
371
+ return ret
372
+ },
373
+ async onChangePage (page, pageSize) {
374
+ this.tableData = await this.requestTableData({ currentPage: page, pageSize })
375
+ },
376
+ async requestTableData (props = {}) {
377
+ const { url, requestType = 'GET', page = {} } = this.tableMeta
378
+ const { pageSize = 10 } = page
379
+ this.tableQuerys = Object.assign(this.tableQuerys, { currentPage: 1, pageSize }, props)
380
+ this.loading = true
381
+ const ret = await net[requestType.toLowerCase()](
382
+ url,
383
+ this.tableQuerys
384
+ ).then(resp => {
385
+ const { data = [], count } = resp || {}
386
+ this.total = count
387
+ this.loading = false
388
+ return data.map(item => {
389
+ delete item.children
390
+ return {
391
+ key: uuidv4(),
392
+ ...item
393
+ }
394
+ })
395
+ })
396
+ return ret
397
+ },
398
+ refreshTreeStatus (props = {}) {},
399
+ refreshTableStatus (props = {}) {},
400
+ calculateTableHeight () {
401
+ const currentViewportHeight = window.innerHeight
402
+ const tableRef = this.$refs[this.tableRef]
403
+ const { top: tableToTop } = tableRef.$el.getBoundingClientRect()
404
+ this.tableHeight = currentViewportHeight - tableToTop
405
+ },
406
+ calculateTreeHeight () {
407
+ const modelTableContainerRef = this.$refs[this.modelTableContainerRef]
408
+ const { height } = modelTableContainerRef.getBoundingClientRect()
409
+ this.treeWrapperHeight = height
410
+ }
411
+ },
412
+ mounted () {
413
+ this.calculateTableHeight()
414
+ this.$nextTick(() => {
415
+ this.calculateTreeHeight()
416
+ })
417
+ this.resizeObserverModelTableWrapper = new ResizeObserver(entries => {
418
+ for (const _ of entries) {
419
+ requestAnimationFrame(() => {
420
+ this.calculateTableHeight()
421
+ })
422
+ }
423
+ })
424
+ this.resizeObserverModelTableWrapper.observe(this.$refs[this.modelTableWrapper])
425
+ },
426
+ destroyed () {
427
+ this.resizeObserverModelTableWrapper.disconnect()
428
+ }
429
+ }
430
+ </script>
431
+
432
+ <style lang="scss" scoped>
433
+ .ele {
434
+ &.model__tree-table {
435
+ background: transparent;
436
+ display: flex;
437
+ flex-direction: row;
438
+ width: 100%;
439
+ .model__tree-table--container {
440
+ .model__tree--wrapper {
441
+ width: 240px;
442
+ background: #fff;
443
+ flex-shrink: 0;
444
+ padding: 16px;
445
+ box-sizing: border-box;
446
+ margin-right: 16px;
447
+ overflow-y: auto;
448
+ }
449
+ }
450
+ .model__table--container {
451
+ width: 100%;
452
+ min-width: 0;
453
+ background: #fff;
454
+ .model__table--title {
455
+ .model__table-title--bar {
456
+ width: 100%;
457
+ height: 8px;
458
+ background: var(--idooel-primary-color);
459
+ border-top-left-radius: 4px;
460
+ border-top-right-radius: 4px;
461
+ }
462
+ .model__table-title--text {
463
+ text-align: left;
464
+ padding: 16px;
465
+ font-size: 16px;
466
+ font-weight: bold;
467
+ background: #fff;
468
+ border-bottom: 1px solid;
469
+ border-color: var(--idoole-black-016);
470
+ }
471
+ }
472
+ .model__table--wrapper {
473
+ background: #fff;
474
+ .button-row__area {
475
+ width: 100%;
476
+ display: flex;
477
+ flex-direction: row;
478
+ align-items: center;
479
+ justify-content: space-between;
480
+ padding-top: 16px;
481
+ padding-bottom: 8px;
482
+ padding-right: 16px;
483
+ }
484
+ .g-table__wrapper {
485
+ .fsm {
486
+ cursor: pointer;
487
+ color: var(--idooel-primary-color);
488
+ }
489
+ }
490
+ }
491
+ }
492
+ }
493
+ }
494
+ </style>