w-web-api 1.0.26 → 1.0.28

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,50 +1,460 @@
1
1
  <template>
2
- <div style="height:100%;">
2
+ <div
3
+ style="height:100%; width:100%;"
4
+ :changeApis="changeApis"
5
+ v-domresize
6
+ @domresize="resize"
7
+ >
3
8
 
4
9
  <template v-if="syncState">
5
10
 
6
- <LayoutContentList></LayoutContentList>
11
+ <!-- menu left, 使用opacity:0.999讓WDrawer使用浮動模式時不會遮蔽vuetify彈窗, 僅由Layout處設定即可, 其內dom皆受影響 -->
12
+ <WDrawer
13
+ :style="`height:${panelHeight}px; width:100%; opacity:0.999;`"
14
+ v-model="drawer"
15
+ :drawerWidth.sync="drawerWidth"
16
+ :drawerWidthMin="drawerWidthMin"
17
+ :drawerWidthMax="drawerWidthMax"
18
+ :mode="'from-left'"
19
+ :afloat="drawerAfloat"
20
+ :dragDrawerWidth="true"
21
+ >
22
+
23
+ <template v-slot:drawer="props">
24
+
25
+ <div :style="`height:${props.height}px; background:${drawerAfloat?'#fff':'transparent'}; position:relative;`">
26
+
27
+ <WTree
28
+ :style="`height:${props.height}px;`"
29
+ :viewHeightMax="props.height"
30
+ :data="apisTree"
31
+ :iconHeight="lineHeightTree"
32
+ :defItemHeight="lineHeightTree"
33
+ :activable="true"
34
+ :itemActive="apiActive"
35
+ :funActive="funActive"
36
+ :itemTextColorActive="'#000'"
37
+ :itemBackgroundColorActive ="'rgba(100,100,100,0.15)'"
38
+ >
39
+ <template v-slot:item="props">
40
+
41
+ <div
42
+ :style="`display:flex; align-items:center; min-height:${lineHeightTree}px;`"
43
+ v-if="props.data.type!=='node'"
44
+ >
45
+ {{props.data.key}}
46
+ </div>
47
+
48
+ <div
49
+ :style="`display:flex; align-items:center; min-height:${lineHeightTree}px; cursor:pointer;`"
50
+ @click="ckItem(getItemByKey(props.data.text))"
51
+ v-else
52
+ >
53
+
54
+ <div style="padding-right:5px;">
55
+ <div :style="`padding:0px 6px; font-size:0.7rem; border-radius:10px; border:1px solid #ddd; color:#fff; background:${getMethodColorByKey(props.data.text)};`">
56
+ {{getMethodByKey(props.data.text)}}
57
+ </div>
58
+ </div>
59
+
60
+ <div>
61
+ {{$ui.gv(getItemByKey(props.data.text),'name')}}
62
+ </div>
63
+
64
+ </div>
65
+
66
+ </template>
67
+ </WTree>
68
+
69
+ <div
70
+ :style="`position:absolute; top:1px; right:12px;`"
71
+ v-if="drawer"
72
+ >
73
+ <WButtonCircle
74
+ :paddingStyle="{v:3,h:3}"
75
+ :icon="'mdi-arrow-left'"
76
+ :iconSize="16"
77
+ :backgroundColor="'#fff'"
78
+ :backgroundColorHover="'#eee'"
79
+ :backgroundColorFocus="'#fff'"
80
+ :borderColor="'transparent'"
81
+ :borderColorHover="'#eee'"
82
+ :borderColorFocus="'#eee'"
83
+ :tooltip="$t('menuTreeHide')"
84
+ :shadow="true"
85
+ @click="drawer=false"
86
+ ></WButtonCircle>
87
+ </div>
88
+
89
+ </div>
90
+
91
+ </template>
92
+
93
+ <template v-slot:content="props">
94
+ <div :style="`height:${props.height}px; width:${props.width}px; position:relative;`">
95
+
96
+ <!-- 選擇API之顯示區 -->
97
+ <template>
98
+
99
+ <div
100
+ :style="`height:${props.height}px; overflow-y:auto;`"
101
+ v-if="apiSelect"
102
+ >
103
+ <div style="padding:20px;">
104
+
105
+ <div style="padding:5px;">
106
+
107
+ <div class="bk-title" style="">
108
+ {{$t('apiUrl')}}
109
+ </div>
110
+
111
+ <div style="padding:10px; border-radius:5px; border:1px solid #ddd; background:#fff; display:flex; align-items:center;">
112
+
113
+ <div style="padding-right:5px;">
114
+ <div :style="`padding:0px 6px; font-size:0.7rem; border-radius:10px; border:1px solid #ddd; color:#fff; background:${getMethodColor(apiSelect)};`">
115
+ {{getMethod(apiSelect)}}
116
+ </div>
117
+ </div>
118
+
119
+ <div style="font-size:0.8rem;">
120
+ {{$ui.gv(apiSelect,'url')}}
121
+ </div>
122
+
123
+ </div>
124
+
125
+ </div>
126
+
127
+ <div style="padding:10px;">
128
+
129
+ <div style="color:#485ed5;">
130
+ {{$ui.gv(apiSelect,'name')}}
131
+ </div>
132
+
133
+ <div class="bk-title" style="">
134
+ {{$ui.gv(apiSelect,'description')}}
135
+ </div>
136
+
137
+ </div>
138
+
139
+ <div style="padding:10px;">
140
+
141
+ <div class="bk" style="">
142
+
143
+ <div class="bk-title" style="">
144
+ {{$t('tokens')}}
145
+ </div>
146
+
147
+ <div class="bk-item" style="">
148
+ {{$ui.gv(apiSelect,'tokens')}}
149
+ </div>
150
+
151
+ </div>
152
+
153
+ <div class="bk" style="">
154
+
155
+ <div class="bk-title" style="">
156
+ {{$t('version')}}
157
+ </div>
158
+
159
+ <div class="bk-item" style="">
160
+ {{$ui.gv(apiSelect,'version')}}
161
+ </div>
162
+
163
+ </div>
164
+
165
+ <div class="bk" style="">
166
+
167
+ <div class="bk-title" style="">
168
+ {{$t('levels')}}
169
+ </div>
170
+
171
+ <div class="bk-item" style="">
172
+ {{$ui.gv(apiSelect,'')}}
173
+ </div>
174
+
175
+ </div>
176
+
177
+ <div class="bk" style="">
178
+
179
+ <div class="bk-title" style="">
180
+ {{$t('keywords')}}
181
+ </div>
182
+
183
+ <div class="bk-item" style="">
184
+ {{$ui.gv(apiSelect,'')}}
185
+ </div>
186
+
187
+ </div>
188
+
189
+ <div class="bk" style="">
190
+
191
+ <div class="bk-title" style="">
192
+ {{$t('state')}}
193
+ </div>
194
+
195
+ <div class="bk-item" style="">
196
+ {{$ui.gv(apiSelect,'')}}
197
+ </div>
198
+
199
+ </div>
200
+
201
+ <div class="bk" style="">
202
+
203
+ <div class="bk-title" style="">
204
+ {{$t('timeCreate')}}
205
+ </div>
206
+
207
+ <div class="bk-item" style="">
208
+ {{$ui.gv(apiSelect,'timeCreate',getDay)}}
209
+ </div>
210
+
211
+ </div>
212
+
213
+ <div class="bk" style="">
214
+
215
+ <div class="bk-title" style="">
216
+ {{$t('timeUpdate')}}
217
+ </div>
218
+
219
+ <div class="bk-item" style="">
220
+ {{$ui.gv(apiSelect,'timeUpdate',getDay)}}
221
+ </div>
222
+
223
+ </div>
224
+
225
+ <div class="bk" style="">
226
+
227
+ <div class="bk-title" style="">
228
+ {{$t('creator')}}
229
+ </div>
230
+
231
+ <div class="bk-item" style="">
232
+ {{$ui.gv(apiSelect,'creator')}}
233
+ </div>
234
+
235
+ </div>
236
+
237
+ <div class="bk" style="">
238
+
239
+ <div class="bk-title" style="">
240
+ {{$t('dataSource')}}
241
+ </div>
242
+
243
+ <div class="bk-item" style="">
244
+ {{$ui.gv(apiSelect,'dataSource')}}
245
+ </div>
246
+
247
+ </div>
248
+
249
+ <div class="bk" style="">
250
+
251
+ <div class="bk-title" style="">
252
+ {{$t('isActive')}}
253
+ </div>
254
+
255
+ <div class="bk-item" style="">
256
+ {{$ui.gv(apiSelect,'isActive')}}
257
+ </div>
258
+
259
+ </div>
260
+
261
+ </div>
262
+
263
+ <div style="padding:10px;">
264
+
265
+ <div class="bk-title" style="">
266
+ {{$t('mdInputParams')}}
267
+ </div>
268
+
269
+ <div class="bk-item" style="padding:10px;">
270
+ <MdPanel
271
+ :md="$ui.gv(apiSelect,'mdInputParams')"
272
+ ></MdPanel>
273
+ </div>
274
+
275
+ </div>
276
+
277
+ <div style="padding:10px;">
278
+
279
+ <div class="bk-title" style="">
280
+ {{$t('inputExample')}}
281
+ </div>
282
+
283
+ <div class="bk-item" style="padding:10px;">
284
+ {{$ui.gv(apiSelect,'inputExample')}}
285
+ </div>
286
+
287
+ </div>
288
+
289
+ <div style="padding:10px;">
290
+
291
+ <div class="bk-title" style="">
292
+ {{$t('mdOutputParams')}}
293
+ </div>
294
+
295
+ <div class="bk-item" style="padding:10px;">
296
+ <MdPanel
297
+ :md="$ui.gv(apiSelect,'mdOutputParams')"
298
+ ></MdPanel>
299
+ </div>
300
+
301
+ </div>
302
+
303
+ <div style="padding:10px;">
304
+
305
+ <div class="bk-title" style="">
306
+ {{$t('outputExample')}}
307
+ </div>
308
+
309
+ <div style="padding-top:3px;">
310
+
311
+ <div style="padding-left:10px; margin-bottom:-1px;">
312
+ <!-- 因上下皆有border, 故需負margin-bottom來吃掉重複border -->
313
+ <WGroupRadio
314
+ :items="optputMenuItems"
315
+ :value="optputMenuItemSelect"
316
+ @input="changeOptputMenuItemSelect"
317
+ :group="true"
318
+ :group-border-radius-style="{top:true}"
319
+ :group-shift="7"
320
+ :border-radius="20"
321
+ :border-color="'#ddd'"
322
+ :border-color-hover="'#dadada'"
323
+ :border-color-active="'orange lighten-2'"
324
+ :margin-style="{}"
325
+ ></WGroupRadio>
326
+ </div>
327
+
328
+ <div style="border:1px solid #ddd; background:#fff">
329
+
330
+ <div style="" v-if="optputMenuItemSelectId==='tree'">
331
+ <WJsonView
332
+ style="width:100%;"
333
+ :viewHeightMax="null"
334
+ :data="getOutputJsonObj(apiSelect)"
335
+ ></WJsonView>
336
+ </div>
337
+
338
+ <div style="padding:10px; color:#555; font-size:0.85rem;" v-if="optputMenuItemSelectId==='raw'">
339
+ <pre>{{getOutputJson(apiSelect)}}</pre>
340
+ </div>
341
+
342
+ </div>
343
+
344
+ </div>
345
+
346
+ </div>
347
+
348
+ </div>
349
+ </div>
350
+
351
+ <div
352
+ style="padding:20px; font-size:0.9rem;"
353
+ v-else
354
+ >
355
+ {{$t('noSelectApi')}}
356
+ </div>
357
+
358
+ </template>
359
+
360
+ <div
361
+ :style="`position:absolute; top:1px; left:4px;`"
362
+ v-if="!drawer"
363
+ >
364
+ <WButtonCircle
365
+ :paddingStyle="{v:3,h:3}"
366
+ :icon="'mdi-arrow-right'"
367
+ :iconSize="16"
368
+ :backgroundColor="'#fff'"
369
+ :backgroundColorHover="'#eee'"
370
+ :backgroundColorFocus="'#fff'"
371
+ :borderColor="'transparent'"
372
+ :borderColorHover="'#eee'"
373
+ :borderColorFocus="'#eee'"
374
+ :tooltip="$t('menuTreeShow')"
375
+ :shadow="true"
376
+ @click="drawer=true"
377
+ ></WButtonCircle>
378
+ </div>
379
+
380
+ </div>
381
+ </template>
382
+
383
+ </WDrawer>
7
384
 
