@mptw/skylens-ui 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/.editorconfig +12 -0
  2. package/.eslintrc.cjs +4 -0
  3. package/.nuxtrc +1 -0
  4. package/.playground/app.config.ts +5 -0
  5. package/.playground/nuxt.config.ts +3 -0
  6. package/README.md +73 -0
  7. package/app.config.ts +5 -0
  8. package/app.vue +3 -0
  9. package/assets/css/fonts/MEShPlus-font-icon.eot +0 -0
  10. package/assets/css/fonts/MEShPlus-font-icon.svg +186 -0
  11. package/assets/css/fonts/MEShPlus-font-icon.ttf +0 -0
  12. package/assets/css/fonts/MEShPlus-font-icon.woff +0 -0
  13. package/assets/css/icons.css +555 -0
  14. package/assets/css/layout.styl +98 -0
  15. package/assets/css/tailwind.css +3 -0
  16. package/assets/images/commons/app-logo-white.png +0 -0
  17. package/assets/images/commons/app-logo.png +0 -0
  18. package/assets/images/commons/empty-box.png +0 -0
  19. package/assets/images/commons/watermark.svg +15 -0
  20. package/components/SLAlertModal.vue +99 -0
  21. package/components/SLBreadcrumbs.vue +42 -0
  22. package/components/SLButton.vue +301 -0
  23. package/components/SLCalendarButton.vue +259 -0
  24. package/components/SLCalendarPopup.vue +832 -0
  25. package/components/SLCard.vue +118 -0
  26. package/components/SLChart.vue +181 -0
  27. package/components/SLCheckbox.vue +179 -0
  28. package/components/SLCircleButton.vue +95 -0
  29. package/components/SLCollapsableBlock.vue +116 -0
  30. package/components/SLCollapsableMulitPillSelect.vue +92 -0
  31. package/components/SLConfirmModal.vue +122 -0
  32. package/components/SLDateInput.vue +460 -0
  33. package/components/SLDatePicker.vue +143 -0
  34. package/components/SLDistributor.vue +30 -0
  35. package/components/SLDownloadButton.vue +410 -0
  36. package/components/SLDraggable.vue +151 -0
  37. package/components/SLDropdown.vue +277 -0
  38. package/components/SLDropdownItem.vue +31 -0
  39. package/components/SLElementWithTitle.vue +181 -0
  40. package/components/SLEyeCheckbox.vue +162 -0
  41. package/components/SLFileInput.vue +101 -0
  42. package/components/SLGenderAgeSelect.vue +279 -0
  43. package/components/SLHeatMap.vue +151 -0
  44. package/components/SLHourRangeInput.vue +211 -0
  45. package/components/SLIOSSwitch.vue +235 -0
  46. package/components/SLIcon.vue +35 -0
  47. package/components/SLIconButton.vue +130 -0
  48. package/components/SLInfoTip.vue +221 -0
  49. package/components/SLInsightSitePage.vue +27 -0
  50. package/components/SLLegend.vue +76 -0
  51. package/components/SLLinearProgressBar.vue +35 -0
  52. package/components/SLLink.vue +162 -0
  53. package/components/SLLoading.vue +127 -0
  54. package/components/SLMapChart.vue +151 -0
  55. package/components/SLModal.vue +377 -0
  56. package/components/SLMonthCalendarButton.vue +378 -0
  57. package/components/SLMonthPicker.vue +151 -0
  58. package/components/SLMultiSelect.vue +121 -0
  59. package/components/SLNoData.vue +43 -0
  60. package/components/SLPageModal.vue +64 -0
  61. package/components/SLPagination.vue +192 -0
  62. package/components/SLPillCheckbox.vue +207 -0
  63. package/components/SLPillLabel.vue +101 -0
  64. package/components/SLPopupMenuButton.vue +158 -0
  65. package/components/SLProfileButton.vue +186 -0
  66. package/components/SLRadioButton.vue +97 -0
  67. package/components/SLRadioButtonGroup.vue +113 -0
  68. package/components/SLRadioGroup.vue +201 -0
  69. package/components/SLRangeInput.vue +209 -0
  70. package/components/SLRegionsMapChart.vue +151 -0
  71. package/components/SLRightSider.vue +242 -0
  72. package/components/SLSearchInput.vue +87 -0
  73. package/components/SLSelect.vue +545 -0
  74. package/components/SLSelectAllToggle.vue +118 -0
  75. package/components/SLSiderbarNav.vue +394 -0
  76. package/components/SLSiderbarNavItem.vue +204 -0
  77. package/components/SLSitePage.vue +96 -0
  78. package/components/SLSkyInsightSitePage.vue +27 -0
  79. package/components/SLSortByDropdown.vue +189 -0
  80. package/components/SLSpinIcon.vue +24 -0
  81. package/components/SLStayRangeInput.vue +306 -0
  82. package/components/SLTab.vue +159 -0
  83. package/components/SLTable.vue +409 -0
  84. package/components/SLTableTooltip.vue +111 -0
  85. package/components/SLTabs.vue +388 -0
  86. package/components/SLTextInput.vue +362 -0
  87. package/components/SLTextarea.vue +134 -0
  88. package/components/SLToast.vue +71 -0
  89. package/components/SLToggleButton.vue +78 -0
  90. package/components/SLTwoLayerMultiSelect.vue +428 -0
  91. package/components/SLTwoLayerSelect.vue +265 -0
  92. package/components/SLWarnModal.vue +75 -0
  93. package/interface/IDateRange.ts +5 -0
  94. package/interface/IHourRange.ts +4 -0
  95. package/interface/IInputOption.ts +6 -0
  96. package/interface/ILegendItem.ts +7 -0
  97. package/interface/IPopupMenuButton.ts +5 -0
  98. package/interface/IStayRange.ts +15 -0
  99. package/interface/ITableField.ts +19 -0
  100. package/interface/IWeb.ts +5 -0
  101. package/interface/NavConfigType.ts +14 -0
  102. package/interface/commons.ts +7 -0
  103. package/models/DateRange.ts +21 -0
  104. package/nuxt.config.ts +22 -0
  105. package/package.json +52 -0
  106. package/plugins/googlemaps.ts +17 -0
  107. package/plugins/v-calendar.ts +5 -0
  108. package/public/assets/files/taiwan-regions.json +7 -0
  109. package/public/assets/files/taiwan.json +24 -0
  110. package/public/assets/images/commons/default-favico.png +0 -0
  111. package/public/assets/images/dashboard/closure-button-icon.png +0 -0
  112. package/public/assets/images/dashboard/dashboard-widget-bar-chart-icon-disabled.png +0 -0
  113. package/public/assets/images/dashboard/dashboard-widget-bar-chart-icon-poi.png +0 -0
  114. package/public/assets/images/dashboard/dashboard-widget-bar-chart-icon-web.png +0 -0
  115. package/public/assets/images/dashboard/dashboard-widget-country-heatmap-chart-icon-disabled.png +0 -0
  116. package/public/assets/images/dashboard/dashboard-widget-country-heatmap-chart-icon.png +0 -0
  117. package/public/assets/images/dashboard/dashboard-widget-geo-list-icon-disabled.png +0 -0
  118. package/public/assets/images/dashboard/dashboard-widget-geo-list-icon-poi.png +0 -0
  119. package/public/assets/images/dashboard/dashboard-widget-geo-list-icon-web.png +0 -0
  120. package/public/assets/images/dashboard/dashboard-widget-heatmap-chart-icon-disabled.png +0 -0
  121. package/public/assets/images/dashboard/dashboard-widget-heatmap-chart-icon-web.png +0 -0
  122. package/public/assets/images/dashboard/dashboard-widget-line-chart-icon-disabled.png +0 -0
  123. package/public/assets/images/dashboard/dashboard-widget-line-chart-icon-poi.png +0 -0
  124. package/public/assets/images/dashboard/dashboard-widget-list-icon-disabled.png +0 -0
  125. package/public/assets/images/dashboard/dashboard-widget-list-icon-poi.png +0 -0
  126. package/public/assets/images/dashboard/dashboard-widget-list-icon-web.png +0 -0
  127. package/public/assets/images/dashboard/dashboard-widget-pie-chart-icon-disabled.png +0 -0
  128. package/public/assets/images/dashboard/dashboard-widget-pie-chart-icon-poi.png +0 -0
  129. package/public/assets/images/dashboard/dashboard-widget-pie-chart-icon-web.png +0 -0
  130. package/public/assets/images/dashboard/drag-hint-icon.svg +3 -0
  131. package/public/assets/images/dashboard/extend-button-icon.png +0 -0
  132. package/public/assets/images/dashboard/map-list-chart-icon.svg +17 -0
  133. package/public/assets/images/dashboard/map-marker-chart-icon.svg +32 -0
  134. package/public/assets/images/dashboard/pie-chart-icon.svg +4 -0
  135. package/public/assets/images/dashboard/poi-gender-age-chart-icon.svg +20 -0
  136. package/public/assets/images/dashboard/poi-nav-icon.png +0 -0
  137. package/public/assets/images/dashboard/web-gender-age-chart-icon.svg +20 -0
  138. package/public/assets/images/dashboard/web-nav-icon.png +0 -0
  139. package/tailwind.config.js +300 -0
  140. package/tsconfig.json +8 -0
  141. package/utils/constants.ts +160 -0
  142. package/utils/generateSheet.ts +36 -0
  143. package/utils/index.ts +539 -0
