@mixd-id/web-scaffold 0.1.230406125 → 0.1.230406127

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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mixd-id/web-scaffold",
3
3
  "private": false,
4
- "version": "0.1.230406125",
4
+ "version": "0.1.230406127",
5
5
  "scripts": {
6
6
  "dev": "vite serve",
7
7
  "build": "vite build",
@@ -30,6 +30,7 @@ export default {
30
30
  type: [ String, Number ],
31
31
  default: "primary" // primary|secondary|outline, default:primary
32
32
  },
33
+
33
34
  },
34
35
 
35
36
  computed: {
@@ -46,6 +47,7 @@ export default {
46
47
  .filter(_ => _)
47
48
  .join(' ')
48
49
  },
50
+
49
51
  },
50
52
  }
51
53
  </script>
@@ -50,15 +50,19 @@
50
50
  export default{
51
51
 
52
52
  props: {
53
+
53
54
  state: Object,
55
+
54
56
  mode: {
55
57
  type: String,
56
58
  default: 'alert' // alert | confirm
57
59
  },
60
+
58
61
  text: {
59
62
  type: String,
60
63
  default: 'OK'
61
- }
64
+ },
65
+
62
66
  },
63
67
 
64
68
  computed: {
@@ -1,167 +1,209 @@
1
1
  <template>
2
- <div :class="$style.comp">
3
-
4
- <slot v-if="$slots.head" name="head"></slot>
5
- <div v-else class="flex flex-row items-center gap-4 px-6 md:px-0 py-4 md:py-0 bg-base-400 dark:bg-base-300 md:bg-transparent">
6
- <div class="flex-1 flex flex-row gap-6">
7
- <button type="button" ref="presetSelectorBtn"
8
- class="flex-1 md:flex-none flex flex-row gap-1 items-center text-left md:ml-2"
9
- @click="$refs.presetSelector.toggle($refs.presetSelectorBtn)">
10
- <h2 class="overflow-hidden whitespace-nowrap text-ellipsis">{{ preset.name }}</h2>
11
- <svg width="13" height="13" class="ml-1 relative top-[2px] fill-text hover:fill-primary" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"/></svg>
12
- </button>
13
-
14
- <ContextMenu ref="presetSelector">
15
- <div class="flex-1 flex flex-col gap-4 md:w-[270px] cursor-pointer p-6">
16
- <div class="pb-0 flex flex-row gap-4">
17
- <h4 class="flex-1">Select Preset</h4>
18
- <button type="button" class="text-primary" @click="openPreset">Settings</button>
2
+ <Suspense>
3
+ <div :class="$style.comp" v-if="configLoaded">
4
+
5
+ <slot v-if="$slots.head" name="head"></slot>
6
+ <div v-else :class="$style.toolbar">
7
+ <div class="flex-1 flex flex-row gap-6">
8
+ <button type="button" ref="presetSelectorBtn"
9
+ class="flex-1 md:flex-none flex flex-col text-left md:ml-2 leading-tight"
10
+ @click="$refs.presetSelector.toggle($refs.presetSelectorBtn)">
11
+ <small v-if="title" class="text-text-400 text-xs">{{ title }}</small>
12
+ <div class="flex flex-row items-center">
13
+ <h3 class="overflow-hidden whitespace-nowrap text-ellipsis">{{ preset.name }}</h3>
14
+ <svg width="13" height="13" class="ml-1 relative top-[2px] fill-text hover:fill-primary" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"/></svg>
19
15
  </div>
20
- <div class="border-text-50 border-[1px] divide-y divide-text-50 bg-base-400 rounded-lg overflow-hidden">
21
- <button type="button" v-for="(preset, idx) in config.presets"
22
- class="p-3 text-left hover:bg-primary hover:text-white block w-full"
23
- @click="selectPreset(idx)">
24
- {{ preset.name }}
25
- </button>
26
- </div>
27
- </div>
28
- </ContextMenu>
29
-
30
- <div class="absolute">
31
- <Modal ref="setting" width="680" height="560" position="bottom">
32
- <template #head>
33
- <div class="relative">
34
- <div class="absolute top-0 right-0 p-2 py-3">
35
- <button type="button" class="p-2" @click="$refs.setting.close()">
36
- <svg width="24" height="24" viewBox="0 0 24 24" class="fill-text-300 hover:fill-red-500" xmlns="http://www.w3.org/2000/svg">
37
- <path d="M6.53034 5.46965C6.23745 5.17676 5.76257 5.17676 5.46968 5.46965C5.17679 5.76255 5.17679 6.23742 5.46968 6.53031L10.9393 12L5.46967 17.4697C5.17678 17.7626 5.17678 18.2374 5.46967 18.5303C5.76256 18.8232 6.23744 18.8232 6.53033 18.5303L12 13.0606L17.4697 18.5303C17.7626 18.8232 18.2375 18.8232 18.5303 18.5303C18.8232 18.2374 18.8232 17.7626 18.5303 17.4697L13.0607 12L18.5303 6.53032C18.8232 6.23743 18.8232 5.76256 18.5303 5.46966C18.2374 5.17677 17.7626 5.17677 17.4697 5.46966L12 10.9393L6.53034 5.46965Z"/>
38
- </svg>
39
- </button>
40
- </div>
16
+ </button>
17
+
18
+ <ContextMenu ref="presetSelector">
19
+ <div class="flex-1 flex flex-col gap-4 md:w-[270px] cursor-pointer p-6">
20
+ <div class="pb-0 flex flex-row gap-4">
21
+ <h4 class="flex-1">Select Preset</h4>
22
+ <button type="button" class="text-primary" @click="openPreset">Settings</button>
41
23
  </div>
42
- </template>
43
- <template #foot>
44
- <div class="p-6 py-4 border-t-[1px] border-text-50">
45
- <Button class="w-full md:w-[90px]" @click="applyPreset">Apply</Button>
24
+ <div class="border-text-50 border-[1px] divide-y divide-text-50 bg-base-400 rounded-lg overflow-hidden">
25
+ <button type="button" v-for="(preset, idx) in config.presets"
26
+ class="p-3 text-left hover:bg-primary hover:text-white block w-full"
27
+ @click="selectPreset(idx)">
28
+ {{ preset.name }}
29
+ </button>
46
30
  </div>
47
- </template>
48
- <ListViewSettings ref="listviewSettings" class="flex-1"
49
- :config="copiedConfig" />
50
- </Modal>
31
+ </div>
32
+ </ContextMenu>
33
+
34
+ <div class="absolute">
35
+ <Modal ref="setting" width="680" height="560" position="bottom">
36
+ <template #head>
37
+ <div class="relative">
38
+ <div class="absolute top-0 right-0 p-2 py-3">
39
+ <button type="button" class="p-2" @click="$refs.setting.close()">
40
+ <svg width="24" height="24" viewBox="0 0 24 24" class="fill-text-300 hover:fill-red-500" xmlns="http://www.w3.org/2000/svg">
41
+ <path d="M6.53034 5.46965C6.23745 5.17676 5.76257 5.17676 5.46968 5.46965C5.17679 5.76255 5.17679 6.23742 5.46968 6.53031L10.9393 12L5.46967 17.4697C5.17678 17.7626 5.17678 18.2374 5.46967 18.5303C5.76256 18.8232 6.23744 18.8232 6.53033 18.5303L12 13.0606L17.4697 18.5303C17.7626 18.8232 18.2375 18.8232 18.5303 18.5303C18.8232 18.2374 18.8232 17.7626 18.5303 17.4697L13.0607 12L18.5303 6.53032C18.8232 6.23743 18.8232 5.76256 18.5303 5.46966C18.2374 5.17677 17.7626 5.17677 17.4697 5.46966L12 10.9393L6.53034 5.46965Z"/>
42
+ </svg>
43
+ </button>
44
+ </div>
45
+ </div>
46
+ </template>
47
+ <template #foot>
48
+ <div class="p-6 py-4 border-t-[1px] border-text-50">
49
+ <Button class="w-full md:w-[90px]" @click="applyPreset">Apply</Button>
50
+ </div>
51
+ </template>
52
+ <ListViewSettings ref="listviewSettings" class="flex-1"
53
+ :config="copiedConfig" />
54
+ </Modal>
55
+ </div>
51
56
  </div>
52
- </div>
53
57
 
54
- <slot name="headerOpt"></slot>
58
+ <slot name="headerOpt"></slot>
55
59
 
56
- <Textbox v-if="mediaPrefix && mediaPrefix !== 'sm'" :placeholder="$t('Search...')" :clearable="true"
57
- @clear="clearSearch" v-model="preset.search"
58
- @keyup.enter="load" :class="$style.searchBox">
59
- <template #start>
60
- <div class="pl-2">
61
- <svg width="14" height="14" class="fill-text-300" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M508.5 481.6l-129-129c-2.3-2.3-5.3-3.5-8.5-3.5h-10.3C395 312 416 262.5 416 208 416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c54.5 0 104-21 141.1-55.2V371c0 3.2 1.3 6.2 3.5 8.5l129 129c4.7 4.7 12.3 4.7 17 0l9.9-9.9c4.7-4.7 4.7-12.3 0-17zM208 384c-97.3 0-176-78.7-176-176S110.7 32 208 32s176 78.7 176 176-78.7 176-176 176z"/></svg>
62
- </div>
63
- </template>
64
- </Textbox>
65
- </div>
60
+ <Textbox v-if="$screenPrefix.value !== ''" :placeholder="$t('Search...')" :clearable="true"
61
+ @clear="clearSearch" v-model="preset.search"
62
+ @keyup.enter="load" :class="$style.searchBox">
63
+ <template #start>
64
+ <div class="pl-2">
65
+ <svg width="14" height="14" class="fill-text-300" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M508.5 481.6l-129-129c-2.3-2.3-5.3-3.5-8.5-3.5h-10.3C395 312 416 262.5 416 208 416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c54.5 0 104-21 141.1-55.2V371c0 3.2 1.3 6.2 3.5 8.5l129 129c4.7 4.7 12.3 4.7 17 0l9.9-9.9c4.7-4.7 4.7-12.3 0-17zM208 384c-97.3 0-176-78.7-176-176S110.7 32 208 32s176 78.7 176 176-78.7 176-176 176z"/></svg>
66
+ </div>
67
+ </template>
68
+ </Textbox>
69
+
70
+ <div v-if="$screenPrefix.value !== ''">
71
+ <button type="button" class="p-2" @click="changeViewType('grid')" v-tooltip="'Grid'">
72
+ <svg width="16" height="16" :class="computedViewType === 'grid' ? 'fill-primary' : 'fill-text-300 hover:fill-primary'" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M496 424H304a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16h192a16 16 0 0 0 16-16v-16a16 16 0 0 0-16-16zm0-128H304a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16h192a16 16 0 0 0 16-16v-16a16 16 0 0 0-16-16zm0-128H304a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16h192a16 16 0 0 0 16-16v-16a16 16 0 0 0-16-16zm0-128H304a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16h192a16 16 0 0 0 16-16V56a16 16 0 0 0-16-16zM208 296H16a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16h192a16 16 0 0 0 16-16v-16a16 16 0 0 0-16-16zm0 128H16a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16h192a16 16 0 0 0 16-16v-16a16 16 0 0 0-16-16zm0-384H16A16 16 0 0 0 0 56v16a16 16 0 0 0 16 16h192a16 16 0 0 0 16-16V56a16 16 0 0 0-16-16zm0 128H16a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16h192a16 16 0 0 0 16-16v-16a16 16 0 0 0-16-16z"/></svg>
73
+ </button>
74
+ <button type="button" class="p-2" @click="changeViewType('table')" v-tooltip="'Table'">
75
+ <svg width="16" height="16" :class="computedViewType === 'table' ? 'fill-primary' : 'fill-text-300 hover:fill-primary'" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M464 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM232 432H54a6 6 0 0 1-6-6V296h184v136zm0-184H48V112h184v136zm226 184H280V296h184v130a6 6 0 0 1-6 6zm6-184H280V112h184v136z"/></svg>
76
+ </button>
77
+ </div>
78
+ </div>
66
79
 
67
- <div v-if="mediaPrefix && mediaPrefix === 'sm'" class="px-6 pb-4 border-b-[1px] border-text-50 bg-base-400 dark:bg-base-300">
68
- <Textbox :placeholder="$t('Search...')" :clearable="true" @clear="clearSearch" v-model="preset.search"
69
- @keyup.enter="load" :class="$style.searchBox2">
70
- <template #start>
71
- <div class="pl-2">
72
- <svg width="14" height="14" class="fill-text-300" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M508.5 481.6l-129-129c-2.3-2.3-5.3-3.5-8.5-3.5h-10.3C395 312 416 262.5 416 208 416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c54.5 0 104-21 141.1-55.2V371c0 3.2 1.3 6.2 3.5 8.5l129 129c4.7 4.7 12.3 4.7 17 0l9.9-9.9c4.7-4.7 4.7-12.3 0-17zM208 384c-97.3 0-176-78.7-176-176S110.7 32 208 32s176 78.7 176 176-78.7 176-176 176z"/></svg>
73
- </div>
74
- </template>
75
- </Textbox>
76
- </div>
80
+ <div v-if="$screenPrefix.value === ''" class="px-6 pb-4 border-b-[1px] border-text-50 bg-base-400 dark:bg-base-300">
81
+ <Textbox :placeholder="$t('Search...')" :clearable="true" @clear="clearSearch" v-model="preset.search"
82
+ @keyup.enter="load" :class="$style.searchBox2">
83
+ <template #start>
84
+ <div class="pl-2">
85
+ <svg width="14" height="14" class="fill-text-300" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M508.5 481.6l-129-129c-2.3-2.3-5.3-3.5-8.5-3.5h-10.3C395 312 416 262.5 416 208 416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c54.5 0 104-21 141.1-55.2V371c0 3.2 1.3 6.2 3.5 8.5l129 129c4.7 4.7 12.3 4.7 17 0l9.9-9.9c4.7-4.7 4.7-12.3 0-17zM208 384c-97.3 0-176-78.7-176-176S110.7 32 208 32s176 78.7 176 176-78.7 176-176 176z"/></svg>
86
+ </div>
87
+ </template>
88
+ </Textbox>
89
+ </div>
77
90
 
78
- <div v-if="presetSummary && summary" class="h-[300px] max-h-[30vh] flex">
79
- <Bar v-if="presetSummary.mode === 'bar'" :data="chartData" :options="chartOptions" class="flex-1 w-full p-2"/>
80
- <Line v-else-if="presetSummary.mode === 'line'" :data="chartData" :options="chartOptions" class="flex-1 w-full p-2"/>
81
- <VirtualTable v-else-if="presetSummary.mode === 'table'" :items="summaryItems" :columns="summaryColumns" class="flex-1"></VirtualTable>
82
- <Gmaps v-else-if="presetSummary.mode === 'map'" :data="summary.items" :config="presetSummary.map"
83
- class="flex-1 w-full p-2" :apiKey="mapApiKey" />
84
- </div>
91
+ <div v-if="presetSummary && summary" class="h-[300px] max-h-[30vh] flex">
92
+ <Bar v-if="presetSummary.mode === 'bar'" :data="chartData" :options="chartOptions" class="flex-1 w-full p-2"/>
93
+ <Line v-else-if="presetSummary.mode === 'line'" :data="chartData" :options="chartOptions" class="flex-1 w-full p-2"/>
94
+ <VirtualTable v-else-if="presetSummary.mode === 'table'" :items="summaryItems" :columns="summaryColumns" class="flex-1"></VirtualTable>
95
+ <Gmaps v-else-if="presetSummary.mode === 'map'" :data="summary.items" :config="presetSummary.map"
96
+ class="flex-1 w-full p-2" :apiKey="mapApiKey" />
97
+ </div>
85
98
 
86
- <div class="flex-1 flex" v-if="mediaPrefix">
87
- <VirtualScroll v-if="mediaPrefix === 'sm'" :items="items" ref="table2"
88
- class="flex-1 bg-base-400 dark:bg-base-300" @scroll-end="loadNext">
89
- <template #item="{ item }">
90
- <slot name="mobileItem" :item="item"></slot>
91
- </template>
92
- </VirtualScroll>
93
-
94
- <VirtualTable v-else ref="table1" :columns="presetColumns" :items="items"
95
- class="flex-1 bg-base-400"
96
- @scroll-end="loadNext">
97
- <template v-for="column in presetColumns" #[colOf(column.key)]="{}">
98
- <div :class="getHeader(column)" @click="openColumnOptions(column.key, $event.target.closest('.' + $style.header))">
99
- <div>
100
- {{ column.label ?? column.key }}
101
- </div>
102
- <div class="absolute top-0 right-0 p-2 bg-base-500" v-if="presetSortedColumns[column.key] === 'asc'">
103
- <svg width="19" height="19" viewBox="0 0 24 24" class="fill-text-400" xmlns="http://www.w3.org/2000/svg">
104
- <path d="M6.75 5C6.75 4.58579 6.41421 4.25 6 4.25C5.58579 4.25 5.25 4.58579 5.25 5V17.6893L3.53033 15.9697C3.23744 15.6768 2.76256 15.6768 2.46967 15.9697C2.17678 16.2626 2.17678 16.7374 2.46967 17.0303L4.76256 19.3232C5.44598 20.0066 6.55402 20.0066 7.23744 19.3232L9.53033 17.0303C9.82322 16.7374 9.82322 16.2626 9.53033 15.9697C9.23744 15.6768 8.76256 15.6768 8.46967 15.9697L6.75 17.6893V5Z"/>
105
- <path fill-rule="evenodd" clip-rule="evenodd" d="M12.25 17C12.25 17.4142 12.5858 17.75 13 17.75H21C21.4142 17.75 21.75 17.4142 21.75 17C21.75 16.5858 21.4142 16.25 21 16.25H13C12.5858 16.25 12.25 16.5858 12.25 17Z"/>
106
- <path fill-rule="evenodd" clip-rule="evenodd" d="M12.25 12C12.25 11.5858 12.5858 11.25 13 11.25H18C18.4142 11.25 18.75 11.5858 18.75 12C18.75 12.4142 18.4142 12.75 18 12.75H13C12.5858 12.75 12.25 12.4142 12.25 12Z"/>
107
- <path fill-rule="evenodd" clip-rule="evenodd" d="M12.25 7C12.25 6.58579 12.5858 6.25 13 6.25H15C15.4142 6.25 15.75 6.58579 15.75 7C15.75 7.41421 15.4142 7.75 15 7.75H13C12.5858 7.75 12.25 7.41421 12.25 7Z"/>
108
- </svg>
99
+ <div class="flex-1 flex">
100
+ <VirtualScroll v-if="computedViewType === 'feed'"
101
+ :items="items"
102
+ ref="table1"
103
+ class="flex-1"
104
+ @scroll-end="loadNext">
105
+ <template #item="{ item }">
106
+ <slot name="mobileItem" :item="item">
107
+ <div :class="$style.mobileItem">
108
+ <strong>{{ item.name }}</strong>
109
+ </div>
110
+ </slot>
111
+ </template>
112
+ </VirtualScroll>
113
+
114
+ <VirtualGrid v-else-if="computedViewType === 'grid'"
115
+ :items="items"
116
+ :column="gridColumn"
117
+ :gap="gridGap"
118
+ class="flex-1"
119
+ ref="table1"
120
+ :opt-bar="optBar"
121
+ @scroll-end="loadNext"
122
+ :config="config">
123
+ <template #item="{ item }">
124
+ <slot name="gridItem" :item="item">
125
+ <div :class="$style.mobileItem">
126
+ <strong>{{ item.name }}</strong>
127
+ </div>
128
+ </slot>
129
+ </template>
130
+ </VirtualGrid>
131
+
132
+ <VirtualTable v-else-if="computedViewType === 'table'"
133
+ ref="table1"
134
+ :columns="presetColumns"
135
+ :items="items"
136
+ class="flex-1 bg-base-400"
137
+ @scroll-end="loadNext">
138
+ <template v-for="column in presetColumns" #[colOf(column.key)]="{}">
139
+ <div :class="getHeader(column)" @click="openColumnOptions(column.key, $event.target.closest('.' + $style.header))">
140
+ <div>
141
+ {{ column.label ?? column.key }}
142
+ </div>
143
+ <div class="absolute top-0 right-0 p-2 bg-base-500" v-if="presetSortedColumns[column.key] === 'asc'">
144
+ <svg width="19" height="19" viewBox="0 0 24 24" class="fill-text-400" xmlns="http://www.w3.org/2000/svg">
145
+ <path d="M6.75 5C6.75 4.58579 6.41421 4.25 6 4.25C5.58579 4.25 5.25 4.58579 5.25 5V17.6893L3.53033 15.9697C3.23744 15.6768 2.76256 15.6768 2.46967 15.9697C2.17678 16.2626 2.17678 16.7374 2.46967 17.0303L4.76256 19.3232C5.44598 20.0066 6.55402 20.0066 7.23744 19.3232L9.53033 17.0303C9.82322 16.7374 9.82322 16.2626 9.53033 15.9697C9.23744 15.6768 8.76256 15.6768 8.46967 15.9697L6.75 17.6893V5Z"/>
146
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M12.25 17C12.25 17.4142 12.5858 17.75 13 17.75H21C21.4142 17.75 21.75 17.4142 21.75 17C21.75 16.5858 21.4142 16.25 21 16.25H13C12.5858 16.25 12.25 16.5858 12.25 17Z"/>
147
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M12.25 12C12.25 11.5858 12.5858 11.25 13 11.25H18C18.4142 11.25 18.75 11.5858 18.75 12C18.75 12.4142 18.4142 12.75 18 12.75H13C12.5858 12.75 12.25 12.4142 12.25 12Z"/>
148
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M12.25 7C12.25 6.58579 12.5858 6.25 13 6.25H15C15.4142 6.25 15.75 6.58579 15.75 7C15.75 7.41421 15.4142 7.75 15 7.75H13C12.5858 7.75 12.25 7.41421 12.25 7Z"/>
149
+ </svg>
150
+ </div>
151
+ <div class="absolute top-0 right-0 p-2 bg-base-500" v-else-if="presetSortedColumns[column.key] === 'desc'">
152
+ <svg width="19" height="19" viewBox="0 0 24 24" class="fill-text-400" xmlns="http://www.w3.org/2000/svg">
153
+ <path d="M6.75 5C6.75 4.58579 6.41421 4.25 6 4.25C5.58579 4.25 5.25 4.58579 5.25 5V17.6893L3.53033 15.9697C3.23744 15.6768 2.76256 15.6768 2.46967 15.9697C2.17678 16.2626 2.17678 16.7374 2.46967 17.0303L4.76256 19.3232C5.44598 20.0066 6.55402 20.0066 7.23744 19.3232L9.53033 17.0303C9.82322 16.7374 9.82322 16.2626 9.53033 15.9697C9.23744 15.6768 8.76256 15.6768 8.46967 15.9697L6.75 17.6893V5Z"/>
154
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M12.25 7C12.25 6.58579 12.5858 6.25 13 6.25H21C21.4142 6.25 21.75 6.58579 21.75 7C21.75 7.41421 21.4142 7.75 21 7.75H13C12.5858 7.75 12.25 7.41421 12.25 7Z"/>
155
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M12.25 12C12.25 12.4142 12.5858 12.75 13 12.75H18C18.4142 12.75 18.75 12.4142 18.75 12C18.75 11.5858 18.4142 11.25 18 11.25H13C12.5858 11.25 12.25 11.5858 12.25 12Z"/>
156
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M12.25 17C12.25 17.4142 12.5858 17.75 13 17.75H15C15.4142 17.75 15.75 17.4142 15.75 17C15.75 16.5858 15.4142 16.25 15 16.25H13C12.5858 16.25 12.25 16.5858 12.25 17Z"/>
157
+ </svg>
158
+ </div>
109
159
  </div>
110
- <div class="absolute top-0 right-0 p-2 bg-base-500" v-else-if="presetSortedColumns[column.key] === 'desc'">
111
- <svg width="19" height="19" viewBox="0 0 24 24" class="fill-text-400" xmlns="http://www.w3.org/2000/svg">
112
- <path d="M6.75 5C6.75 4.58579 6.41421 4.25 6 4.25C5.58579 4.25 5.25 4.58579 5.25 5V17.6893L3.53033 15.9697C3.23744 15.6768 2.76256 15.6768 2.46967 15.9697C2.17678 16.2626 2.17678 16.7374 2.46967 17.0303L4.76256 19.3232C5.44598 20.0066 6.55402 20.0066 7.23744 19.3232L9.53033 17.0303C9.82322 16.7374 9.82322 16.2626 9.53033 15.9697C9.23744 15.6768 8.76256 15.6768 8.46967 15.9697L6.75 17.6893V5Z"/>
113
- <path fill-rule="evenodd" clip-rule="evenodd" d="M12.25 7C12.25 6.58579 12.5858 6.25 13 6.25H21C21.4142 6.25 21.75 6.58579 21.75 7C21.75 7.41421 21.4142 7.75 21 7.75H13C12.5858 7.75 12.25 7.41421 12.25 7Z"/>
114
- <path fill-rule="evenodd" clip-rule="evenodd" d="M12.25 12C12.25 12.4142 12.5858 12.75 13 12.75H18C18.4142 12.75 18.75 12.4142 18.75 12C18.75 11.5858 18.4142 11.25 18 11.25H13C12.5858 11.25 12.25 11.5858 12.25 12Z"/>
115
- <path fill-rule="evenodd" clip-rule="evenodd" d="M12.25 17C12.25 17.4142 12.5858 17.75 13 17.75H15C15.4142 17.75 15.75 17.4142 15.75 17C15.75 16.5858 15.4142 16.25 15 16.25H13C12.5858 16.25 12.25 16.5858 12.25 17Z"/>
116
- </svg>
160
+ </template>
161
+ <template v-for="(_, slot) in headerSlots" #[slot]="{ item, index }">
162
+ <div :class="getHeader(slot.replace('col-', ''))">
163
+ <slot :name="slot" :item="item" :index="index"></slot>
117
164
  </div>
118
- </div>
119
- </template>
120
- <template v-for="(_, slot) in headerSlots" #[slot]="{ item, index }">
121
- <div :class="getHeader(slot.replace('col-', ''))">
165
+ </template>
166
+ <template v-for="(_, slot) in contentSlots" #[slot]="{ item, index }">
122
167
  <slot :name="slot" :item="item" :index="index"></slot>
123
- </div>
124
- </template>
125
- <template v-for="(_, slot) in contentSlots" #[slot]="{ item, index }">
126
- <slot :name="slot" :item="item" :index="index"></slot>
127
- </template>
128
- </VirtualTable>
129
- </div>
168
+ </template>
169
+ </VirtualTable>
170
+ </div>
130
171
 
131
- <ContextMenu ref="columnMenu" :dismiss="false">
132
- <div class="flex-1 flex flex-col w-[270px] p-3">
133
- <div class="flex flex-col">
134
- <div class="flex flex-row gap-2 items-center">
135
- <div class="p-2 text-text-300 flex-1">Sort By</div>
136
- <div class="text-primary cursor-pointer text-sm" @click="openPreset('sort');$refs.columnMenu.close()">Sort Options</div>
137
- </div>
138
- <div class="p-2 cursor-pointer" :class="$style.hoverable" @click="setSortCurrent(1)">Sort Ascending</div>
139
- <div class="p-2 cursor-pointer" :class="$style.hoverable" @click="setSortCurrent(2)">Sort Descending</div>
140
- </div>
141
- <div class="h-[1px] bg-text-50 my-2"></div>
142
- <div class="flex flex-col">
143
- <div class="p-2 cursor-pointer" :class="$style.hoverable" @click="hide">Hide</div>
144
- <div class="p-2 cursor-pointer" :class="$style.hoverable" @click="openPreset();$refs.columnMenu.close()">Column Options</div>
145
- </div>
146
- <div class="h-[1px] bg-text-50 my-2"></div>
147
- <div class="flex flex-col">
148
- <div class="flex flex-row gap-2 items-center">
149
- <div class="p-2 text-text-300 flex-1">Filters</div>
150
- <div class="text-primary cursor-pointer text-sm" @click="openPreset('filter');$refs.columnMenu.close()">Filter Options</div>
172
+ <ContextMenu ref="columnMenu" :dismiss="false">
173
+ <div class="flex-1 flex flex-col w-[270px] p-3">
174
+ <div class="flex flex-col">
175
+ <div class="flex flex-row gap-2 items-center">
176
+ <div class="p-2 text-text-300 flex-1">Sort By</div>
177
+ <div class="text-primary cursor-pointer text-sm" @click="openPreset('sort');$refs.columnMenu.close()">Sort Options</div>
178
+ </div>
179
+ <div class="p-2 cursor-pointer" :class="$style.hoverable" @click="setSortCurrent(1)">Sort Ascending</div>
180
+ <div class="p-2 cursor-pointer" :class="$style.hoverable" @click="setSortCurrent(2)">Sort Descending</div>
151
181
  </div>
152
- <div v-if="presetCurrentFilters.length > 0">
153
- <ListPage1Filter v-if="preset.filters" v-for="filter in presetCurrentFilters"
154
- :filter="filter" :column="config.columns[config.columns.findIndex((_) => _.key === filter.key)]"
155
- @remove="removeFilter(filter)" @change="load" />
182
+ <div class="h-[1px] bg-text-50 my-2"></div>
183
+ <div class="flex flex-col">
184
+ <div class="p-2 cursor-pointer" :class="$style.hoverable" @click="hide">Hide</div>
185
+ <div class="p-2 cursor-pointer" :class="$style.hoverable" @click="openPreset();$refs.columnMenu.close()">Column Options</div>
156
186
  </div>
157
- <div v-else>
158
- <div class="p-2 cursor-pointer" :class="$style.hoverable" @click.stop="addCurrentFilter">Add Filter</div>
187
+ <div class="h-[1px] bg-text-50 my-2"></div>
188
+ <div class="flex flex-col">
189
+ <div class="flex flex-row gap-2 items-center">
190
+ <div class="p-2 text-text-300 flex-1">Filters</div>
191
+ <div class="text-primary cursor-pointer text-sm" @click="openPreset('filter');$refs.columnMenu.close()">Filter Options</div>
192
+ </div>
193
+ <div v-if="presetCurrentFilters.length > 0">
194
+ <ListPage1Filter v-if="preset.filters" v-for="filter in presetCurrentFilters"
195
+ :filter="filter" :column="config.columns[config.columns.findIndex((_) => _.key === filter.key)]"
196
+ @remove="removeFilter(filter)" @change="load" />
197
+ </div>
198
+ <div v-else>
199
+ <div class="p-2 cursor-pointer" :class="$style.hoverable" @click.stop="addCurrentFilter">Add Filter</div>
200
+ </div>
159
201
  </div>
160
202
  </div>
161
- </div>
162
- </ContextMenu>
203
+ </ContextMenu>
163
204
 
164
- </div>
205
+ </div>
206
+ </Suspense>
165
207
  </template>
166
208
 
167
209
  <script>
@@ -170,10 +212,9 @@ import throttle from "lodash/throttle";
170
212
  import { Bar, Line } from 'vue-chartjs'
171
213
  import Chart from 'chart.js/auto'
172
214
  import dayjs from "dayjs";
173
- import VirtualTable from "./VirtualTable.vue"
174
215
 
175
216
  export default{
176
- components: {Line, Bar, VirtualTable},
217
+ components: {Line, Bar},
177
218
 
178
219
  emits: [ ],
179
220
 
@@ -192,7 +233,11 @@ export default{
192
233
  configStore: String,
193
234
  subscription: String,
194
235
 
195
- title: String
236
+ title: String,
237
+
238
+ optBar: String,
239
+
240
+ containerClass: String
196
241
 
197
242
  },
198
243
 
@@ -256,6 +301,10 @@ export default{
256
301
  this.mediaPrefix = prefix
257
302
  },
258
303
 
304
+ changeViewType(type){
305
+ this.config.viewType = type
306
+ },
307
+
259
308
  clearSearch(){
260
309
  this.preset.search = ''
261
310
  this.load()
@@ -284,20 +333,27 @@ export default{
284
333
  async load(){
285
334
  if(!this.src) return
286
335
 
287
- this.$refs.table1 ? this.$refs.table1.setState(3) :
288
- (this.$refs.table2 ? this.$refs.table2.setState(3) : null)
289
- this.socketEmit2(this.src, { columns:this.config.columns, preset:this.preset })
336
+ this.$refs.table1 ? this.$refs.table1.setState(3) : null
337
+
338
+ let itemsPerPage = 16
339
+ switch(this.computedViewType){
340
+ case 'grid':
341
+ itemsPerPage *= this.gridColumn
342
+ break
343
+ case 'table':
344
+ itemsPerPage = 24
345
+ break
346
+ }
347
+
348
+ this.socketEmit2(this.src, { columns:this.config.columns, preset:this.preset, itemsPerPage })
290
349
  .then((res) => {
291
350
  Object.assign(this.$data, res)
292
351
  })
293
- .finally(() => {
294
- this.$refs.table1 ? this.$refs.table1.setState(1) :
295
- (this.$refs.table2 ? this.$refs.table2.setState(1) : null)
296
- })
352
+ .finally(() => this.$refs.table1 ? this.$refs.table1.resetState() : null)
297
353
  },
298
354
 
299
355
  loadNext(){
300
- this.$refs.table1 ? this.$refs.table1.setState(2) : this.$refs.table2.setState(2)
356
+ this.$refs.table1 ? this.$refs.table1.setState(2) : null
301
357
  this.socketEmit2(this.src, {
302
358
  preset: this.preset,
303
359
  afterItem: this.items[this.items.length - 1]
@@ -309,33 +365,27 @@ export default{
309
365
  .catch((err) => {
310
366
  this.toast(err)
311
367
  })
312
- .finally(() => {
313
- this.$refs.table1 ? this.$refs.table1.setState(1) : this.$refs.table2.setState(1)
314
- })
368
+ .finally(() => this.$refs.table1 ? this.$refs.table1.resetState() : null)
315
369
  },
316
370
 
317
371
  async loadConfig(){
318
-
319
372
  if(!this.configStoreObj || 'reset' in ((this.$route ?? {}).query ?? {})){
320
373
  this.configLoaded = true
321
-
322
374
  if('reset' in ((this.$route ?? {}).query ?? {}))
323
375
  await this.saveConfig()
324
-
325
- return
326
376
  }
327
-
328
- switch(this.configStoreObj.type){
329
- case 'socket':
330
- return this.socketEmit2(this.configStoreObj.src,
377
+ else{
378
+ switch(this.configStoreObj.type){
379
+ case 'socket':
380
+ return this.socketEmit2(this.configStoreObj.src,
331
381
  { key:this.configStoreObj.name ?? 'ListView' })
332
- .then((config) => {
333
- if(config && Array.isArray(config.columns)){
334
- Object.assign(this.config, config ?? {})
335
- }
336
-
337
- this.configLoaded = true
338
- })
382
+ .then((config) => {
383
+ if(config && Array.isArray(config.columns)){
384
+ Object.assign(this.config, config ?? {})
385
+ }
386
+ this.configLoaded = true
387
+ })
388
+ }
339
389
  }
340
390
  },
341
391
 
@@ -533,6 +583,17 @@ export default{
533
583
 
534
584
  computed: {
535
585
 
586
+ computedViewType(){
587
+ if(!this.config.viewType){
588
+ this.config.viewType = 'table'
589
+ }
590
+
591
+ if(this.$screenPrefix.value === ''){
592
+ return 'grid'
593
+ }
594
+
595
+ return this.config.viewType
596
+ },
536
597
 
537
598
  chartOptions(){
538
599
 
@@ -655,6 +716,30 @@ export default{
655
716
  }*/
656
717
  },
657
718
 
719
+ gridColumn(){
720
+ if(!this.config.gridColumn){
721
+ this.config.gridColumn = 3
722
+ }
723
+
724
+ if(this.$screenPrefix.value === ''){
725
+ return 1
726
+ }
727
+
728
+ return this.config.gridColumn
729
+ },
730
+
731
+ gridGap(){
732
+ if(!this.config.gridGap){
733
+ this.config.gridGap = 'gap-3'
734
+ }
735
+
736
+ if(this.$screenPrefix.value === ''){
737
+ return 'gap-1'
738
+ }
739
+
740
+ return this.config.gridGap
741
+ },
742
+
658
743
  subscriptionObj(){
659
744
  const splitted = ((this.subscription ?? '').toString()).split(':')
660
745
  const splitted2 = (splitted[1] ?? '').split(',')
@@ -835,6 +920,10 @@ export default{
835
920
  @apply flex-1 flex flex-col md:gap-4;
836
921
  }
837
922
 
923
+ .toolbar{
924
+ @apply flex flex-row items-center gap-4 px-6 md:px-0 py-4 md:py-0 bg-base-400 dark:bg-base-300 md:bg-transparent;
925
+ }
926
+
838
927
  .searchBox{
839
928
  @apply !bg-base-400 md:w-[300px];
840
929
  }
@@ -858,4 +947,8 @@ export default{
858
947
  @apply hover:bg-primary hover:text-white;
859
948
  }
860
949
 
950
+ .mobileItem{
951
+ @apply p-3 border-[1px] border-text-100 bg-base-300 rounded-lg;
952
+ }
953
+
861
954
  </style>
@@ -13,9 +13,13 @@ import { parseBoolean, uid } from "../utils/helpers.mjs"
13
13
  export default{
14
14
 
15
15
  props:{
16
- modelValue: [ String, Number, Boolean ],
16
+
17
+ modelValue: undefined,
18
+
17
19
  trueValue: undefined,
18
- falseValue: undefined
20
+
21
+ falseValue: undefined,
22
+
19
23
  },
20
24
 
21
25
  computed: {
@@ -86,4 +90,4 @@ export default{
86
90
  .switch>input:not(:checked) + label + * + *{
87
91
  @apply hidden;
88
92
  }
89
- </style>
93
+ </style>
@@ -89,7 +89,7 @@ export default{
89
89
  @apply border-[1px] border-primary rounded-xl;
90
90
  }
91
91
  .button>*{
92
- @apply p-[1px] px-2 m-[1px];
92
+ @apply p-[1px] px-2;
93
93
  }
94
94
  .button>*:first-child{
95
95
  @apply rounded-l-lg;
@@ -101,7 +101,7 @@ export default{
101
101
  @apply bg-primary text-text-500;
102
102
  }
103
103
  .button>*[class*="active"] *{
104
- @apply text-white;
104
+ @apply text-white fill-white;
105
105
  }
106
106
 
107
107
  </style>