8
385
  </template>
9
386
 
10
- <div
11
- style="padding:20px; font-size:0.9rem;"
12
- v-else
13
- >
14
- {{$t('waitingData')}}
15
- </div>
387
+ <template v-else>
388
+ <div
389
+ style="padding:20px; font-size:0.9rem;"
390
+ >
391
+ {{$t('waitingData')}}
392
+ </div>
393
+ </template>
16
394
 
17
395
  </div>
18
396
  </template>
19
397
 
20
398
  <script>
21
399
  import get from 'lodash/get'
22
- // import map from 'lodash/map'
23
- // import each from 'lodash/each'
24
- // import size from 'lodash/size'
25
- // import cloneDeep from 'lodash/cloneDeep'
26
- // import isestr from 'wsemi/src/isestr.mjs'
27
- // import isnum from 'wsemi/src/isnum.mjs'
28
- // import cdbl from 'wsemi/src/cdbl.mjs'
29
- // import WPanelBulge from 'w-component-vue/src/components/WPanelBulge.vue'
30
- // import WButtonChip from 'w-component-vue/src/components/WButtonChip.vue'
31
- // import WGroupCheck from 'w-component-vue/src/components/WGroupCheck.vue'
32
- // import WTree from 'w-component-vue/src/components/WTree.vue'
33
- import LayoutContentList from './LayoutContentList.vue'
400
+ import set from 'lodash/set'
401
+ import each from 'lodash/each'
402
+ import trim from 'lodash/trim'
403
+ import find from 'lodash/find'
404
+ import cloneDeep from 'lodash/cloneDeep'
405
+ import isobj from 'wsemi/src/isobj.mjs'
406
+ import iseobj from 'wsemi/src/iseobj.mjs'
407
+ import j2o from 'wsemi/src/j2o.mjs'
408
+ import timemsTZ2day from 'wsemi/src/timemsTZ2day.mjs'
409
+ import convertToTree from 'wsemi/src/convertToTree.mjs'
410
+ import WButtonCircle from 'w-component-vue/src/components/WButtonCircle.vue'
411
+ import WGroupRadio from 'w-component-vue/src/components/WGroupRadio.vue'
412
+ import WDrawer from 'w-component-vue/src/components/WDrawer.vue'
413
+ import WTree from 'w-component-vue/src/components/WTree.vue'
414
+ import WJsonView from 'w-component-vue/src/components/WJsonView.vue'
415
+ import MdPanel from './MdPanel.vue'
34
416
 