@@ -0,0 +1,394 @@
1
+ <template lang="pug">
2
+ .siderbar(:class="{ closure: isClosure, dark }")
3
+ .siderbar-modal(@click="onClickedToggle")
4
+ .siderbar-logo
5
+ a.logo(href="javascript:;" @click="onClickedLogo")
6
+ img.color(src="images/commons/app-logo.png")
7
+ img.white(src="images/commons/app-logo-white.png")
8
+ nav.site-nav
9
+ .nav-wrapper.custom-scrollbar-y
10
+ ul(v-if="firstConfig.length > 0")
11
+ SLSiderbarNavItem(
12
+ v-for="item, i in firstConfig"
13
+ :config="item"
14
+ :isSiderbarClosure="isClosure"
15
+ :key="i"
16
+ @toggle="onClickedToggle"
17
+ @click-item="onClickedItem"
18
+ )
19
+ nav.mng-nav
20
+ .nav-wrapper.custom-scrollbar-y
21
+ ul(v-if="secondConfig.length > 0")
22
+ SLSiderbarNavItem(
23
+ v-for="item, i in secondConfig"
24
+ :config="item"
25
+ :isSiderbarClosure="isClosure"
26
+ :key="i"
27
+ @toggle="onClickedToggle"
28
+ @click-item="onClickedItem"
29
+ )
30
+ .siderbar-mode-setting
31
+ .siderbar-mode-setting-title 模式
32
+ SLIOSSwitch(
33
+ :modelValue="dark"
34
+ trueLabel="深色"
35
+ minTrueLabel="深"
36
+ falseLabel="淺色"
37
+ minFalseLabel="淺"
38
+ :size="isClosure ? 'min' : ''"
39
+ @update:modelValue="onUpdatedMode"
40
+ )
41
+ a.siderbar-toggle(href="javascript:;", @click="onClickedToggle")
42
+ SLIcon(icon="chevron-left")
43
+ SLIcon(icon="chevron-right")
44
+ </template>
45
+
46
+ <script lang="ts">
47
+ import type { PropType } from "vue";
48
+ import type { NavConfigType } from "~ui/interface/NavConfigType";
49
+
50
+ export default defineComponent({
51
+ name: "SLSidebarNav",
52
+ props: {
53
+ dark: {
54
+ type: Boolean,
55
+ default: false,
56
+ },
57
+ firstConfig: {
58
+ type: Array as PropType<NavConfigType>,
59
+ default: () => [],
60
+ },
61
+ secondConfig: {
62
+ type: Array as PropType<NavConfigType>,
63
+ default: () => [],
64
+ },
65
+ },
66
+ emits: ["click:logo", "update:dark", "update:closure", "click:insight"],
67
+ setup(_, { emit }) {
68
+ const isClosure = ref(false);
69
+
70
+ function onClickedToggle() {
71
+ isClosure.value = !isClosure.value;
72
+ }
73
+
74
+ function onClickedLogo() {
75
+ emit("click:logo");
76
+ }
77
+
78
+ function onClickedItem(
79
+ eventName:
80
+ | "click:logo"
81
+ | "update:dark"
82
+ | "update:closure"
83
+ | "click:insight"
84
+ ) {
85
+ emit(eventName);
86
+ }
87
+
88
+ function onUpdatedMode(isDark: boolean) {
89
+ emit("update:dark", isDark);
90
+ }
91
+
92
+ watch(isClosure, () => {
93
+ emit("update:closure", isClosure.value);
94
+ });
95
+
96
+ return {
97
+ isClosure,
98
+ onClickedToggle,
99
+ onClickedLogo,
100
+ onClickedItem,
101
+ onUpdatedMode,
102
+ };
103
+ },
104
+ });
105
+ </script>
106
+
107
+ <style lang="stylus">
108
+ .siderbar
109
+ @apply relative flex flex-col h-full bg-white shadow transition-all
110
+ width 188px
111
+
112
+ &.dark
113
+ @apply bg-primary
114
+
115
+ &.closure
116
+ nav
117
+ .siderbar-nav-item
118
+ &.included
119
+ @apply text-primary-hover
120
+
121
+ & > .nav-item-container
122
+ .nav-item-wrapper
123
+ @apply bg-card-primary-light
124
+
125
+ .siderbar-toggle
126
+ &:hover
127
+ @apply bg-primary-lighter text-white
128
+
129
+ .siderbar-logo
130
+ .logo
131
+ img.color
132
+ @apply hidden
133
+
134
+ img.white
135
+ @apply block
136
+
137
+ nav
138
+ .nav-wrapper.custom-scrollbar-y
139
+ /* Handle */
140
+ &::-webkit-scrollbar-thumb
141
+ @apply bg-primary-hover
142
+
143
+ /* Handle on hover */
144
+ &::-webkit-scrollbar-thumb:hover
145
+ @apply bg-primary-hover
146
+
147
+ .siderbar-nav-item
148
+ @apply text-white
149
+
150
+ &.highlighted
151
+ @apply text-primary-hover
152
+
153
+ & > .nav-item-container
154
+ &:hover
155
+ .nav-item-wrapper
156
+ @apply bg-card-primary-light
157
+
158
+ .nav-item-wrapper
159
+ @apply bg-card-primary-light
160
+
161
+ .nav-item-container
162
+ &:hover
163
+ .nav-item-wrapper
164
+ @apply bg-primary-hover
165
+
166
+ .nav-item-wrapper
167
+ .nav-item-highlight-border
168
+ @apply bg-insight-hint-line
169
+
170
+ .siderbar-mode-setting
171
+ @apply text-white
172
+
173
+ .ios-switch
174
+ label
175
+ @apply border-primary-hover
176
+ background #2D2F57
177
+
178
+ &:before
179
+ @apply border-2 border-primary-hover bg-primary-lighter
180
+
181
+ .siderbar-toggle
182
+ @apply bg-primary-lighter text-white
183
+
184
+ &:hover
185
+ @apply bg-card-primary-light text-primary
186
+
187
+ &.closure
188
+ margin-left -188px
189
+
190
+ @media screen and (min-width: 1024px)
191
+ width 86px
192
+ margin-left 0
193
+
194
+ .siderbar-modal
195
+ @apply hidden
196
+
197
+ .siderbar-toggle
198
+ @apply bg-primary-hover text-white
199
+ margin-right -20px
200
+ border-radius 0px 12px 12px 0px
201
+
202
+ &:hover
203
+ @apply bg-primary-lighter text-white
204
+
205
+ .icon-chevron-left
206
+ @apply hidden
207
+
208
+ .icon-chevron-right
209
+ @apply inline-block
210
+
211
+ nav
212
+ .siderbar-nav-item
213
+ &.included
214
+ @apply text-white
215
+
216
+ & > .nav-item-container
217
+ .nav-item-wrapper
218
+ @apply bg-primary-hover
219
+
220
+ .nav-item-container
221
+ @apply rounded-r-full
222
+ width 37px
223
+
224
+ .nav-item-wrapper
225
+ @apply pl-0
226
+
227
+ .nav-item-button
228
+ .button-pre-icon
229
+ @apply text-lg
230
+ width 37px
231
+ height 37px
232
+
233
+ .button-title
234
+ @apply opacity-0
235
+
236
+ .nav-item-toggle
237
+ @apply opacity-0
238
+
239
+ .siderbar-mode-setting
240
+ @apply p-0 justify-center space-x-0
241
+
242
+ &-title
243
+ @apply hidden
244
+
245
+ .ios-switch
246
+ @apply flex-grow-0 flex-shrink-0
247
+
248
+ &-modal
249
+ @apply fixed top-0 left-0 w-full h-full bg-white opacity-0
250
+ @apply s('lg:hidden')
251
+
252
+ &-logo
253
+ @apply flex-grow-0 flex-shrink-0 relative flex justify-center py-5
254
+
255
+ .logo
256
+ @apply block
257
+
258
+ img.white
259
+ @apply hidden
260
+
261
+ nav + nav
262
+ @apply border-t border-primary-lighter
263
+
264
+ nav
265
+ @apply flex-grow relative flex flex-col overflow-hidden
266
+
267
+ &.mng-nav
268
+ @apply flex-grow-0 flex-shrink-0 pt-2 mt-auto
269
+
270
+ .nav-wrapper
271
+ @apply flex-grow
272
+
273
+ &.custom-scrollbar-y
274
+ @apply overflow-hidden s('hover:overflow-auto')
275
+
276
+ ul
277
+ @apply flex flex-col space-y-2
278
+
279
+ .siderbar-nav-item
280
+ @apply relative flex flex-col items-center w-full text-primary text-base
281
+
282
+ &.opened
283
+ .nav-item-toggle
284
+ @apply rotate-90
285
+
286
+ &.included
287
+ & > .nav-item-container
288
+ .nav-item-wrapper
289
+ .nav-item-button
290
+ .button-title
291
+ @apply font-bold
292
+
293
+ &.highlighted
294
+ @apply text-white
295
+
296
+ & > .nav-item-container
297
+ &:hover
298
+ .nav-item-wrapper
299
+ @apply bg-primary-hover
300
+
301
+ .nav-item-wrapper
302
+ @apply bg-primary-hover
303
+
304
+ .nav-item-button
305
+ .button-title
306
+ @apply font-bold
307
+
308
+ .nav-item-highlight-border
309
+ @apply opacity-100
310
+
311
+ &.disabled
312
+ .nav-item-wrapper
313
+ .nav-item-button
314
+ @apply cursor-default
315
+
316
+ .nav-item-toggle
317
+ @apply text-gray-4 cursor-default
318
+
319
+
320
+ .nav-item-container
321
+ @apply relative w-full rounded-l-full overflow-hidden transition-siderbar-nav-item
322
+ height 37px
323
+
324
+ &:hover
325
+ .nav-item-wrapper
326
+ @apply bg-bg
327
+
328
+ .nav-item-button
329
+ @apply font-bold
330
+
331
+ .nav-item-wrapper
332
+ @apply absolute top-0 left-0 flex items-center pl-4 transition-padding
333
+ width 188px
334
+ height 37px
335
+
336
+ .nav-item-button
337
+ @apply flex-grow flex items-center space-x-2
338
+
339
+ .button-pre-icon
340
+ @apply flex-shrink-0 flex-grow-0 flex items-center justify-center text-base leading-none transition-siderbar-nav-item-icon
341
+ width 16px
342
+ height 16px
343
+
344
+ .button-title
345
+ @apply flex-grow block truncate opacity-100 transition-opacity
346
+
347
+ .nav-item-toggle
348
+ @apply flex-grow-0 flex-shrink-0 inline-flex justify-center items-center w-5 h-5 mr-px text-xs leading-none opacity-100 origin-center transition-opacity
349
+
350
+ .nav-item-highlight-border
351
+ @apply flex-grow-0 flex-shrink-0 w-1 h-full bg-primary opacity-0
352
+
353
+ .sub-items-wrapper
354
+ @apply w-full h-0 pl-4 overflow-hidden transition-height
355
+
356
+ ul
357
+ @apply pt-2
358
+
359
+ .siderbar-nav-item
360
+ .nav-item-container
361
+ .nav-item-wrapper
362
+ @apply pl-6
363
+ width 172px
364
+
365
+ .siderbar-mode-setting
366
+ @apply flex items-center justify-start mt-6 mb-4 space-x-4 text-base text-primary
367
+ padding-right 10px
368
+ padding-left 40px
369
+
370
+ &-title
371
+ @apply flex-grow-0 flex-shrink-0
372
+
373
+ .ios-switch
374
+ @apply flex-grow
375
+
376
+ label
377
+ @apply border-bg bg-card-primary-light
378
+
379
+ &:before
380
+ @apply border-2 border-bg
381
+
382
+ &-toggle
383
+ @apply absolute top-0 right-0 flex justify-center items-center bg-bg-middle text-sm text-primary-light leading-none transition-all
384
+ width 20px
385
+ height 40px
386
+ margin-top 25px
387
+ border-radius 12px 0px 0px 12px
388
+
389
+ &:hover
390
+ @apply bg-primary-lighter text-white
391
+
392
+ .icon-chevron-right
393
+ @apply hidden
394
+ </style>
@@ -0,0 +1,204 @@
1
+ <template lang="pug">
2
+ li.siderbar-nav-item(:class="{ opened: isOpen, highlighted: isHighlight, included: isInclude, disabled: config && config.to === '' && config.subItems && config.subItems.length === 0 }")
3
+ .nav-item-container
4
+ .nav-item-wrapper
5
+ a(href="javascript:;", @click="onClickedItem").nav-item-button
6
+ .button-pre-icon(v-if="config && config.preIcon")
7
+ SLIcon(:icon="config.preIcon")
8
+ span.button-title {{ config ? config.title : '' }}
9
+ a.nav-item-toggle(
10
+ v-if="config && config.postIcon"
11
+ href="javascript:;"
12
+ @click="onClickedToggle"
13
+ )
14
+ SLIcon.button-post-icon(
15
+ :icon="config.postIcon"
16
+ )
17
+ .nav-item-highlight-border
18
+ .sub-items-wrapper(
19
+ v-if="config && config.subItems && config.subItems.length > 0"
20
+ :style="{ height: `${isOpen && !isSiderbarClosure ? subItemsWrapperHeight : 0}px` }"
21
+ )
22
+ ul(ref="subItemsUL")
23
+ SLSiderbarNavItem(
24
+ v-for="item, i in config.subItems"
25
+ :config="item"
26
+ :key="i"
27
+ )
28
+ </template>
29
+
30
+ <script lang="ts">
31
+ import type { PropType } from "vue";
32
+ import { fromEvent, interval, Subscription } from "rxjs";
33
+ import { debounce, startWith } from "rxjs/operators";
34
+ import type { NavItemConfigType } from "~ui/interface/NavConfigType";
35
+
36
+ function getConfigPaths(paths: string[], config: NavItemConfigType | null) {
37
+ if (!config) {
38
+ return paths;
39
+ }
40
+
41
+ let newPaths = [...paths];
42
+
43
+ if (config.subItems) {
44
+ config.subItems.forEach((itemConfig) => {
45
+ newPaths = getConfigPaths(newPaths, itemConfig);
46
+ });
47
+ }
48
+
49
+ if (config.to) {
50
+ newPaths.push(config.to);
51
+ }
52
+
53
+ if (config.include) {
54
+ newPaths.push(...config.include);
55
+ }
56
+
57
+ return newPaths;
58
+ }
59
+
60
+ export default defineComponent({
61
+ name: "SLSiderbarNavItem",
62
+ components: {},
63
+ props: {
64
+ config: {
65
+ type: Object as PropType<NavItemConfigType | null>,
66
+ default: () => null,
67
+ },
68
+ isSiderbarClosure: {
69
+ type: Boolean,
70
+ default: false,
71
+ },
72
+ },
73
+ emits: ["toggle", "click-item"],
74
+ setup(props, { emit }) {
75
+ const route = useRoute();
76
+ const router = useRouter();
77
+
78
+ const { config, isSiderbarClosure } = toRefs(props);
79
+
80
+ const subItemsUL = shallowRef<HTMLElement | null>(null);
81
+ const isOpen = ref(false);
82
+ const subItemsWrapperHeight = ref(0);
83
+
84
+ let resizeSubscriber: Subscription | null = null;
85
+
86
+ const configPaths = computed(() => {
87
+ return getConfigPaths([], config.value);
88
+ });
89
+
90
+ const isInclude = computed(() => {
91
+ let included = false;
92
+ const matched = route.matched[route.matched.length - 1];
93
+
94
+ configPaths.value.forEach((path) => {
95
+ const regex = new RegExp(`${path}(/)?$`);
96
+ if (regex.test(matched.path)) {
97
+ included = true;
98
+ }
99
+ });
100
+
101
+ return included;
102
+ });
103
+
104
+ const isHighlight = computed(() => {
105
+ if (!config.value?.to) return false;
106
+
107
+ const regex = new RegExp(`${config.value.to}(/)?$`);
108
+ const matched = route.matched[route.matched.length - 1];
109
+
110
+ return (
111
+ regex.test(matched.path) ||
112
+ ((config.value.subItems || []).length === 0 && isInclude.value)
113
+ );
114
+ });
115
+
116
+ function isDefaultOpen() {
117
+ let defaultOpen = false;
118
+
119
+ configPaths.value.forEach((path) => {
120
+ if (route.path.includes(path)) {
121
+ defaultOpen = true;
122
+ }
123
+ });
124
+
125
+ isOpen.value = defaultOpen;
126
+ }
127
+
128
+ function setSubItemsWrapperHeight() {
129
+ nextTick(() => {
130
+ if (subItemsUL.value) {
131
+ subItemsWrapperHeight.value =
132
+ subItemsUL.value.getBoundingClientRect().height;
133
+ }
134
+ });
135
+ }
136
+
137
+ function subscribeResize() {
138
+ resizeSubscriber = fromEvent(window, "resize")
139
+ .pipe(debounce(() => interval(500)))
140
+ .pipe(startWith(0))
141
+ .subscribe(setSubItemsWrapperHeight);
142
+ }
143
+
144
+ function unsubscribeResize() {
145
+ if (resizeSubscriber) {
146
+ resizeSubscriber.unsubscribe();
147
+ }
148
+ resizeSubscriber = null;
149
+ }
150
+
151
+ function onClickedItem() {
152
+ if (isSiderbarClosure.value) {
153
+ emit("toggle");
154
+ return;
155
+ }
156
+
157
+ isOpen.value = !isOpen.value;
158
+
159
+ if (config.value?.to && config.value?.to !== "") {
160
+ router.push(config.value.to);
161
+ return;
162
+ }
163
+
164
+ if (config.value?.emit && config.value?.emit !== "") {
165
+ emit("click-item", config.value.emit);
166
+ }
167
+ }
168
+
169
+ function onClickedToggle() {
170
+ isOpen.value = !isOpen.value;
171
+ }
172
+
173
+ watch(route, () => {
174
+ isDefaultOpen();
175
+ });
176
+
177
+ watch(config, () => {
178
+ setSubItemsWrapperHeight();
179
+ isDefaultOpen();
180
+ });
181
+
182
+ onMounted(() => {
183
+ isDefaultOpen();
184
+ subscribeResize();
185
+ });
186
+
187
+ onBeforeUnmount(() => {
188
+ unsubscribeResize();
189
+ });
190
+
191
+ return {
192
+ subItemsUL,
193
+ isOpen,
194
+ isHighlight,
195
+ isInclude,
196
+ subItemsWrapperHeight,
197
+ onClickedItem,
198
+ onClickedToggle,
199
+ };
200
+ },
201
+ });
202
+ </script>
203
+
204
+ <style lang="stylus"></style>
@@ -0,0 +1,96 @@
1
+ <template lang="pug">
2
+ .site-page
3
+ slot(name="site-page-header")
4
+ .site-page-header
5
+ .site-page-header-left
6
+ .site-page-header-left-top
7
+ #breadcrumbs
8
+ #site-page-datasources(
9
+ :style="`margin-left: ${dataSourcesMargin}px;`"
10
+ ref="dataSourcesTarget"
11
+ )
12
+ #site-page-header-left-bottom
13
+ .site-page-header-right
14
+ .site-page-notice(v-if="notice !== '' || $slots.notice")
15
+ slot(name="notice") {{ notice }}
16
+ .site-page-content
17
+ slot
18
+ .site-page-footer
19
+ slot(name='site-page-footer')
20
+ </template>
21
+
22
+ <script lang="ts">
23
+ export default defineComponent({
24
+ name: "SLSitePage",
25
+ components: {},
26
+ props: {
27
+ notice: {
28
+ type: String,
29
+ default: "",
30
+ },
31
+ },
32
+ setup() {
33
+ const dataSourcesTarget = shallowRef<HTMLElement | null>(null);
34
+ const dataSourcesMargin = ref(0);
35
+
36
+ let mutationObserver: MutationObserver | null = null;
37
+
38
+ function onDataSourcesTargetChange() {
39
+ nextTick(() => {
40
+ dataSourcesMargin.value =
41
+ dataSourcesTarget.value && dataSourcesTarget.value.children.length > 0
42
+ ? 16
43
+ : 0;
44
+ });
45
+ }
46
+
47
+ onMounted(() => {
48
+ if (dataSourcesTarget.value) {
49
+ mutationObserver = new MutationObserver(() => {
50
+ onDataSourcesTargetChange();
51
+ });
52
+ mutationObserver.observe(dataSourcesTarget.value, {
53
+ childList: true,
54
+ attributes: false,
55
+ characterData: false,
56
+ subtree: false,
57
+ });
58
+ }
59
+ });
60
+
61
+ onBeforeUnmount(() => {
62
+ if (mutationObserver) {
63
+ mutationObserver.disconnect();
64
+ }
65
+ mutationObserver = null;
66
+ });
67
+
68
+ return {
69
+ dataSourcesTarget,
70
+ dataSourcesMargin,
71
+ onDataSourcesTargetChange,
72
+ };
73
+ },
74
+ });
75
+ </script>
76
+
77
+ <style lang="stylus">
78
+ .site-page
79
+ @apply flex flex-col w-full min-h-full pt-1
80
+
81
+ &-header
82
+ @apply flex justify-between mb-4
83
+
84
+ &-left
85
+ &-top
86
+ @apply flex items-center justify-start
87
+
88
+ #site-page-header-left-bottom
89
+ @apply flex mt-2
90
+
91
+ &-notice
92
+ @apply mb-4 pl-2 pr-20 py-3 s('bg-[#FBFCFF]') rounded-lg text-sm text-gray-2
93
+
94
+ &-content
95
+ @apply flex flex-col flex-grow w-full px-4 pt-4 pb-8 rounded-lg bg-white
96
+ </style>
@@ -0,0 +1,27 @@
1
+ <template lang="pug">
2
+ .sky-insight-site-page
3
+ .sky-insight-site-page-header(v-if="$slots['site-page-header']")
4
+ slot(name="site-page-header")
5
+ .sky-insight-site-page-content
6
+ slot
7
+ </template>
8
+
9
+ <script>
10
+ export default {
11
+ name: 'SkyInsightSitePage',
12
+ props: {},
13
+ computed: {},
14
+ methods: {},
15
+ };
16
+ </script>
17
+
18
+ <style lang="stylus">
19
+ .sky-insight-site-page
20
+ @apply flex-grow flex flex-col
21
+
22
+ &-header
23
+ @apply s('-mx-4')
24
+
25
+ &-content
26
+ @apply flex flex-col flex-grow w-full p-4 rounded bg-bg-middle
27
+ </style>