w-web-perm 1.0.80 → 1.0.81

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.
@@ -1,1165 +1,1180 @@
1
- <template>
2
- <WDialog
3
- :show.sync="bShow"
4
- :title="isEditable?$t('pemiBlngEditGrups'):$t('pemiBlngEditGrupsForDisplay')"
5
- :icon="mdiFormatListCheckbox"
6
- :minWidth="800"
7
- :maxWidth="800"
8
- :fullscreen="fullscreen"
9
- :contentBackgroundColor="'#fff'"
10
- :headerBtns="useHeaderBtns"
11
- :hasSaveBtn="isEditable && isModified"
12
- :save-btn-tooltip="$t('save')"
13
- :close-btn-tooltip="$t('close')"
14
- @click-btns="clickBtns"
15
- @click-save="clickSave"
16
- @click-close="clickClose"
17
- @resize="resizeDialog"
18
- >
19
- <template v-slot:content>
20
- <div>
21
-
22
- <div
23
- style="_border-bottom:1px solid #ddd; background:#fff;"
24
- v-domresize
25
- @domresize="resizeHead"
26
- >
27
-
28
- <!-- 當前權限群組名稱 -->
29
- <div style="padding:18px 12px; background:#fff; border-bottom:1px solid #ddd;">
30
-
31
- <div style="font-size:0.75rem; color:#999; padding-bottom:2px;">
32
- {{$t('pemiBlngPemiNow')}}
33
- </div>
34
-
35
- <div style="font-size:1.3rem;">
36
- {{pemiName}}
37
- </div>
38
-
39
- </div>
40
-
41
- <!-- 功能區 -->
42
- <div
43
- style="padding:5px; background:#fff; display:flex; align-items:center;"
44
- v-if="isEditable"
45
- >
46
-
47
- <template>
48
-
49
- <WButtonCircle
50
- :paddingStyle="{v:6,h:6}"
51
- :tooltip="$t('checkAllYes')"
52
- :icon="mdiCheckboxMultipleMarked"
53
- :backgroundColor="'#fff'"
54
- :backgroundColorHover="'#f2f2f2'"
55
- _textColor="'#eee'"
56
- _textColorHover="'#fff'"
57
- :iconColor="'#444'"
58
- :iconColorHover="'#222'"
59
- :shadow="false"
60
- @click="showVePemiBlngGrupsToggleItemsEnableAllYes"
61
- ></WButtonCircle>
62
-
63
- <div style="padding-left:4px;"></div>
64
-
65
- </template>
66
-
67
- <template>
68
-
69
- <WButtonCircle
70
- :paddingStyle="{v:6,h:6}"
71
- :tooltip="$t('checkAllNo')"
72
- :icon="mdiCheckboxMultipleBlankOutline"
73
- :backgroundColor="'#fff'"
74
- :backgroundColorHover="'#f2f2f2'"
75
- _textColor="'#eee'"
76
- _textColorHover="'#fff'"
77
- :iconColor="'#444'"
78
- :iconColorHover="'#222'"
79
- :shadow="false"
80
- @click="showVePemiBlngGrupsToggleItemsEnableAllNo"
81
- ></WButtonCircle>
82
-
83
- <div style="padding-left:4px;"></div>
84
-
85
- </template>
86
-
87
- <template>
88
-
89
- <WButtonCircle
90
- :paddingStyle="{v:6,h:6}"
91
- :tooltip="$t('checkAllInv')"
92
- :icon="mdiCodeTagsCheck"
93
- :backgroundColor="'#fff'"
94
- :backgroundColorHover="'#f2f2f2'"
95
- _textColor="'#eee'"
96
- _textColorHover="'#fff'"
97
- :iconColor="'#444'"
98
- :iconColorHover="'#222'"
99
- :shadow="false"
100
- @click="showVePemiBlngGrupsToggleItemsEnableAllInv"
101
- ></WButtonCircle>
102
-
103
- <div style="padding-left:4px;"></div>
104
-
105
- </template>
106
-
107
- <template v-if="hasItemsCheck">
108
-
109
- <WButtonCircle
110
- :paddingStyle="{v:6,h:6}"
111
- :tooltip="$t('pemiBlngDeleteCheckPemis')"
112
- :icon="mdiTrashCanOutline"
113
- :backgroundColor="'#fff'"
114
- :backgroundColorHover="'#f2f2f2'"
115
- _textColor="'#eee'"
116
- _textColorHover="'#fff'"
117
- :iconColor="'#444'"
118
- :iconColorHover="'#222'"
119
- :shadow="false"
120
- @click="deleteItemsCheck"
121
- ></WButtonCircle>
122
-
123
- <div style="padding-left:4px;"></div>
124
-
125
- </template>
126
-
127
- </div>
128
-
129
- </div>
130
-
131
- <template
132
- v-if="!firstLoading"
133
- >
134
-
135
- <template v-if="items">
136
- <WAggridVue
137
- ref="rftable"
138
- :style="`width:100%;`"
139
- :height="contentHeight"
140
- :opt="opt"
141
- >
142
- <template v-slot:cell-render="props">
143
- <template v-if="props.key==='pemisNames'">
144
- <span v-for="(item, idx) in props.row.pemis" :key="idx" style="display:inline-block; line-height:20px; height:20px;">
145
- <div style="display:flex;">
146
- <div :style="'padding:0px 5px; border-top-left-radius:4px; border-bottom-left-radius:4px; ' + (item.enable === 'y' ? 'border-left:1px solid #ac2451; border-right:1px solid #9e2149; border-top:1px solid #ac2451; border-bottom:1px solid #ac2451; background:#be295a; color:#fff;' : 'border-left:1px solid #aaaaaa; border-right:1px solid #aaaaaa; border-top:1px solid #aaaaaa; border-bottom:1px solid #aaaaaa; background:#ffffff; color:#555;')">
147
- {{ item.mode }}
148
- </div>
149
- <div :style="'padding:0px 5px; border-top-right-radius:4px; border-bottom-right-radius:4px; ' + (item.enable === 'y' ? '_border-left:1px solid #ac2451; border-right:1px solid #ac2451; border-top:1px solid #ac2451; border-bottom:1px solid #ac2451; background:#d22f64; color:#fff;' : '_border-left:1px solid #aaaaaa; border-right:1px solid #aaaaaa; border-top:1px solid #aaaaaa; border-bottom:1px solid #aaaaaa; background:#eeeeee; color:#555;')">
150
- {{ item.name }}
151
- </div>
152
- </div>
153
- </span>
154
- </template>
155
- <select v-else-if="props.key==='mode'" @change="showVePemiBlngGrupsToggleItemModeByName(props.row.name, $event.target.value)" :disabled="!isEditable">
156
- <option value="OR" :selected="props.row.mode === 'OR'">OR</option>
157
- <option value="AND" :selected="props.row.mode === 'AND'">AND</option>
158
- </select>
159
- <input v-else-if="props.key==='enable'" type="checkbox" :checked="props.value === 'y'" @click="showVePemiBlngGrupsToggleItemEnableByName(props.row.name)" :disabled="!isEditable" />
160
- <span v-else>{{ props.value }}</span>
161
- </template>
162
- </WAggridVue>
163
- </template>
164
-
165
- </template>
166
-
167
- <div
168
- style="padding:10px 15px; font-size:0.8rem;"
169
- v-else
170
- >
171
- {{$t('waitingData')}}
172
- </div>
173
-
174
- </div>
175
- </template>
176
- </WDialog>
177
- </template>
178
-
179
- <script>
180
- import { mdiDeleteForever, mdiFullscreen, mdiFullscreenExit, mdiFormatListCheckbox, mdiFileTree, mdiTrashCanOutline, mdiCheckboxMultipleBlankOutline, mdiCheckboxMultipleMarked, mdiCodeTagsCheck } from '@mdi/js/mdi.js'
181
- import Vue from 'vue'
182
- import JSON5 from 'json5'
183
- import get from 'lodash-es/get.js'
184
- import set from 'lodash-es/set.js'
185
- import each from 'lodash-es/each.js'
186
- import map from 'lodash-es/map.js'
187
- import size from 'lodash-es/size.js'
188
- import filter from 'lodash-es/filter.js'
189
- import join from 'lodash-es/join.js'
190
- import sortBy from 'lodash-es/sortBy.js'
191
- import isEqual from 'lodash-es/isEqual.js'
192
- import cloneDeep from 'lodash-es/cloneDeep.js'
193
- import genPm from 'wsemi/src/genPm.mjs'
194
- import haskey from 'wsemi/src/haskey.mjs'
195
- import delay from 'wsemi/src/delay.mjs'
196
- import iseobj from 'wsemi/src/iseobj.mjs'
197
- import isestr from 'wsemi/src/isestr.mjs'
198
- import WDialog from 'w-component-vue/src/components/WDialog.vue'
199
- import WButtonCircle from 'w-component-vue/src/components/WButtonCircle.vue'
200
- import WAggridVue from 'w-aggrid-vue/src/components/WAggridVue.vue'
201
-
202
-
203
- export default {
204
- components: {
205
- WDialog,
206
- WButtonCircle,
207
- WAggridVue,
208
- },
209
- props: {
210
- },
211
- data: function() {
212
- return {
213
- mdiDeleteForever,
214
- mdiFullscreen,
215
- mdiFullscreenExit,
216
- mdiFormatListCheckbox,
217
- mdiFileTree,
218
- mdiTrashCanOutline,
219
- mdiCheckboxMultipleBlankOutline,
220
- mdiCheckboxMultipleMarked,
221
- mdiCodeTagsCheck,
222
-
223
- bShow: false,
224
- pm: null,
225
-
226
- fullscreen: false,
227
-
228
- panelHeight: 100,
229
- headHeight: 100,
230
-
231
- firstLoading: true,
232
- firstSetting: true,
233
- isEditable: false,
234
- isModified: false,
235
-
236
- pemi: null,
237
-
238
- items: [],
239
- itemsCheck: [],
240
- opt: null,
241
-
242
- }
243
- },
244
- mounted: function() {
245
- //console.log('mounted')
246
-
247
- let vo = this
248
-
249
- //set
250
- Vue.prototype.$dg.showVePemiBlngGrups = vo.show
251
- Vue.prototype.$dg.showVePemiBlngGrupsToggleItemModeByName = vo.showVePemiBlngGrupsToggleItemModeByName
252
- Vue.prototype.$dg.showVePemiBlngGrupsToggleItemEnableByName = vo.showVePemiBlngGrupsToggleItemEnableByName
253
-
254
- //firstSetting
255
- if (vo.firstSetting) {
256
- // console.log('webInfor', vo.webInfor)
257
-
258
- //會觸發數據變更再導致opt變更導致觸發rowsChange等事件, 故得要延遲, 供組件偵測初始設定數據初始化之用
259
- setTimeout(() => {
260
- vo.firstSetting = false
261
- // console.log('firstSetting', vo.firstSetting)
262
- }, 1)
263
-
264
- }
265
-
266
- },
267
- computed: {
268
-
269
- syncState: function() {
270
- let vo = this
271
- return get(vo, '$store.state.syncState')
272
- },
273
-
274
- targets: function() {
275
- let rs = get(this, `$store.state.targets`)
276
- rs = sortBy(rs, 'order')
277
- return rs
278
- },
279
-
280
- pemis: function() {
281
- let rs = get(this, `$store.state.pemis`)
282
- rs = sortBy(rs, 'order')
283
- return rs
284
- },
285
-
286
- grups: function() {
287
- let rs = get(this, `$store.state.grups`)
288
- rs = sortBy(rs, 'order')
289
- return rs
290
- },
291
-
292
- users: function() {
293
- let rs = get(this, `$store.state.users`)
294
- rs = sortBy(rs, 'order')
295
- return rs
296
- },
297
-
298
- kpHeaderBtns: function() {
299
- let vo = this
300
- let kp = {
301
- // delete: {
302
- // icon: mdiDeleteForever,
303
- // tooltip: `${vo.$t('delete')}${vo.tableNameCht}`,
304
- // evName: 'delete'
305
- // },
306
- toFullscreen: {
307
- icon: mdiFullscreen,
308
- tooltip: vo.$t('screenFull'),
309
- evName: 'toFullscreen'
310
- },
311
- toNormalscreen: {
312
- icon: mdiFullscreenExit,
313
- tooltip: vo.$t('screenNormal'),
314
- evName: 'toNormalscreen'
315
- },
316
- }
317
- return kp
318
- },
319
-
320
- useHeaderBtns: function() {
321
- let vo = this
322
- let bts = []
323
- if (true) {
324
- let k = vo.fullscreen ? 'toNormalscreen' : 'toFullscreen'
325
- bts = [
326
- ...bts,
327
- vo.kpHeaderBtns[k]
328
- ]
329
- }
330
- // if (vo.useDelete) {
331
- // let k = 'delete'
332
- // bts = [
333
- // ...bts,
334
- // vo.kpHeaderBtns[k]
335
- // ]
336
- // }
337
- return bts
338
- },
339
-
340
- contentHeight: function() {
341
- let vo = this
342
-
343
- //h
344
- let h = vo.panelHeight - vo.headHeight
345
- h = Math.max(h, 0)
346
-
347
- return h
348
- },
349
-
350
- hasItemsCheck: function() {
351
- let vo = this
352
-
353
- //h
354
- let b = vo.itemsCheck.length > 0
355
-
356
- return b
357
- },
358
-
359
- pemiName: function() {
360
- let vo = this
361
-
362
- let c = get(vo, 'pemi.name', '')
363
-
364
- return c
365
- },
366
-
367
- },
368
- methods: {
369
-
370
- resizeDialog: function(msg) {
371
- // console.log('methods resizeDialog', msg)
372
-
373
- let vo = this
374
-
375
- //panelWidth, panelHeight
376
- vo.panelHeight = msg.contentHeightMax
377
-
378
- },
379
-
380
- resizeHead: function(msg) {
381
- // console.log('methods resizeHead', msg)
382
-
383
- let vo = this
384
-
385
- //headHeight
386
- vo.headHeight = msg.snew.offsetHeight
387
-
388
- },
389
-
390
- genOpt: function() {
391
- // console.log('methods genOpt')
392
-
393
- let vo = this
394
-
395
- //default
396
- vo.itemsCheck = []
397
-
398
- //opt
399
- let opt = null
400
- if (size(vo.items) > 0) {
401
-
402
- //ks
403
- let ks = [
404
- 'name',
405
- 'pemisNames',
406
- 'mode',
407
- 'enable',
408
- ]
409
- // console.log('ks', ks)
410
-
411
- //kpHead
412
- let kpHead = {
413
- 'name': vo.$t('grupName'),
414
- 'pemisNames': vo.$t('belongPemisNames'),
415
- 'mode': vo.$t('operPemiMode'),
416
- 'enable': vo.$t('operEnable'),
417
- }
418
-
419
- //opt
420
- opt = {
421
- language: vo.$t('aggridLanguage'),
422
- rows: vo.items,
423
- keys: ks,
424
- kpHead,
425
- autoFitColumn: true,
426
- defCellEditable: false, //vo.isEditable,
427
- defHeadFilter: true,
428
- defCellAlignH: 'left',
429
- kpCellEditable: {
430
- 'name': vo.isEditable,
431
- 'mode': false,
432
- 'enable': false,
433
- },
434
- kpHeadWidth: {
435
- 'mode': 100,
436
- 'enable': 100,
437
- },
438
- // kpRowDrag: {
439
- // 'name': true,
440
- // },
441
- // kpHeadFilter: {
442
- // 'enable': false,
443
- // },
444
- kpHeadFilterType: {
445
- 'name': 'text',
446
- 'pemisNames': 'text',
447
- 'mode': 'text',
448
- 'enable': 'text',
449
- },
450
- // kpHeadCheckBox: {
451
- // 'name': true,
452
- // },
453
- kpHeadFocusHighlight: { //雖然效果不完全, 但因按鈕與cell有padding可被點擊, 故還是需要開啟
454
- 'pemisNames': false,
455
- },
456
- rowsChange: (rs) => {
457
- // console.log('rowsChange', rs)
458
- // console.log('rowsChange cloneDeep(vo.opt.rows)', cloneDeep(vo.opt.rows))
459
-
460
- //check
461
- if (!vo.syncState || vo.firstLoading || vo.firstSetting) {
462
- return
463
- }
464
-
465
- //isModified
466
- vo.isModified = true
467
-
468
- },
469
- rowChecked: (rs) => {
470
- // console.log('rowChecked', rs)
471
- // console.log('rowChecked cloneDeep(vo.opt.rows)', cloneDeep(vo.opt.rows))
472
-
473
- //save itemsCheck
474
- vo.itemsCheck = cloneDeep(rs)
475
-
476
- },
477
- }
478
- // console.log('opt', opt)
479
-
480
- }
481
-
482
- //save
483
- vo.opt = opt
484
-
485
- },
486
-
487
- deleteItemsCheck: function() {
488
- // console.log('method deleteItemsCheck')
489
-
490
- let vo = this
491
-
492
- //check
493
- if (size(vo.itemsCheck) === 0) {
494
- return
495
- }
496
-
497
- //cloneDeep
498
- let rows = get(vo, 'opt.rows', [])
499
-
500
- //cloneDeep
501
- rows = cloneDeep(rows)
502
-
503
- //filter
504
- each(vo.itemsCheck, (v) => {
505
- // console.log('v', v)
506
- let name = get(v, 'data.name', '')
507
- if (!isestr(name)) {
508
- console.log(`invalid name`)
509
- return true //跳出換下一個
510
- }
511
- rows = filter(rows, (vv) => {
512
- return vv.name !== name
513
- })
514
- })
515
-
516
- //clear
517
- vo.itemsCheck = []
518
-
519
- //save
520
- vo.opt.rows = rows
521
- // console.log('deleteItemsCheck cloneDeep(vo.opt.rows)', cloneDeep(vo.opt.rows))
522
-
523
- //isModified
524
- vo.isModified = true
525
-
526
- },
527
-
528
- refresh: function() {
529
- let vo = this
530
-
531
- //cmp
532
- let cmp = get(vo, '$refs.rftable')
533
- // console.log('cmp', cmp)
534
-
535
- //refresh, 因set不會觸發ag-grid重繪, 故須另外調用組件函數refresh(內為redrawRows)重繪各列, 使cell-render slot內容更新(w-aggrid-vue 2.0.56起以cell-render slot取代opt.kpCellRender)
536
- cmp.refresh()
537
-
538
- },
539
-
540
- getDisplayData: function() {
541
- let vo = this
542
-
543
- //cmp
544
- let cmp = get(vo, '$refs.rftable')
545
- // console.log('cmp', cmp)
546
-
547
- //getDisplayData
548
- let rows = cmp.getDisplayData()
549
-
550
- return rows
551
- },
552
-
553
- fltKpPemi: function(kp) {
554
- // console.log('fltKpPemi', kp)
555
-
556
- let vo = this
557
-
558
- //_kp
559
- let _kp = {}
560
- each(vo.pemis, (v, k) => {
561
- _kp[v.name] = true
562
- })
563
- // console.log('_kp', _kp)
564
-
565
- //kpt
566
- let kpt = {}
567
- each(kp, (v, k) => {
568
- if (haskey(_kp, k)) {
569
- kpt[k] = v
570
- }
571
- })
572
-
573
- return kpt
574
- },
575
-
576
- genItems: function(pemi, grups) {
577
- // console.log('genItems', pemi, grups)
578
-
579
- let vo = this
580
-
581
- //items
582
- let items = map(grups, (g) => {
583
-
584
- //kpPemi
585
- let kpPemi = JSON5.parse(g.cpemis)
586
- // console.log(g.name, 'kpPemi', kpPemi)
587
-
588
- //fltKpPemi
589
- kpPemi = vo.fltKpPemi(kpPemi)
590
- // console.log(g.name, 'kpPemi(fltKpPemi)', kpPemi)
591
-
592
- //mode, enable, pemis
593
- let mode = 'OR'
594
- let enable = 'n'
595
- let pemis = []
596
- each(kpPemi, (v, k) => {
597
- // console.log(k, 'v', v)
598
-
599
- //_isActive, 此為使用者cpemis內設定, 可為y或n, 僅提取y, 再判斷此使用者是否有使用此pemi
600
- let _isActive = get(v, 'isActive', '')
601
- if (_isActive !== 'y') {
602
- return true //跳出換下一個
603
- }
604
- // console.log(k, '_isActive', _isActive)
605
-
606
- //_mode
607
- let _mode = get(v, 'mode', '')
608
- // console.log(k, '_mode', _mode)
609
-
610
- //b, 使用者是否擁有指定權限群組
611
- let b = k === pemi.name
612
- // console.log(k, 'b', b)
613
-
614
- //mode, isActive
615
- if (b) {
616
- enable = 'y'
617
- mode = _mode //使用使用者給予cpemis內指定權限群組之合併權限模式
618
- // console.log('使用使用者給予cpemis內指定權限群組之合併權限模式 pemi', pemi)
619
- }
620
-
621
- //push
622
- pemis.push({
623
- name: k,
624
- ...v,
625
- enable: b ? 'y' : 'n', //給render使用
626
- })
627
-
628
- })
629
- // console.log(g.name, 'pemis', pemis)
630
-
631
- //pemisNames
632
- let pemisNames = map(pemis, 'name')
633
- pemisNames = join(pemisNames, ' ')
634
- // console.log(g.name, 'pemisNames', pemisNames)
635
-
636
- return {
637
- name: g.name,
638
- pemisNames,
639
- mode,
640
- enable,
641
- // kpPemi,
642
- pemis,
643
- }
644
- })
645
- // console.log(g.name, 'items', items)
646
-
647
- return items
648
- },
649
-
650
- revRows: function() {
651
- // console.log('revRows')
652
-
653
- let vo = this
654
-
655
- //pemi
656
- let pemi = cloneDeep(vo.pemi)
657
- // console.log('pemi', pemi)
658
-
659
- //grups
660
- let grups = cloneDeep(vo.grups)
661
- // console.log('grups', grups)
662
-
663
- //rows
664
- let rows = get(vo, 'opt.rows', [])
665
- // console.log('rows', rows)
666
-
667
- //grups
668
- grups = map(grups, (g, kg) => {
669
-
670
- //kpPemi
671
- let kpPemi = JSON5.parse(g.cpemis)
672
- // console.log(g.name, 'kpPemi', kpPemi)
673
-
674
- //fltKpPemi
675
- kpPemi = vo.fltKpPemi(kpPemi)
676
- // console.log(g.name, 'kpPemi(fltKpPemi)', kpPemi)
677
-
678
- //mode
679
- let mode = get(rows, `${kg}.mode`, '')
680
- if (mode !== 'OR' && mode !== 'AND') {
681
- console.log(`非預期: mode應該皆已指定不應觸發`, mode)
682
- mode = 'OR'
683
- }
684
- // console.log(g.name, 'mode', mode)
685
-
686
- //enable
687
- let enable = get(rows, `${kg}.enable`, '')
688
- if (enable !== 'y' && enable !== 'n') {
689
- console.log(`非預期: enable應該皆已指定不應觸發`, enable)
690
- enable = 'n'
691
- }
692
- // console.log(g.name, 'enable', enable)
693
-
694
- //kpPemi
695
- if (enable === 'y') {
696
- kpPemi[pemi.name] = {
697
- mode,
698
- isActive: 'y',
699
- }
700
- }
701
- else {
702
- if (haskey(kpPemi, pemi.name)) {
703
- delete kpPemi[pemi.name]
704
- }
705
- }
706
- // console.log(g.name, 'kpPemi', kpPemi)
707
-
708
- //update cpemis
709
- let cpemis = JSON.stringify(kpPemi)
710
- g.cpemis = cpemis
711
- // console.log(g.name, 'cpemis', cpemis)
712
-
713
- return g
714
- })
715
-
716
- //items
717
- let items = vo.genItems(pemi, grups)
718
- // console.log('items', items)
719
-
720
- //update pemisNames, pemis
721
- each(items, (r, kr) => {
722
- // name: g.name,
723
- // pemisNames,
724
- // mode,
725
- // enable,
726
- // pemis,
727
-
728
- //set
729
- set(vo, `opt.rows[${kr}].pemisNames`, r.pemisNames)
730
- set(vo, `opt.rows[${kr}].pemis`, r.pemis)
731
- // console.log('vo.opt.rows[kr]', cloneDeep(vo.opt.rows[kr]))
732
-
733
- })
734
-
735
- //refresh
736
- vo.refresh()
737
-
738
- },
739
-
740
- showVePemiBlngGrupsToggleItemModeByName: function(name, mode) {
741
- // console.log('showVePemiBlngGrupsToggleItemModeByName', name, mode)
742
-
743
- let vo = this
744
-
745
- //check
746
- if (!isestr(name)) {
747
- vo.$alert(`${vo.$t('pemiBlngEditNoName')}`, { type: 'error' })
748
- return
749
- }
750
-
751
- //rows
752
- let rows = get(vo, 'opt.rows', [])
753
-
754
- //find
755
- let r = null
756
- let kr = null
757
- each(rows, (v, k) => {
758
- if (get(v, 'name', '') === name) {
759
- r = v
760
- kr = k
761
- return false //跳出
762
- }
763
- })
764
-
765
- //check
766
- if (!iseobj(r)) {
767
- vo.$alert(`${vo.$t('pemiBlngEditNoPemi')}`, { type: 'error' })
768
- return
769
- }
770
-
771
- //mode
772
- // let mode = th.value
773
- // console.log('mode', mode)
774
-
775
- //set
776
- set(vo, `opt.rows[${kr}].mode`, mode)
777
- // console.log('vo.opt.rows[kr]', cloneDeep(vo.opt.rows[kr]))
778
-
779
- //revRows, 已含refresh
780
- vo.revRows()
781
-
782
- //isModified
783
- vo.isModified = true
784
-
785
- },
786
-
787
- showVePemiBlngGrupsToggleItemEnableByName: function(name) {
788
- // console.log('showVePemiBlngGrupsToggleItemEnableByName', name)
789
-
790
- let vo = this
791
-
792
- //check
793
- if (!isestr(name)) {
794
- vo.$alert(`${vo.$t('pemiBlngEditNoName')}`, { type: 'error' })
795
- return
796
- }
797
-
798
- //rows
799
- let rows = get(vo, 'opt.rows', [])
800
-
801
- //find
802
- let r = null
803
- let kr = null
804
- each(rows, (v, k) => {
805
- if (get(v, 'name', '') === name) {
806
- r = v
807
- kr = k
808
- return false //跳出
809
- }
810
- })
811
-
812
- //check
813
- if (!iseobj(r)) {
814
- vo.$alert(`${vo.$t('pemiBlngEditNoPemi')}`, { type: 'error' })
815
- return
816
- }
817
-
818
- //enable
819
- let _enable = get(r, 'enable', 'n')
820
- let enable = _enable === 'y' ? 'n' : 'y'
821
- // console.log('enable', enable)
822
-
823
- //set
824
- set(vo, `opt.rows[${kr}].enable`, enable)
825
- // console.log('vo.opt.rows[kr]', cloneDeep(vo.opt.rows[kr]))
826
-
827
- //revRows, 已含refresh
828
- vo.revRows()
829
-
830
- //isModified
831
- vo.isModified = true
832
-
833
- },
834
-
835
- showVePemiBlngGrupsToggleItemsEnableAllYes: function() {
836
- // console.log('showVePemiBlngGrupsToggleItemsEnableAllYes')
837
-
838
- let vo = this
839
-
840
- //rows
841
- let rows = get(vo, 'opt.rows', [])
842
- // console.log('rows', rows)
843
-
844
- //kpRow
845
- let kpRow = {}
846
- each(rows, (r, kr) => {
847
- kpRow[r.name] = kr
848
- })
849
-
850
- //rowsEff
851
- let rowsEff = vo.getDisplayData()
852
- // console.log('rowsEff', rowsEff)
853
-
854
- //toggle
855
- each(rowsEff, (r) => {
856
-
857
- //kr
858
- let kr = kpRow[r.name]
859
-
860
- //set
861
- set(vo, `opt.rows[${kr}].enable`, 'y')
862
- // console.log('vo.opt.rows[kr]', cloneDeep(vo.opt.rows[kr]))
863
-
864
- })
865
-
866
- //revRows, 已含refresh
867
- vo.revRows()
868
-
869
- //isModified
870
- vo.isModified = true
871
-
872
- },
873
-
874
- showVePemiBlngGrupsToggleItemsEnableAllNo: function() {
875
- // console.log('showVePemiBlngGrupsToggleItemsEnableAllNo')
876
-
877
- let vo = this
878
-
879
- //rows
880
- let rows = get(vo, 'opt.rows', [])
881
- // console.log('rows', rows)
882
-
883
- //kpRow
884
- let kpRow = {}
885
- each(rows, (r, kr) => {
886
- kpRow[r.name] = kr
887
- })
888
-
889
- //rowsEff
890
- let rowsEff = vo.getDisplayData()
891
- // console.log('rowsEff', rowsEff)
892
-
893
- //toggle
894
- each(rowsEff, (r) => {
895
-
896
- //kr
897
- let kr = kpRow[r.name]
898
-
899
- //set
900
- set(vo, `opt.rows[${kr}].enable`, 'n')
901
- // console.log('vo.opt.rows[kr]', cloneDeep(vo.opt.rows[kr]))
902
-
903
- })
904
-
905
- //revRows, 已含refresh
906
- vo.revRows()
907
-
908
- //isModified
909
- vo.isModified = true
910
-
911
- },
912
-
913
- showVePemiBlngGrupsToggleItemsEnableAllInv: function() {
914
- // console.log('showVePemiBlngGrupsToggleItemsEnableAllInv')
915
-
916
- let vo = this
917
-
918
- //rows
919
- let rows = get(vo, 'opt.rows', [])
920
- // console.log('rows', rows)
921
-
922
- //kpRow
923
- let kpRow = {}
924
- each(rows, (r, kr) => {
925
- kpRow[r.name] = kr
926
- })
927
-
928
- //rowsEff
929
- let rowsEff = vo.getDisplayData()
930
- // console.log('rowsEff', rowsEff)
931
-
932
- //toggle
933
- each(rowsEff, (r) => {
934
-
935
- //kr
936
- let kr = kpRow[r.name]
937
-
938
- //enable
939
- let _enable = get(r, 'enable', 'n')
940
- let enable = _enable === 'y' ? 'n' : 'y'
941
-
942
- //set
943
- set(vo, `opt.rows[${kr}].enable`, enable)
944
- // console.log('vo.opt.rows[kr]', cloneDeep(vo.opt.rows[kr]))
945
-
946
- })
947
-
948
- //revRows, 已含refresh
949
- vo.revRows()
950
-
951
- //isModified
952
- vo.isModified = true
953
-
954
- },
955
-
956
- saveGrups: async function(rows) {
957
- // console.log('method saveGrups', rows)
958
-
959
- let vo = this
960
-
961
- //3) updateGrups, 各自 catch + okX 旗標短路 (canonical 五段結構; 空清單檢查已上移至 doSave core())
962
- let okSave = false
963
- await vo.$fapi.updateGrups(rows)
964
- .then(() => { okSave = true })
965
- .catch(async (err) => {
966
- vo.$ui.updateLoading(false) //showCheckYes 前關 loading(modal 阻斷期間避免 loading 疊在底下)
967
- await vo.$dg.showCheckYes(`${vo.$t('grupSaveGrupsFail')}: ${vo.$tErr(err)}`)
968
- })
969
- if (!okSave) {
970
- return
971
- }
972
-
973
- //alert(showCheckYes 前關 loading,避免 modal 等待期間 loading 疊在底下)
974
- vo.$ui.updateLoading(false)
975
- await vo.$dg.showCheckYes(vo.$t('grupSaveGrupsSuccess'), { type: 'success' })
976
-
977
- },
978
-
979
- clickBtns: function(msg) {
980
- // console.log('clickBtns', msg)
981
-
982
- let vo = this
983
-
984
- //evName
985
- if (msg.evName === 'toFullscreen') {
986
- vo.fullscreen = true
987
- }
988
- else if (msg.evName === 'toNormalscreen') {
989
- vo.fullscreen = false
990
- }
991
-
992
- },
993
-
994
- clickSave: function(msg) {
995
- //console.log('methods clickSave', msg)
996
-
997
- let vo = this
998
-
999
- //save按鈕第一行立刻釋放視覺鎖
1000
- msg.pm.resolve()
1001
-
1002
- //fire-and-forget, 不 await
1003
- vo.doSave()
1004
-
1005
- },
1006
-
1007
- doSave: function() {
1008
-
1009
- let vo = this
1010
-
1011
- async function core() {
1012
-
1013
- //1) 事先檢測 (所有同步檢查在開 loading 之前, 空清單不應先閃 loading)
1014
- let rows = get(vo, 'opt.rows', [])
1015
- // console.log('rows', rows)
1016
- if (size(rows) === 0) {
1017
- await vo.$dg.showCheckYes(`${vo.$t('grupSaveGrupsEmpty')}`)
1018
- return
1019
- }
1020
-
1021
- //2) 確定打 API 才開 loading
1022
- vo.$ui.updateLoading(true)
1023
-
1024
- //delay
1025
- await delay(300)
1026
-
1027
- //grups
1028
- let grups = cloneDeep(vo.grups)
1029
- // console.log('grups', grups)
1030
-
1031
- //grupsNew
1032
- let grupsNew = map(rows, (r, kr) => {
1033
-
1034
- //g
1035
- let g = get(grups, kr, {})
1036
-
1037
- //cpemis
1038
- let cpemis = get(g, 'cpemis', '')
1039
-
1040
- //kpPemi
1041
- let kpPemi = JSON5.parse(cpemis)
1042
- // console.log('kpGrup', kpGrup)
1043
-
1044
- //pemis
1045
- let pemis = get(r, 'pemis', [])
1046
-
1047
- //kpPemiNew
1048
- let kpPemiNew = {}
1049
- if (true) {
1050
- each(pemis, (p) => {
1051
- if (p.isActive === 'y') {
1052
- kpPemiNew[p.name] = {
1053
- mode: p.mode,
1054
- isActive: p.isActive,
1055
- }
1056
- }
1057
- })
1058
- }
1059
-
1060
- //check
1061
- if (!isEqual(kpPemi, kpPemiNew)) {
1062
-
1063
- //cpemis
1064
- g.cpemis = JSON.stringify(kpPemiNew)
1065
-
1066
- }
1067
-
1068
- return g
1069
- })
1070
- console.log('grupsNew', grupsNew)
1071
-
1072
- // //check
1073
- // if (size(grupsNew) === 0) {
1074
- // return
1075
- // }
1076
-
1077
- //saveGrups
1078
- await vo.saveGrups(grupsNew)
1079
-
1080
- }
1081
-
1082
- //core
1083
- core()
1084
- .then((rows) => {
1085
-
1086
- //resolve
1087
- vo.pm.resolve(rows)
1088
-
1089
- //hide
1090
- vo.bShow = false
1091
-
1092
- })
1093
- .catch((err) => {
1094
- console.log('doSave', err)
1095
- vo.$alert(vo.$t('anUnexpectedErrorOccurred'), { type: 'error' }) //§5.1: 非預期例外須告知, 不靜默吞 (失敗時 .then 不執行→視窗不關)
1096
- })
1097
- .finally(() => {
1098
-
1099
- //hide loading
1100
- vo.$ui.updateLoading(false)
1101
-
1102
- })
1103
-
1104
- },
1105
-
1106
- clickClose: function() {
1107
- //console.log('methods clickClose')
1108
-
1109
- let vo = this
1110
-
1111
- //reject
1112
- vo.pm.reject('close window')
1113
-
1114
- //hide
1115
- vo.bShow = false
1116
-
1117
- },
1118
-
1119
- show: function (msg) {
1120
- // console.log('methods show', msg)
1121
-
1122
- let vo = this
1123
-
1124
- //pm
1125
- vo.pm = genPm()
1126
-
1127
- //default
1128
- vo.isModified = false
1129
-
1130
- //isEditable, pemi
1131
- let isEditable = get(msg, 'isEditable', false)
1132
- let pemi = get(msg, 'pemi', {})
1133
-
1134
- //grup
1135
- pemi = cloneDeep(pemi)
1136
-
1137
- //grups
1138
- let grups = cloneDeep(vo.grups)
1139
-
1140
- //items
1141
- let items = vo.genItems(pemi, grups)
1142
-
1143
- //save
1144
- vo.isEditable = isEditable
1145
- vo.pemi = pemi
1146
- vo.items = items
1147
-
1148
- //genOpt
1149
- vo.genOpt()
1150
-
1151
- //firstLoading
1152
- vo.firstLoading = false
1153
-
1154
- //bShow
1155
- vo.bShow = true
1156
-
1157
- return vo.pm
1158
- },
1159
-
1160
- }
1161
- }
1162
- </script>
1163
-
1164
- <style scoped>
1165
- </style>
1
+ <template>
2
+ <WDialog
3
+ :show.sync="bShow"
4
+ :title="isEditable?$t('pemiBlngEditGrups'):$t('pemiBlngEditGrupsForDisplay')"
5
+ :icon="mdiFormatListCheckbox"
6
+ :minWidth="800"
7
+ :maxWidth="800"
8
+ :fullscreen="fullscreen"
9
+ :contentBackgroundColor="'#fff'"
10
+ :headerBtns="useHeaderBtns"
11
+ :hasSaveBtn="isEditable && isModified"
12
+ :save-btn-tooltip="$t('save')"
13
+ :close-btn-tooltip="$t('close')"
14
+ @click-btns="clickBtns"
15
+ @click-save="clickSave"
16
+ @click-close="clickClose"
17
+ @resize="resizeDialog"
18
+ >
19
+ <template v-slot:content>
20
+ <div>
21
+
22
+ <div
23
+ style="_border-bottom:1px solid #ddd; background:#fff;"
24
+ v-domresize
25
+ @domresize="resizeHead"
26
+ >
27
+
28
+ <!-- 當前權限群組名稱 -->
29
+ <div style="padding:18px 12px; background:#fff; border-bottom:1px solid #ddd;">
30
+
31
+ <div style="font-size:0.75rem; color:#999; padding-bottom:2px;">
32
+ {{$t('pemiBlngPemiNow')}}
33
+ </div>
34
+
35
+ <div style="font-size:1.3rem;">
36
+ {{pemiName}}
37
+ </div>
38
+
39
+ </div>
40
+
41
+ <!-- 功能區 -->
42
+ <div
43
+ style="padding:5px; background:#fff; display:flex; align-items:center;"
44
+ v-if="isEditable"
45
+ >
46
+
47
+ <template>
48
+
49
+ <WButtonCircle
50
+ :paddingStyle="{v:6,h:6}"
51
+ :tooltip="$t('checkAllYes')"
52
+ :icon="mdiCheckboxMultipleMarked"
53
+ :backgroundColor="'#fff'"
54
+ :backgroundColorHover="'#f2f2f2'"
55
+ _textColor="'#eee'"
56
+ _textColorHover="'#fff'"
57
+ :iconColor="'#444'"
58
+ :iconColorHover="'#222'"
59
+ :shadow="false"
60
+ @click="showVePemiBlngGrupsToggleItemsEnableAllYes"
61
+ ></WButtonCircle>
62
+
63
+ <div style="padding-left:4px;"></div>
64
+
65
+ </template>
66
+
67
+ <template>
68
+
69
+ <WButtonCircle
70
+ :paddingStyle="{v:6,h:6}"
71
+ :tooltip="$t('checkAllNo')"
72
+ :icon="mdiCheckboxMultipleBlankOutline"
73
+ :backgroundColor="'#fff'"
74
+ :backgroundColorHover="'#f2f2f2'"
75
+ _textColor="'#eee'"
76
+ _textColorHover="'#fff'"
77
+ :iconColor="'#444'"
78
+ :iconColorHover="'#222'"
79
+ :shadow="false"
80
+ @click="showVePemiBlngGrupsToggleItemsEnableAllNo"
81
+ ></WButtonCircle>
82
+
83
+ <div style="padding-left:4px;"></div>
84
+
85
+ </template>
86
+
87
+ <template>
88
+
89
+ <WButtonCircle
90
+ :paddingStyle="{v:6,h:6}"
91
+ :tooltip="$t('checkAllInv')"
92
+ :icon="mdiCodeTagsCheck"
93
+ :backgroundColor="'#fff'"
94
+ :backgroundColorHover="'#f2f2f2'"
95
+ _textColor="'#eee'"
96
+ _textColorHover="'#fff'"
97
+ :iconColor="'#444'"
98
+ :iconColorHover="'#222'"
99
+ :shadow="false"
100
+ @click="showVePemiBlngGrupsToggleItemsEnableAllInv"
101
+ ></WButtonCircle>
102
+
103
+ <div style="padding-left:4px;"></div>
104
+
105
+ </template>
106
+
107
+ <template v-if="hasItemsCheck">
108
+
109
+ <WButtonCircle
110
+ :paddingStyle="{v:6,h:6}"
111
+ :tooltip="$t('pemiBlngDeleteCheckPemis')"
112
+ :icon="mdiTrashCanOutline"
113
+ :backgroundColor="'#fff'"
114
+ :backgroundColorHover="'#f2f2f2'"
115
+ _textColor="'#eee'"
116
+ _textColorHover="'#fff'"
117
+ :iconColor="'#444'"
118
+ :iconColorHover="'#222'"
119
+ :shadow="false"
120
+ @click="deleteItemsCheck"
121
+ ></WButtonCircle>
122
+
123
+ <div style="padding-left:4px;"></div>
124
+
125
+ </template>
126
+
127
+ </div>
128
+
129
+ </div>
130
+
131
+ <template
132
+ v-if="!firstLoading"
133
+ >
134
+
135
+ <template v-if="items">
136
+ <WAggridVue
137
+ ref="rftable"
138
+ :style="`width:100%;`"
139
+ :height="contentHeight"
140
+ :opt="opt"
141
+ >
142
+ <template v-slot:cell-render="props">
143
+ <template v-if="props.key==='pemisNames'">
144
+ <span v-for="(item, idx) in props.row.pemis" :key="idx" style="display:inline-block; line-height:20px; height:20px;">
145
+ <div style="display:flex;">
146
+ <div :style="'padding:0px 5px; border-top-left-radius:4px; border-bottom-left-radius:4px; ' + (item.enable === 'y' ? 'border-left:1px solid #ac2451; border-right:1px solid #9e2149; border-top:1px solid #ac2451; border-bottom:1px solid #ac2451; background:#be295a; color:#fff;' : 'border-left:1px solid #aaaaaa; border-right:1px solid #aaaaaa; border-top:1px solid #aaaaaa; border-bottom:1px solid #aaaaaa; background:#ffffff; color:#555;')">
147
+ {{ item.mode }}
148
+ </div>
149
+ <div :style="'padding:0px 5px; border-top-right-radius:4px; border-bottom-right-radius:4px; ' + (item.enable === 'y' ? '_border-left:1px solid #ac2451; border-right:1px solid #ac2451; border-top:1px solid #ac2451; border-bottom:1px solid #ac2451; background:#d22f64; color:#fff;' : '_border-left:1px solid #aaaaaa; border-right:1px solid #aaaaaa; border-top:1px solid #aaaaaa; border-bottom:1px solid #aaaaaa; background:#eeeeee; color:#555;')">
150
+ {{ item.name }}
151
+ </div>
152
+ </div>
153
+ </span>
154
+ </template>
155
+ <WTextSelect
156
+ v-else-if="props.key==='mode'"
157
+ :style="`width:${modeSelectWidth}px;`"
158
+ :items="modeItems"
159
+ :value="props.row.mode"
160
+ :editable="isEditable"
161
+ :paddingStyle="{v:0,h:10}"
162
+ :shadow="false"
163
+ :itemPaddingStyle="{v:8,h:10}"
164
+ :placementDistX="-10"
165
+ :labelContent="'modeSelect'"
166
+ @input="(item)=>{showVePemiBlngGrupsToggleItemModeByName(props.row.name, item)}"
167
+ ></WTextSelect>
168
+ <input v-else-if="props.key==='enable'" type="checkbox" :checked="props.value === 'y'" @click="showVePemiBlngGrupsToggleItemEnableByName(props.row.name)" :disabled="!isEditable" />
169
+ <span v-else>{{ props.value }}</span>
170
+ </template>
171
+ </WAggridVue>
172
+ </template>
173
+
174
+ </template>
175
+
176
+ <div
177
+ style="padding:10px 15px; font-size:0.8rem;"
178
+ v-else
179
+ >
180
+ {{$t('waitingData')}}
181
+ </div>
182
+
183
+ </div>
184
+ </template>
185
+ </WDialog>
186
+ </template>
187
+
188
+ <script>
189
+ import { mdiDeleteForever, mdiFullscreen, mdiFullscreenExit, mdiFormatListCheckbox, mdiFileTree, mdiTrashCanOutline, mdiCheckboxMultipleBlankOutline, mdiCheckboxMultipleMarked, mdiCodeTagsCheck } from '@mdi/js/mdi.js'
190
+ import Vue from 'vue'
191
+ import JSON5 from 'json5'
192
+ import get from 'lodash-es/get.js'
193
+ import set from 'lodash-es/set.js'
194
+ import each from 'lodash-es/each.js'
195
+ import map from 'lodash-es/map.js'
196
+ import size from 'lodash-es/size.js'
197
+ import filter from 'lodash-es/filter.js'
198
+ import join from 'lodash-es/join.js'
199
+ import sortBy from 'lodash-es/sortBy.js'
200
+ import isEqual from 'lodash-es/isEqual.js'
201
+ import cloneDeep from 'lodash-es/cloneDeep.js'
202
+ import genPm from 'wsemi/src/genPm.mjs'
203
+ import haskey from 'wsemi/src/haskey.mjs'
204
+ import delay from 'wsemi/src/delay.mjs'
205
+ import iseobj from 'wsemi/src/iseobj.mjs'
206
+ import isestr from 'wsemi/src/isestr.mjs'
207
+ import WDialog from 'w-component-vue/src/components/WDialog.vue'
208
+ import WButtonCircle from 'w-component-vue/src/components/WButtonCircle.vue'
209
+ import WAggridVue from 'w-aggrid-vue/src/components/WAggridVue.vue'
210
+ import WTextSelect from 'w-component-vue/src/components/WTextSelect.vue'
211
+
212
+
213
+ export default {
214
+ components: {
215
+ WDialog,
216
+ WButtonCircle,
217
+ WAggridVue,
218
+ WTextSelect,
219
+ },
220
+ props: {
221
+ },
222
+ data: function() {
223
+ return {
224
+ mdiDeleteForever,
225
+ mdiFullscreen,
226
+ mdiFullscreenExit,
227
+ mdiFormatListCheckbox,
228
+ mdiFileTree,
229
+ mdiTrashCanOutline,
230
+ mdiCheckboxMultipleBlankOutline,
231
+ mdiCheckboxMultipleMarked,
232
+ mdiCodeTagsCheck,
233
+
234
+ bShow: false,
235
+ pm: null,
236
+
237
+ fullscreen: false,
238
+
239
+ panelHeight: 100,
240
+ headHeight: 100,
241
+
242
+ firstLoading: true,
243
+ firstSetting: true,
244
+ isEditable: false,
245
+ isModified: false,
246
+
247
+ //mode 欄之自製下拉(WTextSelect, 取代原生 select 以免彈出清單之 highlight 色由 OS 決定)
248
+ modeItems: ['OR', 'AND'],
249
+ modeSelectWidth: 72, //= 最長項 'AND' 文字實寬 + 左右內距 10×2 + 展開箭頭 18 + 邊框 1×2, 實測後定值(見 CLAUDE_experience.md)
250
+
251
+ pemi: null,
252
+
253
+ items: [],
254
+ itemsCheck: [],
255
+ opt: null,
256
+
257
+ }
258
+ },
259
+ mounted: function() {
260
+ //console.log('mounted')
261
+
262
+ let vo = this
263
+
264
+ //set
265
+ Vue.prototype.$dg.showVePemiBlngGrups = vo.show
266
+ Vue.prototype.$dg.showVePemiBlngGrupsToggleItemModeByName = vo.showVePemiBlngGrupsToggleItemModeByName
267
+ Vue.prototype.$dg.showVePemiBlngGrupsToggleItemEnableByName = vo.showVePemiBlngGrupsToggleItemEnableByName
268
+
269
+ //firstSetting
270
+ if (vo.firstSetting) {
271
+ // console.log('webInfor', vo.webInfor)
272
+
273
+ //會觸發數據變更再導致opt變更導致觸發rowsChange等事件, 故得要延遲, 供組件偵測初始設定數據初始化之用
274
+ setTimeout(() => {
275
+ vo.firstSetting = false
276
+ // console.log('firstSetting', vo.firstSetting)
277
+ }, 1)
278
+
279
+ }
280
+
281
+ },
282
+ computed: {
283
+
284
+ syncState: function() {
285
+ let vo = this
286
+ return get(vo, '$store.state.syncState')
287
+ },
288
+
289
+ targets: function() {
290
+ let rs = get(this, `$store.state.targets`)
291
+ rs = sortBy(rs, 'order')
292
+ return rs
293
+ },
294
+
295
+ pemis: function() {
296
+ let rs = get(this, `$store.state.pemis`)
297
+ rs = sortBy(rs, 'order')
298
+ return rs
299
+ },
300
+
301
+ grups: function() {
302
+ let rs = get(this, `$store.state.grups`)
303
+ rs = sortBy(rs, 'order')
304
+ return rs
305
+ },
306
+
307
+ users: function() {
308
+ let rs = get(this, `$store.state.users`)
309
+ rs = sortBy(rs, 'order')
310
+ return rs
311
+ },
312
+
313
+ kpHeaderBtns: function() {
314
+ let vo = this
315
+ let kp = {
316
+ // delete: {
317
+ // icon: mdiDeleteForever,
318
+ // tooltip: `${vo.$t('delete')}${vo.tableNameCht}`,
319
+ // evName: 'delete'
320
+ // },
321
+ toFullscreen: {
322
+ icon: mdiFullscreen,
323
+ tooltip: vo.$t('screenFull'),
324
+ evName: 'toFullscreen'
325
+ },
326
+ toNormalscreen: {
327
+ icon: mdiFullscreenExit,
328
+ tooltip: vo.$t('screenNormal'),
329
+ evName: 'toNormalscreen'
330
+ },
331
+ }
332
+ return kp
333
+ },
334
+
335
+ useHeaderBtns: function() {
336
+ let vo = this
337
+ let bts = []
338
+ if (true) {
339
+ let k = vo.fullscreen ? 'toNormalscreen' : 'toFullscreen'
340
+ bts = [
341
+ ...bts,
342
+ vo.kpHeaderBtns[k]
343
+ ]
344
+ }
345
+ // if (vo.useDelete) {
346
+ // let k = 'delete'
347
+ // bts = [
348
+ // ...bts,
349
+ // vo.kpHeaderBtns[k]
350
+ // ]
351
+ // }
352
+ return bts
353
+ },
354
+
355
+ contentHeight: function() {
356
+ let vo = this
357
+
358
+ //h
359
+ let h = vo.panelHeight - vo.headHeight
360
+ h = Math.max(h, 0)
361
+
362
+ return h
363
+ },
364
+
365
+ hasItemsCheck: function() {
366
+ let vo = this
367
+
368
+ //h
369
+ let b = vo.itemsCheck.length > 0
370
+
371
+ return b
372
+ },
373
+
374
+ pemiName: function() {
375
+ let vo = this
376
+
377
+ let c = get(vo, 'pemi.name', '')
378
+
379
+ return c
380
+ },
381
+
382
+ },
383
+ methods: {
384
+
385
+ resizeDialog: function(msg) {
386
+ // console.log('methods resizeDialog', msg)
387
+
388
+ let vo = this
389
+
390
+ //panelWidth, panelHeight
391
+ vo.panelHeight = msg.contentHeightMax
392
+
393
+ },
394
+
395
+ resizeHead: function(msg) {
396
+ // console.log('methods resizeHead', msg)
397
+
398
+ let vo = this
399
+
400
+ //headHeight
401
+ vo.headHeight = msg.snew.offsetHeight
402
+
403
+ },
404
+
405
+ genOpt: function() {
406
+ // console.log('methods genOpt')
407
+
408
+ let vo = this
409
+
410
+ //default
411
+ vo.itemsCheck = []
412
+
413
+ //opt
414
+ let opt = null
415
+ if (size(vo.items) > 0) {
416
+
417
+ //ks
418
+ let ks = [
419
+ 'name',
420
+ 'pemisNames',
421
+ 'mode',
422
+ 'enable',
423
+ ]
424
+ // console.log('ks', ks)
425
+
426
+ //kpHead
427
+ let kpHead = {
428
+ 'name': vo.$t('grupName'),
429
+ 'pemisNames': vo.$t('belongPemisNames'),
430
+ 'mode': vo.$t('operPemiMode'),
431
+ 'enable': vo.$t('operEnable'),
432
+ }
433
+
434
+ //opt
435
+ opt = {
436
+ language: vo.$t('aggridLanguage'),
437
+ rows: vo.items,
438
+ keys: ks,
439
+ kpHead,
440
+ autoFitColumn: true,
441
+ defCellEditable: false, //vo.isEditable,
442
+ defHeadFilter: true,
443
+ defCellAlignH: 'left',
444
+ kpCellEditable: {
445
+ 'name': vo.isEditable,
446
+ 'mode': false,
447
+ 'enable': false,
448
+ },
449
+ kpHeadWidth: {
450
+ 'mode': 100,
451
+ 'enable': 100,
452
+ },
453
+ // kpRowDrag: {
454
+ // 'name': true,
455
+ // },
456
+ // kpHeadFilter: {
457
+ // 'enable': false,
458
+ // },
459
+ kpHeadFilterType: {
460
+ 'name': 'text',
461
+ 'pemisNames': 'text',
462
+ 'mode': 'text',
463
+ 'enable': 'text',
464
+ },
465
+ // kpHeadCheckBox: {
466
+ // 'name': true,
467
+ // },
468
+ kpHeadFocusHighlight: { //雖然效果不完全, 但因按鈕與cell有padding可被點擊, 故還是需要開啟
469
+ 'pemisNames': false,
470
+ },
471
+ rowsChange: (rs) => {
472
+ // console.log('rowsChange', rs)
473
+ // console.log('rowsChange cloneDeep(vo.opt.rows)', cloneDeep(vo.opt.rows))
474
+
475
+ //check
476
+ if (!vo.syncState || vo.firstLoading || vo.firstSetting) {
477
+ return
478
+ }
479
+
480
+ //isModified
481
+ vo.isModified = true
482
+
483
+ },
484
+ rowChecked: (rs) => {
485
+ // console.log('rowChecked', rs)
486
+ // console.log('rowChecked cloneDeep(vo.opt.rows)', cloneDeep(vo.opt.rows))
487
+
488
+ //save itemsCheck
489
+ vo.itemsCheck = cloneDeep(rs)
490
+
491
+ },
492
+ }
493
+ // console.log('opt', opt)
494
+
495
+ }
496
+
497
+ //save
498
+ vo.opt = opt
499
+
500
+ },
501
+
502
+ deleteItemsCheck: function() {
503
+ // console.log('method deleteItemsCheck')
504
+
505
+ let vo = this
506
+
507
+ //check
508
+ if (size(vo.itemsCheck) === 0) {
509
+ return
510
+ }
511
+
512
+ //cloneDeep
513
+ let rows = get(vo, 'opt.rows', [])
514
+
515
+ //cloneDeep
516
+ rows = cloneDeep(rows)
517
+
518
+ //filter
519
+ each(vo.itemsCheck, (v) => {
520
+ // console.log('v', v)
521
+ let name = get(v, 'data.name', '')
522
+ if (!isestr(name)) {
523
+ console.log(`invalid name`)
524
+ return true //跳出換下一個
525
+ }
526
+ rows = filter(rows, (vv) => {
527
+ return vv.name !== name
528
+ })
529
+ })
530
+
531
+ //clear
532
+ vo.itemsCheck = []
533
+
534
+ //save
535
+ vo.opt.rows = rows
536
+ // console.log('deleteItemsCheck cloneDeep(vo.opt.rows)', cloneDeep(vo.opt.rows))
537
+
538
+ //isModified
539
+ vo.isModified = true
540
+
541
+ },
542
+
543
+ refresh: function() {
544
+ let vo = this
545
+
546
+ //cmp
547
+ let cmp = get(vo, '$refs.rftable')
548
+ // console.log('cmp', cmp)
549
+
550
+ //refresh, 因set不會觸發ag-grid重繪, 故須另外調用組件函數refresh(內為redrawRows)重繪各列, 使cell-render slot內容更新(w-aggrid-vue 2.0.56起以cell-render slot取代opt.kpCellRender)
551
+ cmp.refresh()
552
+
553
+ },
554
+
555
+ getDisplayData: function() {
556
+ let vo = this
557
+
558
+ //cmp
559
+ let cmp = get(vo, '$refs.rftable')
560
+ // console.log('cmp', cmp)
561
+
562
+ //getDisplayData
563
+ let rows = cmp.getDisplayData()
564
+
565
+ return rows
566
+ },
567
+
568
+ fltKpPemi: function(kp) {
569
+ // console.log('fltKpPemi', kp)
570
+
571
+ let vo = this
572
+
573
+ //_kp
574
+ let _kp = {}
575
+ each(vo.pemis, (v, k) => {
576
+ _kp[v.name] = true
577
+ })
578
+ // console.log('_kp', _kp)
579
+
580
+ //kpt
581
+ let kpt = {}
582
+ each(kp, (v, k) => {
583
+ if (haskey(_kp, k)) {
584
+ kpt[k] = v
585
+ }
586
+ })
587
+
588
+ return kpt
589
+ },
590
+
591
+ genItems: function(pemi, grups) {
592
+ // console.log('genItems', pemi, grups)
593
+
594
+ let vo = this
595
+
596
+ //items
597
+ let items = map(grups, (g) => {
598
+
599
+ //kpPemi
600
+ let kpPemi = JSON5.parse(g.cpemis)
601
+ // console.log(g.name, 'kpPemi', kpPemi)
602
+
603
+ //fltKpPemi
604
+ kpPemi = vo.fltKpPemi(kpPemi)
605
+ // console.log(g.name, 'kpPemi(fltKpPemi)', kpPemi)
606
+
607
+ //mode, enable, pemis
608
+ let mode = 'OR'
609
+ let enable = 'n'
610
+ let pemis = []
611
+ each(kpPemi, (v, k) => {
612
+ // console.log(k, 'v', v)
613
+
614
+ //_isActive, 此為使用者cpemis內設定, 可為y或n, 僅提取y, 再判斷此使用者是否有使用此pemi
615
+ let _isActive = get(v, 'isActive', '')
616
+ if (_isActive !== 'y') {
617
+ return true //跳出換下一個
618
+ }
619
+ // console.log(k, '_isActive', _isActive)
620
+
621
+ //_mode
622
+ let _mode = get(v, 'mode', '')
623
+ // console.log(k, '_mode', _mode)
624
+
625
+ //b, 使用者是否擁有指定權限群組
626
+ let b = k === pemi.name
627
+ // console.log(k, 'b', b)
628
+
629
+ //mode, isActive
630
+ if (b) {
631
+ enable = 'y'
632
+ mode = _mode //使用使用者給予cpemis內指定權限群組之合併權限模式
633
+ // console.log('使用使用者給予cpemis內指定權限群組之合併權限模式 pemi', pemi)
634
+ }
635
+
636
+ //push
637
+ pemis.push({
638
+ name: k,
639
+ ...v,
640
+ enable: b ? 'y' : 'n', //給render使用
641
+ })
642
+
643
+ })
644
+ // console.log(g.name, 'pemis', pemis)
645
+
646
+ //pemisNames
647
+ let pemisNames = map(pemis, 'name')
648
+ pemisNames = join(pemisNames, ' ')
649
+ // console.log(g.name, 'pemisNames', pemisNames)
650
+
651
+ return {
652
+ name: g.name,
653
+ pemisNames,
654
+ mode,
655
+ enable,
656
+ // kpPemi,
657
+ pemis,
658
+ }
659
+ })
660
+ // console.log(g.name, 'items', items)
661
+
662
+ return items
663
+ },
664
+
665
+ revRows: function() {
666
+ // console.log('revRows')
667
+
668
+ let vo = this
669
+
670
+ //pemi
671
+ let pemi = cloneDeep(vo.pemi)
672
+ // console.log('pemi', pemi)
673
+
674
+ //grups
675
+ let grups = cloneDeep(vo.grups)
676
+ // console.log('grups', grups)
677
+
678
+ //rows
679
+ let rows = get(vo, 'opt.rows', [])
680
+ // console.log('rows', rows)
681
+
682
+ //grups
683
+ grups = map(grups, (g, kg) => {
684
+
685
+ //kpPemi
686
+ let kpPemi = JSON5.parse(g.cpemis)
687
+ // console.log(g.name, 'kpPemi', kpPemi)
688
+
689
+ //fltKpPemi
690
+ kpPemi = vo.fltKpPemi(kpPemi)
691
+ // console.log(g.name, 'kpPemi(fltKpPemi)', kpPemi)
692
+
693
+ //mode
694
+ let mode = get(rows, `${kg}.mode`, '')
695
+ if (mode !== 'OR' && mode !== 'AND') {
696
+ console.log(`非預期: mode應該皆已指定不應觸發`, mode)
697
+ mode = 'OR'
698
+ }
699
+ // console.log(g.name, 'mode', mode)
700
+
701
+ //enable
702
+ let enable = get(rows, `${kg}.enable`, '')
703
+ if (enable !== 'y' && enable !== 'n') {
704
+ console.log(`非預期: enable應該皆已指定不應觸發`, enable)
705
+ enable = 'n'
706
+ }
707
+ // console.log(g.name, 'enable', enable)
708
+
709
+ //kpPemi
710
+ if (enable === 'y') {
711
+ kpPemi[pemi.name] = {
712
+ mode,
713
+ isActive: 'y',
714
+ }
715
+ }
716
+ else {
717
+ if (haskey(kpPemi, pemi.name)) {
718
+ delete kpPemi[pemi.name]
719
+ }
720
+ }
721
+ // console.log(g.name, 'kpPemi', kpPemi)
722
+
723
+ //update cpemis
724
+ let cpemis = JSON.stringify(kpPemi)
725
+ g.cpemis = cpemis
726
+ // console.log(g.name, 'cpemis', cpemis)
727
+
728
+ return g
729
+ })
730
+
731
+ //items
732
+ let items = vo.genItems(pemi, grups)
733
+ // console.log('items', items)
734
+
735
+ //update pemisNames, pemis
736
+ each(items, (r, kr) => {
737
+ // name: g.name,
738
+ // pemisNames,
739
+ // mode,
740
+ // enable,
741
+ // pemis,
742
+
743
+ //set
744
+ set(vo, `opt.rows[${kr}].pemisNames`, r.pemisNames)
745
+ set(vo, `opt.rows[${kr}].pemis`, r.pemis)
746
+ // console.log('vo.opt.rows[kr]', cloneDeep(vo.opt.rows[kr]))
747
+
748
+ })
749
+
750
+ //refresh
751
+ vo.refresh()
752
+
753
+ },
754
+
755
+ showVePemiBlngGrupsToggleItemModeByName: function(name, mode) {
756
+ // console.log('showVePemiBlngGrupsToggleItemModeByName', name, mode)
757
+
758
+ let vo = this
759
+
760
+ //check
761
+ if (!isestr(name)) {
762
+ vo.$alert(`${vo.$t('pemiBlngEditNoName')}`, { type: 'error' })
763
+ return
764
+ }
765
+
766
+ //rows
767
+ let rows = get(vo, 'opt.rows', [])
768
+
769
+ //find
770
+ let r = null
771
+ let kr = null
772
+ each(rows, (v, k) => {
773
+ if (get(v, 'name', '') === name) {
774
+ r = v
775
+ kr = k
776
+ return false //跳出
777
+ }
778
+ })
779
+
780
+ //check
781
+ if (!iseobj(r)) {
782
+ vo.$alert(`${vo.$t('pemiBlngEditNoPemi')}`, { type: 'error' })
783
+ return
784
+ }
785
+
786
+ //mode
787
+ // let mode = th.value
788
+ // console.log('mode', mode)
789
+
790
+ //set
791
+ set(vo, `opt.rows[${kr}].mode`, mode)
792
+ // console.log('vo.opt.rows[kr]', cloneDeep(vo.opt.rows[kr]))
793
+
794
+ //revRows, 已含refresh
795
+ vo.revRows()
796
+
797
+ //isModified
798
+ vo.isModified = true
799
+
800
+ },
801
+
802
+ showVePemiBlngGrupsToggleItemEnableByName: function(name) {
803
+ // console.log('showVePemiBlngGrupsToggleItemEnableByName', name)
804
+
805
+ let vo = this
806
+
807
+ //check
808
+ if (!isestr(name)) {
809
+ vo.$alert(`${vo.$t('pemiBlngEditNoName')}`, { type: 'error' })
810
+ return
811
+ }
812
+
813
+ //rows
814
+ let rows = get(vo, 'opt.rows', [])
815
+
816
+ //find
817
+ let r = null
818
+ let kr = null
819
+ each(rows, (v, k) => {
820
+ if (get(v, 'name', '') === name) {
821
+ r = v
822
+ kr = k
823
+ return false //跳出
824
+ }
825
+ })
826
+
827
+ //check
828
+ if (!iseobj(r)) {
829
+ vo.$alert(`${vo.$t('pemiBlngEditNoPemi')}`, { type: 'error' })
830
+ return
831
+ }
832
+
833
+ //enable
834
+ let _enable = get(r, 'enable', 'n')
835
+ let enable = _enable === 'y' ? 'n' : 'y'
836
+ // console.log('enable', enable)
837
+
838
+ //set
839
+ set(vo, `opt.rows[${kr}].enable`, enable)
840
+ // console.log('vo.opt.rows[kr]', cloneDeep(vo.opt.rows[kr]))
841
+
842
+ //revRows, 已含refresh
843
+ vo.revRows()
844
+
845
+ //isModified
846
+ vo.isModified = true
847
+
848
+ },
849
+
850
+ showVePemiBlngGrupsToggleItemsEnableAllYes: function() {
851
+ // console.log('showVePemiBlngGrupsToggleItemsEnableAllYes')
852
+
853
+ let vo = this
854
+
855
+ //rows
856
+ let rows = get(vo, 'opt.rows', [])
857
+ // console.log('rows', rows)
858
+
859
+ //kpRow
860
+ let kpRow = {}
861
+ each(rows, (r, kr) => {
862
+ kpRow[r.name] = kr
863
+ })
864
+
865
+ //rowsEff
866
+ let rowsEff = vo.getDisplayData()
867
+ // console.log('rowsEff', rowsEff)
868
+
869
+ //toggle
870
+ each(rowsEff, (r) => {
871
+
872
+ //kr
873
+ let kr = kpRow[r.name]
874
+
875
+ //set
876
+ set(vo, `opt.rows[${kr}].enable`, 'y')
877
+ // console.log('vo.opt.rows[kr]', cloneDeep(vo.opt.rows[kr]))
878
+
879
+ })
880
+
881
+ //revRows, 已含refresh
882
+ vo.revRows()
883
+
884
+ //isModified
885
+ vo.isModified = true
886
+
887
+ },
888
+
889
+ showVePemiBlngGrupsToggleItemsEnableAllNo: function() {
890
+ // console.log('showVePemiBlngGrupsToggleItemsEnableAllNo')
891
+
892
+ let vo = this
893
+
894
+ //rows
895
+ let rows = get(vo, 'opt.rows', [])
896
+ // console.log('rows', rows)
897
+
898
+ //kpRow
899
+ let kpRow = {}
900
+ each(rows, (r, kr) => {
901
+ kpRow[r.name] = kr
902
+ })
903
+
904
+ //rowsEff
905
+ let rowsEff = vo.getDisplayData()
906
+ // console.log('rowsEff', rowsEff)
907
+
908
+ //toggle
909
+ each(rowsEff, (r) => {
910
+
911
+ //kr
912
+ let kr = kpRow[r.name]
913
+
914
+ //set
915
+ set(vo, `opt.rows[${kr}].enable`, 'n')
916
+ // console.log('vo.opt.rows[kr]', cloneDeep(vo.opt.rows[kr]))
917
+
918
+ })
919
+
920
+ //revRows, 已含refresh
921
+ vo.revRows()
922
+
923
+ //isModified
924
+ vo.isModified = true
925
+
926
+ },
927
+
928
+ showVePemiBlngGrupsToggleItemsEnableAllInv: function() {
929
+ // console.log('showVePemiBlngGrupsToggleItemsEnableAllInv')
930
+
931
+ let vo = this
932
+
933
+ //rows
934
+ let rows = get(vo, 'opt.rows', [])
935
+ // console.log('rows', rows)
936
+
937
+ //kpRow
938
+ let kpRow = {}
939
+ each(rows, (r, kr) => {
940
+ kpRow[r.name] = kr
941
+ })
942
+
943
+ //rowsEff
944
+ let rowsEff = vo.getDisplayData()
945
+ // console.log('rowsEff', rowsEff)
946
+
947
+ //toggle
948
+ each(rowsEff, (r) => {
949
+
950
+ //kr
951
+ let kr = kpRow[r.name]
952
+
953
+ //enable
954
+ let _enable = get(r, 'enable', 'n')
955
+ let enable = _enable === 'y' ? 'n' : 'y'
956
+
957
+ //set
958
+ set(vo, `opt.rows[${kr}].enable`, enable)
959
+ // console.log('vo.opt.rows[kr]', cloneDeep(vo.opt.rows[kr]))
960
+
961
+ })
962
+
963
+ //revRows, 已含refresh
964
+ vo.revRows()
965
+
966
+ //isModified
967
+ vo.isModified = true
968
+
969
+ },
970
+
971
+ saveGrups: async function(rows) {
972
+ // console.log('method saveGrups', rows)
973
+
974
+ let vo = this
975
+
976
+ //3) updateGrups, 各自 catch + okX 旗標短路 (canonical 五段結構; 空清單檢查已上移至 doSave core())
977
+ let okSave = false
978
+ await vo.$fapi.updateGrups(rows)
979
+ .then(() => { okSave = true })
980
+ .catch(async (err) => {
981
+ vo.$ui.updateLoading(false) //showCheckYes 前關 loading(modal 阻斷期間避免 loading 疊在底下)
982
+ await vo.$dg.showCheckYes(`${vo.$t('grupSaveGrupsFail')}: ${vo.$tErr(err)}`)
983
+ })
984
+ if (!okSave) {
985
+ return
986
+ }
987
+
988
+ //alert(showCheckYes 前關 loading,避免 modal 等待期間 loading 疊在底下)
989
+ vo.$ui.updateLoading(false)
990
+ await vo.$dg.showCheckYes(vo.$t('grupSaveGrupsSuccess'), { type: 'success' })
991
+
992
+ },
993
+
994
+ clickBtns: function(msg) {
995
+ // console.log('clickBtns', msg)
996
+
997
+ let vo = this
998
+
999
+ //evName
1000
+ if (msg.evName === 'toFullscreen') {
1001
+ vo.fullscreen = true
1002
+ }
1003
+ else if (msg.evName === 'toNormalscreen') {
1004
+ vo.fullscreen = false
1005
+ }
1006
+
1007
+ },
1008
+
1009
+ clickSave: function(msg) {
1010
+ //console.log('methods clickSave', msg)
1011
+
1012
+ let vo = this
1013
+
1014
+ //save按鈕第一行立刻釋放視覺鎖
1015
+ msg.pm.resolve()
1016
+
1017
+ //fire-and-forget, 不 await
1018
+ vo.doSave()
1019
+
1020
+ },
1021
+
1022
+ doSave: function() {
1023
+
1024
+ let vo = this
1025
+
1026
+ async function core() {
1027
+
1028
+ //1) 事先檢測 (所有同步檢查在開 loading 之前, 空清單不應先閃 loading)
1029
+ let rows = get(vo, 'opt.rows', [])
1030
+ // console.log('rows', rows)
1031
+ if (size(rows) === 0) {
1032
+ await vo.$dg.showCheckYes(`${vo.$t('grupSaveGrupsEmpty')}`)
1033
+ return
1034
+ }
1035
+
1036
+ //2) 確定打 API 才開 loading
1037
+ vo.$ui.updateLoading(true)
1038
+
1039
+ //delay
1040
+ await delay(300)
1041
+
1042
+ //grups
1043
+ let grups = cloneDeep(vo.grups)
1044
+ // console.log('grups', grups)
1045
+
1046
+ //grupsNew
1047
+ let grupsNew = map(rows, (r, kr) => {
1048
+
1049
+ //g
1050
+ let g = get(grups, kr, {})
1051
+
1052
+ //cpemis
1053
+ let cpemis = get(g, 'cpemis', '')
1054
+
1055
+ //kpPemi
1056
+ let kpPemi = JSON5.parse(cpemis)
1057
+ // console.log('kpGrup', kpGrup)
1058
+
1059
+ //pemis
1060
+ let pemis = get(r, 'pemis', [])
1061
+
1062
+ //kpPemiNew
1063
+ let kpPemiNew = {}
1064
+ if (true) {
1065
+ each(pemis, (p) => {
1066
+ if (p.isActive === 'y') {
1067
+ kpPemiNew[p.name] = {
1068
+ mode: p.mode,
1069
+ isActive: p.isActive,
1070
+ }
1071
+ }
1072
+ })
1073
+ }
1074
+
1075
+ //check
1076
+ if (!isEqual(kpPemi, kpPemiNew)) {
1077
+
1078
+ //cpemis
1079
+ g.cpemis = JSON.stringify(kpPemiNew)
1080
+
1081
+ }
1082
+
1083
+ return g
1084
+ })
1085
+ console.log('grupsNew', grupsNew)
1086
+
1087
+ // //check
1088
+ // if (size(grupsNew) === 0) {
1089
+ // return
1090
+ // }
1091
+
1092
+ //saveGrups
1093
+ await vo.saveGrups(grupsNew)
1094
+
1095
+ }
1096
+
1097
+ //core
1098
+ core()
1099
+ .then((rows) => {
1100
+
1101
+ //resolve
1102
+ vo.pm.resolve(rows)
1103
+
1104
+ //hide
1105
+ vo.bShow = false
1106
+
1107
+ })
1108
+ .catch((err) => {
1109
+ console.log('doSave', err)
1110
+ vo.$alert(vo.$t('anUnexpectedErrorOccurred'), { type: 'error' }) //§5.1: 非預期例外須告知, 不靜默吞 (失敗時 .then 不執行→視窗不關)
1111
+ })
1112
+ .finally(() => {
1113
+
1114
+ //hide loading
1115
+ vo.$ui.updateLoading(false)
1116
+
1117
+ })
1118
+
1119
+ },
1120
+
1121
+ clickClose: function() {
1122
+ //console.log('methods clickClose')
1123
+
1124
+ let vo = this
1125
+
1126
+ //reject
1127
+ vo.pm.reject('close window')
1128
+
1129
+ //hide
1130
+ vo.bShow = false
1131
+
1132
+ },
1133
+
1134
+ show: function (msg) {
1135
+ // console.log('methods show', msg)
1136
+
1137
+ let vo = this
1138
+
1139
+ //pm
1140
+ vo.pm = genPm()
1141
+
1142
+ //default
1143
+ vo.isModified = false
1144
+
1145
+ //isEditable, pemi
1146
+ let isEditable = get(msg, 'isEditable', false)
1147
+ let pemi = get(msg, 'pemi', {})
1148
+
1149
+ //grup
1150
+ pemi = cloneDeep(pemi)
1151
+
1152
+ //grups
1153
+ let grups = cloneDeep(vo.grups)
1154
+
1155
+ //items
1156
+ let items = vo.genItems(pemi, grups)
1157
+
1158
+ //save
1159
+ vo.isEditable = isEditable
1160
+ vo.pemi = pemi
1161
+ vo.items = items
1162
+
1163
+ //genOpt
1164
+ vo.genOpt()
1165
+
1166
+ //firstLoading
1167
+ vo.firstLoading = false
1168
+
1169
+ //bShow
1170
+ vo.bShow = true
1171
+
1172
+ return vo.pm
1173
+ },
1174
+
1175
+ }
1176
+ }
1177
+ </script>
1178
+
1179
+ <style scoped>
1180
+ </style>