35
417
 
36
418
  export default {
37
419
  components: {
38
- // WPanelBulge,
39
- // WButtonChip,
40
- // WGroupCheck,
41
- // WTree,
42
- LayoutContentList,
420
+ WButtonCircle,
421
+ WGroupRadio,
422
+ WDrawer,
423
+ WTree,
424
+ WJsonView,
425
+ MdPanel,
43
426
  },
44
427
  props: {
45
428
  },
46
429
  data: function() {
47
430
  return {
431
+
432
+ panelWidth: 0,
433
+ panelWidthTemp: 0,
434
+ panelHeight: 0,
435
+
436
+ drawer: true,
437
+ drawerAfloat: false,
438
+ drawerWidth: 320,
439
+ drawerWidthMin: 200,
440
+ drawerWidthMax: 700,
441
+
442
+ lineHeightTree: 38,
443
+
444
+ apisTree: [],
445
+ kpApisTree: {},
446
+ apiActive: null,
447
+ apiSelect: null,
448
+
449
+ kpColorMethod: {
450
+ GET: '#7c2',
451
+ POST: '#68f',
452
+ PUT: '#f82',
453
+ DEL: '#f26',
454
+ },
455
+
456
+ optputMenuItemSelectId: 'tree',
457
+
48
458
  }
49
459
  },
50
460
  computed: {
@@ -53,11 +463,230 @@ export default {
53
463
  return get(this, '$store.state.syncState')
54
464
  },
55
465
 
466
+ apis: function() {
467
+ return get(this, '$store.state.apis')
468
+ },
469
+
470
+ changeApis: function() {
471
+ let vo = this
472
+ //trigger
473
+ let apis = vo.apis
474
+ vo.genTree(apis)
475
+ return ''
476
+ },
477
+
478
+ optputMenuItems: function() {
479
+ let vo = this
480
+ let ms = [
481
+ {
482
+ id: 'tree',
483
+ text: vo.$t('outputMenuTree'),
484
+ icon: 'mdi-vanity-light',
485
+ },
486
+ {
487
+ id: 'raw',
488
+ text: vo.$t('outputMenuRaw'),
489
+ icon: 'mdi-lan',
490
+ },
491
+ ]
492
+ return ms
493
+ },
494
+
495
+ optputMenuItemSelect: function() {
496
+ let vo = this
497
+ let r = find(vo.optputMenuItems, { id: vo.optputMenuItemSelectId })
498
+ // console.log(r)
499
+ return r
500
+ },
501
+
56
502
  },
57
503
  methods: {
504
+
505
+ resize: function(msg) {
506
+ // console.log('methods resize', msg)
507
+
508
+ let vo = this
509
+
510
+ //save
511
+ vo.panelWidth = msg.snew.clientWidth
512
+ vo.panelHeight = msg.snew.clientHeight
513
+ // console.log('vo.panelHeight', vo.panelHeight)
514
+
515
+ //modeResize
516
+ let modeResize = '' //寬度可能相同故得有預設空字串的種類
517
+ if (vo.panelWidth > vo.panelWidthTemp) {
518
+ modeResize = 'toLarge'
519
+ }
520
+ else if (vo.panelWidth < vo.panelWidthTemp) {
521
+ modeResize = 'toSmall'
522
+ }
523
+ // console.log('modeResize', modeResize, vo.panelWidth, vo.panelWidthTemp)
524
+
525
+ //drawer
526
+ if (vo.drawer && modeResize === 'toSmall' && vo.panelWidth < 1.7 * vo.drawerWidthMax) { //已開啟抽屜且為變窄時才偵測
527
+ vo.drawer = false
528
+ }
529
+ else if (!vo.drawer && modeResize === 'toLarge' && vo.panelWidth >= 1.7 * vo.drawerWidthMax) { //已隱藏抽屜且為變寬時才偵測
530
+ vo.drawer = true
531
+ }
532
+
533
+ //drawerAfloat
534
+ vo.drawerAfloat = vo.panelWidth < 1.7 * vo.drawerWidthMax
535
+
536
+ //save
537
+ vo.panelWidthTemp = vo.panelWidth
538
+
539
+ },
540
+
541
+ genTree: function () {
542
+ let vo = this
543
+
544
+ //default
545
+ vo.apisTree = []
546
+ vo.kpApisTree = {}
547
+
548
+ //cloneDeep
549
+ let apis = cloneDeep(vo.apis)
550
+ // console.log('apis', cloneDeep(apis))
551
+
552
+ //tr
553
+ let tr = {}
554
+ let kpTree = {}
555
+ each(apis, (v) => {
556
+
557
+ //id, levels
558
+ let id = v.id
559
+ let levels = `${v.levels}.${v.name}`
560
+
561
+ //save
562
+ kpTree[id] = v
563
+
564
+ //check
565
+ if (!isobj(get(tr, levels))) {
566
+ set(tr, levels, id)
567
+ }
568
+
569
+ })
570
+ // console.log('tr', cloneDeep(tr))
571
+ // console.log('kpTree', cloneDeep(kpTree))
572
+
573
+ //convertToTree, 由預處理tree物件轉成tree物件
574
+ let tree = convertToTree(tr, { bindRoot: '全部' })
575
+ // console.log('tree', cloneDeep(tree))
576
+
577
+ //apiSelect, 預先選定api項目, 非tree選單active物件, 因id由convertToTree轉換提供, 故不能直接算得active選單物件id
578
+ let apiSelect = get(apis, 0, null)
579
+ // console.log('apiSelect', cloneDeep(apiSelect))
580
+
581
+ //save
582
+ vo.apiSelect = apiSelect
583
+ vo.apisTree = tree
584
+ vo.kpApisTree = kpTree
585
+
586
+ },
587
+
588
+ getItemByKey: function(key) {
589
+ let vo = this
590
+ // let k = `kpApisTree.${key}`
591
+ // console.log('getItemByKey k', k)
592
+ let r = vo.kpApisTree[key]
593
+ // console.log('getItemByKey r', r, vo.kpApisTree)
594
+ return r
595
+ },
596
+
597
+ getMethod: function(item) {
598
+ // let vo = this
599
+ let method = get(item, 'method', '').toUpperCase()
600
+ return method
601
+ },
602
+
603
+ getMethodByKey: function(key) {
604
+ let vo = this
605
+ let item = vo.getItemByKey(key)
606
+ let method = get(item, 'method', '').toUpperCase()
607
+ return method
608
+ },
609
+
610
+ getMethodColor: function(item) {
611
+ let vo = this
612
+ let method = vo.getMethod(item)
613
+ let color = get(vo.kpColorMethod, method, '#888')
614
+ return color
615
+ },
616
+
617
+ getMethodColorByKey: function(key) {
618
+ let vo = this
619
+ let method = vo.getMethodByKey(key)
620
+ let color = get(vo.kpColorMethod, method, '#888')
621
+ return color
622
+ },
623
+
624
+ getDay: function(t) {
625
+ return timemsTZ2day(t)
626
+ },
627
+
628
+ getOutputJson: function(item) {
629
+ // let vo = this
630
+ let j = get(item, 'outputExample', '')
631
+ j = trim(j)
632
+ return j
633
+ },
634
+
635
+ getOutputJsonObj: function(item) {
636
+ // let vo = this
637
+ let j = this.getOutputJson(item)
638
+ // console.log(j)
639
+ let o = j2o(j)
640
+ return o
641
+ },
642
+
643
+ funActive: function(msg) {
644
+ let vo = this
645
+ let b = !Array.isArray(msg.item.children) //children非陣列代表沒有所屬節點
646
+ if (b) {
647
+ if (!iseobj(vo.apiActive)) { //偵測若沒有apiActive才初始化預先選擇之api項目, 非api完整資訊
648
+ let id = msg.item.id
649
+ vo.apiActive = { id }
650
+ // console.log('!iseobj(vo.apiActive)', vo.apiActive)
651
+ }
652
+ }
653
+ return b
654
+ },
655
+
656
+ changeOptputMenuItemSelect: function(msg) {
657
+ // console.log('changeOptputMenuItemSelect', msg)
658
+ let vo = this
659
+ vo.optputMenuItemSelectId = msg.id
660
+ },
661
+
662
+ ckItem: function(item) {
663
+ // console.log('ckItem', item)
664
+ let vo = this
665
+ vo.apiSelect = cloneDeep(item)
666
+ },
667
+
58
668
  }
59
669
  }
60
670
  </script>
61
671
 
62
672
  <style scoped>
673
+ .bk {
674
+ display:inline-block;
675
+ width:200px;
676
+ padding:0px 10px 10px 0px;
677
+ vertical-align:top;
678
+ }
679
+ .bk-title {
680
+ padding:3px;
681
+ font-size:0.8rem;
682
+ color:#888;
683
+ }
684
+ .bk-item {
685
+ padding:3px 5px;
686
+ font-size:0.9rem;
687
+ line-height:0.9rem;
688
+ border-radius:5px;
689
+ border:1px solid #ddd;
690
+ background:#fff;
691
+ }
63
692
  </style>