@mptw/skylens-ui 1.3.15 → 1.4.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.
- package/components/SLNotification.vue +151 -0
- package/components/SLTabs.vue +379 -377
- package/package.json +1 -1
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
<template lang="pug">
|
|
2
|
+
Transition(
|
|
3
|
+
@before-enter='onBeforeEnter',
|
|
4
|
+
@enter='onEnter',
|
|
5
|
+
@after-enter='onAfterEnter',
|
|
6
|
+
@enter-cancelled='onAfterEnter',
|
|
7
|
+
@before-leave='onBeforeLeave',
|
|
8
|
+
@leave='onLeave',
|
|
9
|
+
@after-leave='onAfterLeave',
|
|
10
|
+
@leave-cancelled='onAfterLeave',
|
|
11
|
+
)
|
|
12
|
+
.notification(v-if='isShow')
|
|
13
|
+
.notification-wrapper {{ content }}
|
|
14
|
+
</template>
|
|
15
|
+
|
|
16
|
+
<script lang="ts">
|
|
17
|
+
import gsap from 'gsap';
|
|
18
|
+
|
|
19
|
+
export default defineComponent({
|
|
20
|
+
name: 'SLNotification',
|
|
21
|
+
props: {
|
|
22
|
+
isShow: {
|
|
23
|
+
type: Boolean,
|
|
24
|
+
default: false,
|
|
25
|
+
},
|
|
26
|
+
content: {
|
|
27
|
+
type: String,
|
|
28
|
+
default: '',
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
emits: ['update:isShow'],
|
|
32
|
+
setup(props, { emit }) {
|
|
33
|
+
const { isShow } = toRefs(props);
|
|
34
|
+
|
|
35
|
+
let timeoutId: any = null;
|
|
36
|
+
|
|
37
|
+
function onBeforeEnter(el: Element) {
|
|
38
|
+
const wrapperEl = el.querySelector('.notification-wrapper');
|
|
39
|
+
|
|
40
|
+
if (wrapperEl) {
|
|
41
|
+
gsap.set(wrapperEl, {
|
|
42
|
+
alpha: 0
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function onEnter(el: Element, done: () => void) {
|
|
48
|
+
const wrapperEl = el.querySelector('.notification-wrapper');
|
|
49
|
+
|
|
50
|
+
if (wrapperEl) {
|
|
51
|
+
gsap.to(wrapperEl, {
|
|
52
|
+
alpha: 1,
|
|
53
|
+
duration: 0.3,
|
|
54
|
+
onComplete: () => {
|
|
55
|
+
done();
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
} else {
|
|
59
|
+
done();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function onAfterEnter(el: Element) {
|
|
64
|
+
const wrapperEl = el.querySelector('.notification-wrapper');
|
|
65
|
+
|
|
66
|
+
if (wrapperEl) {
|
|
67
|
+
gsap.set(wrapperEl, {
|
|
68
|
+
alpha: 1
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function onBeforeLeave(el: Element) {
|
|
74
|
+
const wrapperEl = el.querySelector('.notification-wrapper');
|
|
75
|
+
|
|
76
|
+
if (wrapperEl) {
|
|
77
|
+
gsap.set(wrapperEl, {
|
|
78
|
+
alpha: 1
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function onLeave(el: Element, done: () => void) {
|
|
84
|
+
const wrapperEl = el.querySelector('.notification-wrapper');
|
|
85
|
+
|
|
86
|
+
if (wrapperEl) {
|
|
87
|
+
gsap.to(wrapperEl, {
|
|
88
|
+
alpha: 0,
|
|
89
|
+
duration: 0.3,
|
|
90
|
+
onComplete: () => {
|
|
91
|
+
done();
|
|
92
|
+
}
|
|
93
|
+
})
|
|
94
|
+
} else {
|
|
95
|
+
done();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function onAfterLeave(el: Element) {
|
|
100
|
+
const wrapperEl = el.querySelector('.notification-wrapper');
|
|
101
|
+
|
|
102
|
+
if (wrapperEl) {
|
|
103
|
+
gsap.set(wrapperEl, {
|
|
104
|
+
alpha: 0
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function delayHide() {
|
|
110
|
+
if (timeoutId) {
|
|
111
|
+
clearTimeout(timeoutId);
|
|
112
|
+
}
|
|
113
|
+
timeoutId = null;
|
|
114
|
+
|
|
115
|
+
timeoutId = setTimeout(() => {
|
|
116
|
+
emit('update:isShow', false);
|
|
117
|
+
}, 2000);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
watch(isShow, () => {
|
|
121
|
+
if (isShow.value) {
|
|
122
|
+
delayHide();
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
onBeforeUnmount(() => {
|
|
127
|
+
if (timeoutId) {
|
|
128
|
+
clearTimeout(timeoutId);
|
|
129
|
+
}
|
|
130
|
+
timeoutId = null;
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
return {
|
|
134
|
+
onBeforeEnter,
|
|
135
|
+
onEnter,
|
|
136
|
+
onAfterEnter,
|
|
137
|
+
onBeforeLeave,
|
|
138
|
+
onLeave,
|
|
139
|
+
onAfterLeave,
|
|
140
|
+
};
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
</script>
|
|
144
|
+
|
|
145
|
+
<style lang="stylus">
|
|
146
|
+
.notification
|
|
147
|
+
@apply s('z-[100]') fixed top-0 left-0 w-full h-full pointer-events-none
|
|
148
|
+
|
|
149
|
+
&-wrapper
|
|
150
|
+
@apply absolute s('top-1/2') s('left-1/2') p-4 s('bg-backdrop/80') rounded text-base text-white s('-translate-x-1/2') s('-translate-y-1/2') shadow-popup-sm
|
|
151
|
+
</style>
|
package/components/SLTabs.vue
CHANGED
|
@@ -1,428 +1,430 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
a(href='javascript:;')
|
|
14
|
-
SLIcon(icon='book')
|
|
15
|
-
span 單元導覽
|
|
16
|
-
.site-page-actions
|
|
17
|
-
SLButton(title='新增受眾包', post-icon='chevron-right', color='primary' class='create-btn')
|
|
18
|
-
.site-page-header-right
|
|
19
|
-
img(src='~/assets/images/m03/02p/m0302p-page-logo.svg')
|
|
20
|
-
SLNewTabs(:type='5')
|
|
21
|
-
template(#tabs-nav-right)
|
|
22
|
-
.inline-flex.items-center.space-x-4
|
|
23
|
-
SLSearchInput(
|
|
24
|
-
size='sm',
|
|
25
|
-
placeholder='搜尋標題名稱(部分字元即可)',
|
|
26
|
-
class='m0302p-search-input'
|
|
27
|
-
)
|
|
28
|
-
SLTab(title='受眾列表 (125)')
|
|
29
|
-
SLCard.audience-package-card
|
|
30
|
-
.audience-package
|
|
31
|
-
.audience-package-header
|
|
32
|
-
.header-left
|
|
33
|
-
SLButton(
|
|
34
|
-
title='新增受眾包',
|
|
35
|
-
color='primary',
|
|
36
|
-
size='lg',
|
|
37
|
-
@click='onClickedAdd'
|
|
38
|
-
)
|
|
39
|
-
.header-right
|
|
40
|
-
SLPagination(
|
|
41
|
-
v-if='totalCount > 0',
|
|
42
|
-
:total='totalCount',
|
|
43
|
-
:perPage='perPage',
|
|
44
|
-
:page='currentPage',
|
|
45
|
-
:showInfo='true'
|
|
46
|
-
@update:perPage='onUpdatedPerPage'
|
|
47
|
-
@update:page='onUpdatedPage'
|
|
48
|
-
)
|
|
49
|
-
.audience-package-body
|
|
50
|
-
template(v-if='tasks.length > 0')
|
|
51
|
-
ModuleM12AudiencePackageListItem(
|
|
52
|
-
v-for='task in tasks',
|
|
53
|
-
:task='task',
|
|
54
|
-
:key='task.id',
|
|
55
|
-
@delete='onClickedDelete',
|
|
56
|
-
@repack='onClickedRepack'
|
|
57
|
-
)
|
|
58
|
-
template(v-else) 沒有任何受眾包
|
|
59
|
-
.audience-package-footer
|
|
60
|
-
SLPagination(
|
|
61
|
-
v-if='totalCount > 0',
|
|
62
|
-
:total='totalCount',
|
|
63
|
-
:perPage='perPage',
|
|
64
|
-
:page='currentPage',
|
|
65
|
-
:showInfo='true'
|
|
66
|
-
@update:perPage='onUpdatedPerPage'
|
|
67
|
-
@update:page='onUpdatedPage'
|
|
68
|
-
)
|
|
69
|
-
SLTab(title='投放 (125)')
|
|
70
|
-
ClientOnly
|
|
71
|
-
Teleport(to="#popup")
|
|
72
|
-
SLConfirmModal(
|
|
73
|
-
v-model:show='isShowDeleteConfirmModal',
|
|
74
|
-
title='刪除受眾包',
|
|
75
|
-
confirmButtonTitle='刪除',
|
|
76
|
-
confirmButtonColor='danger',
|
|
77
|
-
confirmButtonVariant='',
|
|
78
|
-
modalClass='m12-delete-confirm-modal',
|
|
79
|
-
@confirm='onDeleteApply',
|
|
80
|
-
data-cy="delete-confirm-modal"
|
|
2
|
+
.tabs(:class='tabsClass')
|
|
3
|
+
.tabs-nav(
|
|
4
|
+
v-show="!tabItemsOversize"
|
|
5
|
+
:class="{ show: !tabItemsOversize }"
|
|
6
|
+
)
|
|
7
|
+
.tabs-nav-left(ref='tabsNavLeftEl')
|
|
8
|
+
SLDistributor(
|
|
9
|
+
tag='ul',
|
|
10
|
+
:header='true',
|
|
11
|
+
:changeTabTo='changeTabTo',
|
|
12
|
+
ref='navComp'
|
|
81
13
|
)
|
|
82
|
-
|
|
83
|
-
|
|
14
|
+
slot
|
|
15
|
+
.tabs-nav-right(v-if='(type === 1 || type === 5) && $slots["tabs-nav-right"]')
|
|
16
|
+
slot(name='tabs-nav-right')
|
|
17
|
+
.tabs-content
|
|
18
|
+
SLDistributor
|
|
19
|
+
.tabs-content-header(v-show="tabItemsOversize")
|
|
20
|
+
.tabs-content-header-left
|
|
21
|
+
SLDropdown.tabs-dropdown(
|
|
22
|
+
:title='currentTab',
|
|
23
|
+
v-model:showDropdown='showDropdown',
|
|
24
|
+
:class='{ active: showDropdown }',
|
|
25
|
+
)
|
|
26
|
+
SLDropdownItem(
|
|
27
|
+
v-for='(tabTitle, i) in tabTitles',
|
|
28
|
+
:title='tabTitle',
|
|
29
|
+
:class='{ active: i === activeTabIndex }',
|
|
30
|
+
@click='onClickedTab(i)',
|
|
31
|
+
:key='`${tabTitle}-${i}`'
|
|
32
|
+
)
|
|
33
|
+
.tabs-content-header-right(v-if='$slots["tabs-nav-right"]')
|
|
34
|
+
slot(name='tabs-nav-right')
|
|
35
|
+
.tabs-content-body(ref='tabsContentBody')
|
|
36
|
+
slot
|
|
84
37
|
</template>
|
|
85
38
|
|
|
86
39
|
<script lang="ts">
|
|
87
|
-
import
|
|
88
|
-
import {
|
|
89
|
-
import
|
|
90
|
-
import useM12Store from '~/store/app/m12';
|
|
91
|
-
import DomainUnionSubset from '@/models/DomainUnionSubset';
|
|
92
|
-
import LatlonUnionSubset from '@/models/LatlonUnionSubset';
|
|
93
|
-
import type { IAudTaskResponse, IUnionSubsetSource } from '~/interface/IAudTask';
|
|
94
|
-
import type IAudTask from '~/interface/IAudTask';
|
|
95
|
-
import { AudTaskStatus, AudTaskCMType } from '~/interface/IAudTask';
|
|
96
|
-
|
|
97
|
-
const PER_PAGE = 10;
|
|
98
|
-
|
|
99
|
-
function normalizeTask(task: IAudTaskResponse): IAudTask {
|
|
100
|
-
let gender = '';
|
|
101
|
-
|
|
102
|
-
switch ((task.genders || [])[0]) {
|
|
103
|
-
case '0':
|
|
104
|
-
gender = '未知';
|
|
105
|
-
break;
|
|
106
|
-
case '1':
|
|
107
|
-
gender = '男性';
|
|
108
|
-
break;
|
|
109
|
-
case '2':
|
|
110
|
-
gender = '女性';
|
|
111
|
-
break;
|
|
112
|
-
case '3':
|
|
113
|
-
gender = '不限';
|
|
114
|
-
break;
|
|
115
|
-
default:
|
|
116
|
-
break;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
return {
|
|
120
|
-
id: task.task_id || '',
|
|
121
|
-
name: task.name || '',
|
|
122
|
-
status: task.status || AudTaskStatus.Run,
|
|
123
|
-
includeSets: JSON.parse(task.and || '[]').map((includeSets: Array<IUnionSubsetSource>) => {
|
|
124
|
-
return {
|
|
125
|
-
id: uniqueId(),
|
|
126
|
-
sets: includeSets
|
|
127
|
-
.map((includeSet) => {
|
|
128
|
-
if (includeSet.domains) {
|
|
129
|
-
return DomainUnionSubset.normalize(includeSet);
|
|
130
|
-
}
|
|
131
|
-
if (includeSet.pg_id) {
|
|
132
|
-
return LatlonUnionSubset.normalize(includeSet);
|
|
133
|
-
}
|
|
134
|
-
return null;
|
|
135
|
-
})
|
|
136
|
-
.filter((includeSet) => !!includeSet),
|
|
137
|
-
};
|
|
138
|
-
}),
|
|
139
|
-
differenceSets: JSON.parse(task.not || '[]').map((differenceSets: Array<IUnionSubsetSource>) => {
|
|
140
|
-
return {
|
|
141
|
-
id: uniqueId(),
|
|
142
|
-
sets: differenceSets
|
|
143
|
-
.map((differenceSet) => {
|
|
144
|
-
if (differenceSet.domains) {
|
|
145
|
-
return DomainUnionSubset.normalize(differenceSet);
|
|
146
|
-
}
|
|
147
|
-
if (differenceSet.pg_id) {
|
|
148
|
-
return LatlonUnionSubset.normalize(differenceSet);
|
|
149
|
-
}
|
|
150
|
-
return null;
|
|
151
|
-
})
|
|
152
|
-
.filter((differenceSet) => !!differenceSet),
|
|
153
|
-
};
|
|
154
|
-
}),
|
|
155
|
-
uuid: task.uuid || '',
|
|
156
|
-
steps: task.steps || [],
|
|
157
|
-
ages: (task.ages || []).map((age) => {
|
|
158
|
-
let name = '';
|
|
159
|
-
switch (age) {
|
|
160
|
-
case 'A':
|
|
161
|
-
name = '17以下';
|
|
162
|
-
break;
|
|
163
|
-
case 'B':
|
|
164
|
-
name = '18 - 24';
|
|
165
|
-
break;
|
|
166
|
-
case 'C':
|
|
167
|
-
name = '25 - 34';
|
|
168
|
-
break;
|
|
169
|
-
case 'D':
|
|
170
|
-
name = '35 - 44';
|
|
171
|
-
break;
|
|
172
|
-
case 'E':
|
|
173
|
-
name = '45 - 54';
|
|
174
|
-
break;
|
|
175
|
-
case 'F':
|
|
176
|
-
name = '55 - 64';
|
|
177
|
-
break;
|
|
178
|
-
case 'G':
|
|
179
|
-
name = '65 - 74';
|
|
180
|
-
break;
|
|
181
|
-
case 'H':
|
|
182
|
-
name = '75以上';
|
|
183
|
-
break;
|
|
184
|
-
default:
|
|
185
|
-
break;
|
|
186
|
-
}
|
|
40
|
+
import { fromEvent, interval, Subscription } from "rxjs";
|
|
41
|
+
import { debounce, startWith } from "rxjs/operators";
|
|
42
|
+
import { SLDistributor } from "#components";
|
|
187
43
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
44
|
+
type SLDistributorType = InstanceType<typeof SLDistributor>;
|
|
45
|
+
|
|
46
|
+
export default defineComponent({
|
|
47
|
+
name: "SLTabs",
|
|
48
|
+
components: {},
|
|
49
|
+
props: {
|
|
50
|
+
size: {
|
|
51
|
+
type: String,
|
|
52
|
+
default: "",
|
|
53
|
+
validator: (value: string) => ["", "xs", "sm"].includes(value),
|
|
196
54
|
},
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
55
|
+
navMode: {
|
|
56
|
+
type: String,
|
|
57
|
+
default: "",
|
|
58
|
+
},
|
|
59
|
+
type: {
|
|
60
|
+
type: Number,
|
|
61
|
+
default: 1,
|
|
62
|
+
validator: (value: number) => [1, 2, 3, 4, 5].includes(value),
|
|
63
|
+
},
|
|
64
|
+
activeTab: {
|
|
65
|
+
type: Number,
|
|
66
|
+
default: 0,
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
emits: ["update:activeTab"],
|
|
70
|
+
setup(props, { emit }) {
|
|
71
|
+
const { activeTab, size, type, navMode } = toRefs(props);
|
|
72
|
+
|
|
73
|
+
const tabsContentBody = shallowRef<HTMLElement | null>(null);
|
|
74
|
+
const tabsNavLeftEl = shallowRef<HTMLElement | null>(null);
|
|
75
|
+
const navComp = shallowRef<SLDistributorType | null>(null);
|
|
76
|
+
const activeTabIndex = ref(activeTab.value || 0);
|
|
77
|
+
const tabTitles = ref<Array<string>>([]);
|
|
78
|
+
const showDropdown = ref(false);
|
|
79
|
+
const tabItemsOversizeProxy = ref(false);
|
|
80
|
+
|
|
81
|
+
let observer: MutationObserver | null = null;
|
|
82
|
+
let resizeSubscriber: Subscription | null = null;
|
|
83
|
+
|
|
84
|
+
const tabsClass = computed(() => {
|
|
85
|
+
const classes: Array<string> = [`tabs-type-${type.value}`];
|
|
86
|
+
|
|
87
|
+
if (size.value !== "") {
|
|
88
|
+
classes.push(`tabs-${size.value}`);
|
|
210
89
|
}
|
|
211
|
-
const foundCM = (task.reports?.cm || []).find(
|
|
212
|
-
(reportsCM) => reportsCM.name === cm
|
|
213
|
-
);
|
|
214
90
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
91
|
+
return classes.join(" ");
|
|
92
|
+
});
|
|
93
|
+
const currentTab = computed(() => {
|
|
94
|
+
return tabTitles.value[activeTabIndex.value];
|
|
95
|
+
});
|
|
96
|
+
const tabItemsOversize = computed({
|
|
97
|
+
get: () => {
|
|
98
|
+
return (
|
|
99
|
+
type.value !== 4 &&
|
|
100
|
+
(tabItemsOversizeProxy.value || navMode.value === "dropdown")
|
|
101
|
+
);
|
|
102
|
+
},
|
|
103
|
+
set: (newValue: boolean) => {
|
|
104
|
+
tabItemsOversizeProxy.value = newValue;
|
|
105
|
+
},
|
|
106
|
+
});
|
|
219
107
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
108
|
+
provide("activeTab", readonly(activeTabIndex));
|
|
109
|
+
provide("initialTab", readonly(activeTab));
|
|
110
|
+
|
|
111
|
+
function caculateTabs() {
|
|
112
|
+
nextTick(() => {
|
|
113
|
+
const tabLinks =
|
|
114
|
+
navComp.value?.$el.querySelectorAll(".tab-nav-item-link");
|
|
115
|
+
const tabLinkTitles = [];
|
|
116
|
+
if (tabLinks) {
|
|
117
|
+
for (let i = 0; i < tabLinks.length; i += 1) {
|
|
118
|
+
tabLinkTitles.push((tabLinks[i] as HTMLElement).innerText);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
tabTitles.value = tabLinkTitles;
|
|
122
|
+
|
|
123
|
+
const tabsNavLeftRect = tabsNavLeftEl.value?.getBoundingClientRect();
|
|
124
|
+
const navRect = navComp.value?.$el?.getBoundingClientRect();
|
|
125
|
+
|
|
126
|
+
if (tabsNavLeftRect && navRect) {
|
|
127
|
+
tabItemsOversizeProxy.value = navRect.width > tabsNavLeftRect.width;
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
}
|
|
238
131
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
132
|
+
function changeTabTo(newTab: number) {
|
|
133
|
+
activeTabIndex.value = newTab;
|
|
134
|
+
emit("update:activeTab", newTab);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function onClickedTab(i: number) {
|
|
138
|
+
changeTabTo(i);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
watch(activeTab, () => {
|
|
142
|
+
activeTabIndex.value = activeTab.value || 0;
|
|
245
143
|
});
|
|
246
144
|
|
|
247
|
-
|
|
145
|
+
onMounted(() => {
|
|
146
|
+
resizeSubscriber = fromEvent(window, "resize")
|
|
147
|
+
.pipe(debounce(() => interval(500)))
|
|
148
|
+
.pipe(startWith(0))
|
|
149
|
+
.subscribe(() => {
|
|
150
|
+
caculateTabs();
|
|
151
|
+
});
|
|
248
152
|
|
|
249
|
-
|
|
250
|
-
|
|
153
|
+
if (navComp.value) {
|
|
154
|
+
observer = new MutationObserver(caculateTabs);
|
|
155
|
+
observer.observe(navComp.value.$el, {
|
|
156
|
+
characterData: true,
|
|
157
|
+
attributes: false,
|
|
158
|
+
childList: true,
|
|
159
|
+
subtree: true,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
});
|
|
251
163
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
164
|
+
onBeforeUnmount(() => {
|
|
165
|
+
if (resizeSubscriber) {
|
|
166
|
+
resizeSubscriber.unsubscribe();
|
|
167
|
+
}
|
|
168
|
+
if (observer) {
|
|
169
|
+
observer.disconnect();
|
|
170
|
+
}
|
|
171
|
+
resizeSubscriber = null;
|
|
172
|
+
observer = null;
|
|
173
|
+
});
|
|
259
174
|
|
|
260
|
-
|
|
175
|
+
return {
|
|
176
|
+
tabsContentBody,
|
|
177
|
+
tabsNavLeftEl,
|
|
178
|
+
navComp,
|
|
179
|
+
activeTabIndex,
|
|
180
|
+
tabTitles,
|
|
181
|
+
showDropdown,
|
|
182
|
+
tabItemsOversize,
|
|
183
|
+
tabsClass,
|
|
184
|
+
currentTab,
|
|
185
|
+
changeTabTo,
|
|
186
|
+
onClickedTab,
|
|
187
|
+
};
|
|
188
|
+
},
|
|
189
|
+
});
|
|
190
|
+
</script>
|
|
261
191
|
|
|
262
|
-
|
|
192
|
+
<style lang="stylus">
|
|
193
|
+
.tabs
|
|
194
|
+
&.tabs-sm
|
|
195
|
+
&.tabs-type-1
|
|
196
|
+
& > .tabs-nav
|
|
197
|
+
ul
|
|
198
|
+
.tab-nav-item
|
|
199
|
+
&-link
|
|
200
|
+
@apply text-sm
|
|
263
201
|
|
|
264
|
-
|
|
265
|
-
|
|
202
|
+
&.tabs-xs
|
|
203
|
+
&.tabs-type-1
|
|
204
|
+
& > .tabs-nav
|
|
205
|
+
ul
|
|
206
|
+
.tab-nav-item
|
|
207
|
+
&.active
|
|
208
|
+
&:before
|
|
209
|
+
@apply hidden
|
|
266
210
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
limit: perPage.value,
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
loading.value = false;
|
|
273
|
-
|
|
274
|
-
if (error) {
|
|
275
|
-
appStore.addAlert({
|
|
276
|
-
title: '錯誤',
|
|
277
|
-
color: 'danger',
|
|
278
|
-
message: error.message,
|
|
279
|
-
});
|
|
280
|
-
}
|
|
211
|
+
&-link
|
|
212
|
+
@apply s("py-0.75") text-base
|
|
281
213
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
214
|
+
&.tabs-type-1
|
|
215
|
+
& > .tabs-nav
|
|
216
|
+
@apply flex items-start justify-between h-0 space-x-8 overflow-hidden
|
|
217
|
+
@apply s('lg:space-x-30')
|
|
285
218
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
}
|
|
219
|
+
&.show
|
|
220
|
+
@apply h-auto s("-mb-1.5")
|
|
289
221
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
}
|
|
222
|
+
.tabs-nav-left
|
|
223
|
+
@apply flex-grow overflow-hidden
|
|
293
224
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
isShowDeleteConfirmModal.value = true;
|
|
297
|
-
}
|
|
225
|
+
.tabs-nav-right
|
|
226
|
+
@apply flex-grow-0 flex-shrink-0
|
|
298
227
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
if (!foundTask) return;
|
|
228
|
+
ul
|
|
229
|
+
@apply inline-flex items-start s("-space-x-px")
|
|
302
230
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
}
|
|
231
|
+
.tab-nav-item
|
|
232
|
+
@apply relative rounded-t bg-white
|
|
306
233
|
|
|
307
|
-
|
|
308
|
-
|
|
234
|
+
&:first-child
|
|
235
|
+
.tab-nav-item-link
|
|
236
|
+
&:after
|
|
237
|
+
content ""
|
|
238
|
+
@apply absolute bottom-0 left-0 w-px h-3 s("-mb-3") s("-ml-px") bg-border
|
|
309
239
|
|
|
310
|
-
|
|
240
|
+
&.active
|
|
241
|
+
@apply s("pb-1.75")
|
|
311
242
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
code: error.code,
|
|
316
|
-
message: error.message,
|
|
317
|
-
});
|
|
318
|
-
}
|
|
243
|
+
&:before
|
|
244
|
+
content ""
|
|
245
|
+
@apply block absolute s("top-0.5") s("right-0.75") s("left-0.75") h-1 bg-secondary-hover
|
|
319
246
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
}
|
|
323
|
-
fetch();
|
|
324
|
-
}
|
|
247
|
+
.tab-nav-item-link
|
|
248
|
+
@apply text-primary cursor-default
|
|
325
249
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
currentPage.value = 1;
|
|
329
|
-
fetch();
|
|
330
|
-
}
|
|
250
|
+
&-link
|
|
251
|
+
@apply relative block s("py-1.75") s("px-3.75") border-t border-r border-l border-border rounded-t text-lg text-primary-light
|
|
331
252
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
}
|
|
253
|
+
&-title
|
|
254
|
+
@apply truncate
|
|
335
255
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
});
|
|
339
|
-
watch(currentPage, () => {
|
|
340
|
-
fetch();
|
|
341
|
-
});
|
|
342
|
-
watch(project, () => {
|
|
343
|
-
currentPage.value = 1;
|
|
344
|
-
fetch();
|
|
345
|
-
});
|
|
256
|
+
.tab-pane
|
|
257
|
+
@apply space-y-8
|
|
346
258
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
});
|
|
259
|
+
& > .tabs-content
|
|
260
|
+
@apply p-4 border border-border rounded-lg bg-white overflow-hidden
|
|
350
261
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
search,
|
|
354
|
-
totalCount,
|
|
355
|
-
currentPage,
|
|
356
|
-
loading,
|
|
357
|
-
isShowDeleteConfirmModal,
|
|
358
|
-
perPage,
|
|
359
|
-
onClickedAdd,
|
|
360
|
-
onClearedSearch,
|
|
361
|
-
onClickedDelete,
|
|
362
|
-
onClickedRepack,
|
|
363
|
-
onDeleteApply,
|
|
364
|
-
onUpdatedPerPage,
|
|
365
|
-
onUpdatedPage,
|
|
366
|
-
};
|
|
367
|
-
},
|
|
368
|
-
});
|
|
369
|
-
</script>
|
|
262
|
+
.tabs-content-header
|
|
263
|
+
@apply flex items-start justify-between mb-4
|
|
370
264
|
|
|
371
|
-
|
|
372
|
-
.
|
|
373
|
-
|
|
374
|
-
|
|
265
|
+
&.tabs-type-2
|
|
266
|
+
& > .tabs-nav
|
|
267
|
+
@apply mb-0
|
|
268
|
+
|
|
269
|
+
ul
|
|
270
|
+
@apply flex px-8 pb-5 space-x-8
|
|
271
|
+
@apply s('lg:px-6') s('lg:space-x-14')
|
|
272
|
+
|
|
273
|
+
.tab-nav-item
|
|
274
|
+
@apply relative flex-grow s('py-6') rounded bg-bg text-lg text-primary-hover text-center
|
|
275
|
+
@apply s('lg:py-5.5')
|
|
276
|
+
|
|
277
|
+
&:before
|
|
278
|
+
content ""
|
|
279
|
+
@apply absolute s('top-0.5') s('left-0.5') block rounded bg-white
|
|
280
|
+
width calc(100% - theme('spacing.1'))
|
|
281
|
+
height calc(100% - theme('spacing.1'))
|
|
282
|
+
|
|
283
|
+
&:after
|
|
284
|
+
content ""
|
|
285
|
+
@apply absolute left-0 bottom-0 s('-ml-4') s('-mb-5') block w-full h-3 rounded-t bg-primary-lighter opacity-0
|
|
286
|
+
width calc(100% + theme('spacing.4') * 2)
|
|
287
|
+
|
|
288
|
+
&.active
|
|
289
|
+
@apply text-primary font-bold
|
|
290
|
+
|
|
291
|
+
&:after
|
|
292
|
+
@apply opacity-100
|
|
293
|
+
|
|
294
|
+
&:nth-child(odd)
|
|
295
|
+
@apply bg-transparent s('bg-gradient-to-r') s('from-insight-web-title-start') s('to-insight-web-title-end')
|
|
296
|
+
|
|
297
|
+
&:after
|
|
298
|
+
@apply bg-transparent s('bg-gradient-to-r') s('from-insight-web-title-start') s('to-insight-web-title-end')
|
|
299
|
+
|
|
300
|
+
&:nth-child(even)
|
|
301
|
+
@apply bg-transparent s('bg-gradient-to-r') s('from-insight-poi-title-start') s('to-insight-poi-title-end')
|
|
302
|
+
|
|
303
|
+
&:after
|
|
304
|
+
@apply bg-transparent s('bg-gradient-to-r') s('from-insight-poi-title-start') s('to-insight-poi-title-end')
|
|
305
|
+
|
|
306
|
+
.tab-nav-item-link
|
|
307
|
+
@apply cursor-default
|
|
308
|
+
|
|
309
|
+
&-link
|
|
310
|
+
@apply relative
|
|
311
|
+
|
|
312
|
+
&.tabs-type-3
|
|
313
|
+
& > .tabs-nav
|
|
314
|
+
@apply flex items-start justify-between h-0 space-x-8 overflow-hidden
|
|
315
|
+
@apply s('lg:space-x-30')
|
|
316
|
+
|
|
317
|
+
&.show
|
|
318
|
+
@apply h-auto mb-1
|
|
319
|
+
|
|
320
|
+
.tabs-nav-left
|
|
321
|
+
@apply flex-grow overflow-hidden
|
|
322
|
+
|
|
323
|
+
.tabs-nav-right
|
|
324
|
+
@apply flex-grow-0 flex-shrink-0
|
|
325
|
+
|
|
326
|
+
ul
|
|
327
|
+
@apply inline-flex items-start space-x-2
|
|
328
|
+
|
|
329
|
+
.tab-nav-item
|
|
330
|
+
@apply relative rounded-t bg-bg
|
|
331
|
+
|
|
332
|
+
&.active
|
|
333
|
+
@apply bg-primary
|
|
334
|
+
|
|
335
|
+
.tab-nav-item-link
|
|
336
|
+
@apply text-white cursor-default
|
|
337
|
+
|
|
338
|
+
&-link
|
|
339
|
+
@apply relative block py-2 px-8 rounded-t text-base text-primary
|
|
340
|
+
|
|
341
|
+
&-title
|
|
342
|
+
@apply truncate
|
|
343
|
+
|
|
344
|
+
.tab-pane
|
|
345
|
+
@apply space-y-8
|
|
346
|
+
|
|
347
|
+
& > .tabs-content
|
|
348
|
+
@apply p-6 rounded-tr-lg rounded-b-lg bg-white shadow overflow-hidden
|
|
349
|
+
|
|
350
|
+
.tabs-content-header
|
|
351
|
+
@apply flex items-start justify-between
|
|
352
|
+
|
|
353
|
+
.tabs-dropdown
|
|
354
|
+
@apply mb-4
|
|
355
|
+
|
|
356
|
+
&.tabs-type-4
|
|
357
|
+
@apply flex
|
|
358
|
+
|
|
359
|
+
& > .tabs-nav
|
|
360
|
+
@apply flex-grow-0 flex-shrink-0
|
|
361
|
+
|
|
362
|
+
.tabs-nav-left
|
|
363
|
+
ul
|
|
364
|
+
@apply flex flex-col s('space-y-0.5')
|
|
365
|
+
|
|
366
|
+
.tab-nav-item
|
|
367
|
+
@apply flex justify-between s('w-[184px]') py-3 pl-3 pr-5 bg-bg-middle rounded-l-lg text-xs
|
|
368
|
+
|
|
369
|
+
&.active
|
|
370
|
+
@apply bg-primary-hover text-white font-bold shadow-md
|
|
371
|
+
|
|
372
|
+
&-link
|
|
373
|
+
@apply block w-full
|
|
374
|
+
|
|
375
|
+
.tabs-content
|
|
376
|
+
@apply flex-grow s('-ml-2') p-4 bg-white border border-border rounded-lg shadow-md
|
|
375
377
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
@apply mb-2 s('text-3.33xl') text-primary font-bold
|
|
378
|
+
& > div
|
|
379
|
+
@apply flex min-h-full
|
|
379
380
|
|
|
380
|
-
|
|
381
|
-
|
|
381
|
+
.tabs-content-body
|
|
382
|
+
@apply w-full
|
|
382
383
|
|
|
383
|
-
|
|
384
|
-
|
|
384
|
+
&.tabs-type-5
|
|
385
|
+
& > .tabs-nav
|
|
386
|
+
@apply relative flex items-start justify-between h-0 mb-4 space-x-8 overflow-hidden
|
|
387
|
+
@apply s('lg:space-x-30')
|
|
385
388
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
@apply s('py-1.75') s('pl-[23px]') s('pr-3.75') rounded-lg text-lg
|
|
389
|
+
&.show
|
|
390
|
+
@apply h-auto
|
|
389
391
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
+
&:before
|
|
393
|
+
content ""
|
|
394
|
+
@apply absolute right-0 bottom-0 left-0 h-px s('rounded-[1px]') bg-primary-lighter
|
|
392
395
|
|
|
393
|
-
|
|
394
|
-
|
|
396
|
+
.tabs-nav-left
|
|
397
|
+
@apply flex-grow overflow-hidden
|
|
395
398
|
|
|
396
|
-
.
|
|
397
|
-
|
|
398
|
-
input
|
|
399
|
-
@apply text-sm
|
|
399
|
+
.tabs-nav-right
|
|
400
|
+
@apply flex-grow-0 flex-shrink-0
|
|
400
401
|
|
|
401
|
-
|
|
402
|
-
|
|
402
|
+
ul
|
|
403
|
+
@apply inline-flex items-start
|
|
403
404
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
@apply space-y-4
|
|
405
|
+
.tab-nav-item
|
|
406
|
+
@apply relative
|
|
407
407
|
|
|
408
|
-
|
|
409
|
-
|
|
408
|
+
&.active
|
|
409
|
+
&:after
|
|
410
|
+
content ""
|
|
411
|
+
@apply block absolute right-0 bottom-0 left-0 h-1 s('rounded-[1px]') bg-primary
|
|
410
412
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
+
.tab-nav-item-link
|
|
414
|
+
@apply cursor-default
|
|
413
415
|
|
|
414
|
-
|
|
415
|
-
@apply
|
|
416
|
+
&-link
|
|
417
|
+
@apply relative block px-4 pb-2 text-lg text-gray-2
|
|
416
418
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
+
&-title
|
|
420
|
+
@apply truncate
|
|
419
421
|
|
|
420
|
-
.
|
|
421
|
-
|
|
422
|
-
&-content
|
|
423
|
-
@apply flex flex-col items-center justify-center space-y-6 text-base text-gray-2
|
|
422
|
+
.tab-pane
|
|
423
|
+
@apply space-y-8
|
|
424
424
|
|
|
425
|
-
|
|
426
|
-
|
|
425
|
+
& > .tabs-content
|
|
426
|
+
.tabs
|
|
427
|
+
& > .tabs-content
|
|
428
|
+
@apply shadow-md
|
|
427
429
|
</style>
|
|
428
|
-
|
|
430
|
+
|