Discover: sidebarFilter toggle button done.
This commit is contained in:
@@ -31,63 +31,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* toggle */
|
|
||||||
/* <div class="toggle">
|
|
||||||
<input type="checkbox"/>
|
|
||||||
<label></label>
|
|
||||||
</div> */
|
|
||||||
.toggle {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.toggle input[type="checkbox"] {
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
z-index: 10;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
cursor: pointer;
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
.toggle label {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
.toggle label:before {
|
|
||||||
content: '';
|
|
||||||
border: 5px solid #bbb;
|
|
||||||
height: 35px;
|
|
||||||
width: 70px;
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
border-radius: 46px;
|
|
||||||
transition: 0.2s ease-in;
|
|
||||||
}
|
|
||||||
.toggle label:after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
background: #555;
|
|
||||||
width: 28px;
|
|
||||||
height: 28px;
|
|
||||||
left: 8px;
|
|
||||||
top: 8px;
|
|
||||||
border-radius: 50%;
|
|
||||||
z-index: 2;
|
|
||||||
box-shadow: 0 0 5px #0002;
|
|
||||||
transition: 0.2s ease-in;
|
|
||||||
}
|
|
||||||
.toggle input[type="checkbox"]:hover + label:after {
|
|
||||||
box-shadow: 0 2px 15px 0 #0002, 0 3px 8px 0 #0001;
|
|
||||||
}
|
|
||||||
.toggle input[type="checkbox"]:checked + label:before {
|
|
||||||
border-color: #77C2BB;
|
|
||||||
}
|
|
||||||
.toggle input[type="checkbox"]:checked + label:after {
|
|
||||||
background: #009688;
|
|
||||||
left: 44px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* components */
|
/* components */
|
||||||
/* Scrollbar */
|
/* Scrollbar */
|
||||||
@layer utilities {
|
@layer utilities {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Primevue */
|
/* Primevue */
|
||||||
|
/* sidebar */
|
||||||
.p-sidebar-left {
|
.p-sidebar-left {
|
||||||
@apply ml-14
|
@apply ml-14
|
||||||
}
|
}
|
||||||
@@ -32,11 +33,19 @@
|
|||||||
.p-sidebar-header {
|
.p-sidebar-header {
|
||||||
@apply bg-neutral-200 border-b border-neutral-300 !py-2 !justify-between
|
@apply bg-neutral-200 border-b border-neutral-300 !py-2 !justify-between
|
||||||
};
|
};
|
||||||
|
|
||||||
.p-sidebar-right .p-sidebar-header {
|
.p-sidebar-right .p-sidebar-header {
|
||||||
@apply flex-row-reverse !justify-end text-neutral-500
|
@apply flex-row-reverse !justify-end text-neutral-500
|
||||||
}
|
}
|
||||||
|
|
||||||
.p-sidebar-right .p-sidebar {
|
.p-sidebar-right .p-sidebar {
|
||||||
@apply !shadow-[-1px_0px_4px_rgba(0,0,0,0.25)]
|
@apply !shadow-[-1px_0px_4px_rgba(0,0,0,0.25)]
|
||||||
}
|
}
|
||||||
|
/* inputswitch */
|
||||||
|
.p-inputswitch {
|
||||||
|
@apply !w-11 !h-6
|
||||||
|
}
|
||||||
|
.p-inputswitch.p-inputswitch-checked .p-inputswitch-slider {
|
||||||
|
@apply !bg-primary
|
||||||
|
}
|
||||||
|
.p-inputswitch .p-inputswitch-slider:before {
|
||||||
|
@apply !w-5 !h-5 !left-0.5
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</template>
|
</template>
|
||||||
<!-- header: filter -->
|
<!-- header: filter -->
|
||||||
<div v-if="tab === 'filter'" class="pt-4 bg-neutral-100 flex w-full h-full">
|
<div v-if="tab === 'filter'" class="pt-4 flex w-full h-full">
|
||||||
<!-- title: filter silect -->
|
<!-- title: filter silect -->
|
||||||
<div class="space-y-2 mr-4 w-56 text-sm">
|
<div class="space-y-2 mr-4 w-56 text-sm">
|
||||||
<div>
|
<div>
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
<label :for="item + index" class="ml-2">{{ item }}</label>
|
<label :for="item + index" class="ml-2">{{ item }}</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-show="selectValue[1] === 'Start activity & end activity'">
|
<div v-show="selectValue[1] === 'Start activity / end activity'">
|
||||||
<p class="h2">Start & End</p>
|
<p class="h2">Start & End</p>
|
||||||
<div v-for="(item, index) in selectFilter['Start & End']" :key="index" class="flex align-items-center">
|
<div v-for="(item, index) in selectFilter['Start & End']" :key="index" class="flex align-items-center">
|
||||||
<RadioButton v-model="selectValue[2]" :inputId="item + index" name="Start & End" :value="item" />
|
<RadioButton v-model="selectValue[2]" :inputId="item + index" name="Start & End" :value="item" />
|
||||||
@@ -68,11 +68,11 @@
|
|||||||
<!-- Filter task Data-->
|
<!-- Filter task Data-->
|
||||||
<ActOccCase v-if="selectValue[0] === 'Sequence' && selectValue[1] === 'Have activity(s)'" :tableTitle="'Activity List'" :tableData="filterTaskData" :tableSelect="selectFilterTask" :progressWidth ="progressWidth" @on-row-select="onRowAct"></ActOccCase>
|
<ActOccCase v-if="selectValue[0] === 'Sequence' && selectValue[1] === 'Have activity(s)'" :tableTitle="'Activity List'" :tableData="filterTaskData" :tableSelect="selectFilterTask" :progressWidth ="progressWidth" @on-row-select="onRowAct"></ActOccCase>
|
||||||
<!-- Filter Start Data -->
|
<!-- Filter Start Data -->
|
||||||
<ActOcc v-if="selectValue[0] === 'Sequence' && selectValue[1] === 'Start activity & end activity' && selectValue[2] === 'Start'" :tableTitle="'Start activity'" :tableData="filterStartData" :tableSelect="selectFilterStart" :progressWidth ="progressWidth" @on-row-select="onRowStart"></ActOcc>
|
<ActOcc v-if="selectValue[0] === 'Sequence' && selectValue[1] === 'Start activity / end activity' && selectValue[2] === 'Start'" :tableTitle="'Start activity'" :tableData="filterStartData" :tableSelect="selectFilterStart" :progressWidth ="progressWidth" @on-row-select="onRowStart"></ActOcc>
|
||||||
<!-- Filter End Data -->
|
<!-- Filter End Data -->
|
||||||
<ActOcc v-if="selectValue[0] === 'Sequence' && selectValue[1] === 'Start activity & end activity' && selectValue[2] === 'End'" :tableTitle="'End activity'" :tableData="filterEndData" :tableSelect="selectFilterEnd" :progressWidth ="progressWidth" @on-row-select="onRowEnd"></ActOcc>
|
<ActOcc v-if="selectValue[0] === 'Sequence' && selectValue[1] === 'Start activity / end activity' && selectValue[2] === 'End'" :tableTitle="'End activity'" :tableData="filterEndData" :tableSelect="selectFilterEnd" :progressWidth ="progressWidth" @on-row-select="onRowEnd"></ActOcc>
|
||||||
<!-- Filter Start And End Data -->
|
<!-- Filter Start And End Data -->
|
||||||
<div v-if="selectValue[0] === 'Sequence' && selectValue[1] === 'Start activity & end activity' && selectValue[2] === 'Start & End'" class="flex justify-between items-center w-full h-full space-x-4 ">
|
<div v-if="selectValue[0] === 'Sequence' && selectValue[1] === 'Start activity / end activity' && selectValue[2] === 'Start & End'" class="flex justify-between items-center w-full h-full space-x-4 ">
|
||||||
<ActOcc :tableTitle="'Start activity'" :tableData="filterStartToEndData" :tableSelect="selectFilterStartToEnd" :progressWidth ="progressWidth" class="w-1/2" @on-row-select="startRow"></ActOcc>
|
<ActOcc :tableTitle="'Start activity'" :tableData="filterStartToEndData" :tableSelect="selectFilterStartToEnd" :progressWidth ="progressWidth" class="w-1/2" @on-row-select="startRow"></ActOcc>
|
||||||
<ActOcc :tableTitle="'End activity'" :tableData="filterEndToStartData" :tableSelect="selectFilterEndToStart" :progressWidth ="progressWidth" class="w-1/2" @on-row-select="endRow"></ActOcc>
|
<ActOcc :tableTitle="'End activity'" :tableData="filterEndToStartData" :tableSelect="selectFilterEndToStart" :progressWidth ="progressWidth" class="w-1/2" @on-row-select="endRow"></ActOcc>
|
||||||
</div>
|
</div>
|
||||||
@@ -83,63 +83,45 @@
|
|||||||
|
|
||||||
<!-- Button -->
|
<!-- Button -->
|
||||||
<div class="float-right space-x-4 px-4 py-2">
|
<div class="float-right space-x-4 px-4 py-2">
|
||||||
<button class="btn btn-sm btn-neutral" @click="reset">Clear</button>
|
<button type="button" class="btn btn-sm btn-neutral" @click="reset">Clear</button>
|
||||||
<button class="btn btn-sm btn-neutral" @click="submit">Apply</button>
|
<button type="button" class="btn btn-sm btn-neutral" @click="submit">Apply</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- header: funnel -->
|
<!-- header: funnel -->
|
||||||
<div v-if="tab === 'funnel'" class="bg-neutral-10 w-full h-full">
|
<div v-if="tab === 'funnel'" class=" w-full h-full">
|
||||||
<div class="h-[calc(100%_-_58px)] border-b border-neutral-300 mb-2">
|
<div class="h-[calc(100%_-_58px)] border-b border-neutral-400 mb-2 overflow-y-auto overflow-x-auto scrollbar">
|
||||||
<div v-if="temporaryData.length === 0" class="h-full flex justify-center items-center">
|
<div v-if="this.temporaryData.length === 0" class="h-full flex justify-center items-center">
|
||||||
<span class="text-neutral-500">No Filter.</span>
|
<span class="text-neutral-500">No Filter.</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
temporaryData:{{ temporaryData }}
|
<Timeline :value="ruleData">
|
||||||
<Timeline :value="events">
|
<template #content="rule">
|
||||||
<template #content="slotProps">
|
<div class="border-b border-neutral-300 flex justify-between items-center space-x-2">
|
||||||
{{ slotProps.item.status }}
|
<!-- content -->
|
||||||
|
<div class="pl-2 mb-2">
|
||||||
|
<p class="text-sm font-medium leading-5">{{ rule.item.type }}: <span class="text-neutral-500">{{ rule.item.label }}</span></p>
|
||||||
|
<!-- <p class="text-sm font-medium mb-5">{{ rule.item.type }}</p>
|
||||||
|
<p class="text-sm text-neutral-500 mb-2">{{ rule.item.label }}</p> -->
|
||||||
|
</div>
|
||||||
|
<!-- button -->
|
||||||
|
<div class="min-w-fit">
|
||||||
|
<InputSwitch v-model="rule.item.toggle" @input="isRule($event, rule.index)"/>
|
||||||
|
<button type="button" class="m-2 focus:ring focus:ring-danger/20 text-neutral-500 hover:text-danger" @click.stop="deleteRule(rule.index)">
|
||||||
|
<span class="material-symbols-outlined">delete</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</Timeline>
|
</Timeline>
|
||||||
|
|
||||||
<!-- <Timeline :value="events" align="alternate" class="customized-timeline">
|
|
||||||
<template #marker="slotProps">
|
|
||||||
<span class="!flex !w-2rem !h-2rem !align-items-center !justify-content-center !text-white !border-circle !z-1 !shadow-1" :style="{ backgroundColor: slotProps.item.color }">
|
|
||||||
<i :class="slotProps.item.icon"></i>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
<template #content="slotProps">
|
|
||||||
{{ slotProps.item.status }}
|
|
||||||
<Card>
|
|
||||||
<template #title>
|
|
||||||
{{ slotProps.item.status }}
|
|
||||||
</template>
|
|
||||||
<template #subtitle>
|
|
||||||
{{ slotProps.item.date }}
|
|
||||||
</template>
|
|
||||||
<template #content>
|
|
||||||
<img v-if="slotProps.item.image" :src="`https://primefaces.org/cdn/primevue/images/product/${slotProps.item.image}`" :alt="slotProps.item.name" width="200" class="shadow-1" />
|
|
||||||
<p>
|
|
||||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Inventore sed consequuntur error repudiandae numquam deserunt quisquam repellat libero asperiores earum nam nobis, culpa ratione quam perferendis esse, cupiditate
|
|
||||||
neque quas!
|
|
||||||
</p>
|
|
||||||
<Button label="Read more" text></Button>
|
|
||||||
</template>
|
|
||||||
</Card>
|
|
||||||
</template>
|
|
||||||
</Timeline> -->
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- Button -->
|
<!-- Button -->
|
||||||
<div class="">
|
<div class="">
|
||||||
<div class="float-right space-x-4 px-4 py-2">
|
<div class="float-right space-x-4 px-4 py-2">
|
||||||
<button class="btn btn-sm btn-neutral" @click="deleteAll">Delete All</button>
|
<button type="button" class="btn btn-sm " :class="[ temporaryData.length === 0 ? 'btn-disable' : 'btn-neutral']" :disabled="temporaryData.length === 0" @click="deleteRule('all')">Delete All</button>
|
||||||
<button class="btn btn-sm btn-neutral" @click="submitAll">Apply All</button>
|
<button type="button" class="btn btn-sm" :class="[ temporaryData.length === 0 ? 'btn-disable' : 'btn-neutral']" :disabled="temporaryData.length === 0" @click="submitAll">Apply All</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -186,21 +168,15 @@ export default {
|
|||||||
const loadingStore = LoadingStore();
|
const loadingStore = LoadingStore();
|
||||||
const allMapDataStore = AllMapDataStore();
|
const allMapDataStore = AllMapDataStore();
|
||||||
const { isLoading } = storeToRefs(loadingStore);
|
const { isLoading } = storeToRefs(loadingStore);
|
||||||
const { hasResultRule, postRuleData} = storeToRefs(allMapDataStore);
|
const { hasResultRule, temporaryData, postRuleData} = storeToRefs(allMapDataStore);
|
||||||
|
|
||||||
return { isLoading, hasResultRule, postRuleData, allMapDataStore }
|
return { isLoading, hasResultRule, temporaryData, postRuleData, allMapDataStore }
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
events: [
|
|
||||||
{ status: 'Ordered', date: '15/10/2020 10:30', icon: 'pi pi-shopping-cart', color: '#9C27B0'},
|
|
||||||
{ status: 'Processing', date: '15/10/2020 14:00', icon: 'pi pi-cog', color: '#673AB7' },
|
|
||||||
{ status: 'Shipped', date: '15/10/2020 16:15', icon: 'pi pi-shopping-cart', color: '#FF9800' },
|
|
||||||
{ status: 'Delivered', date: '16/10/2020 10:00', icon: 'pi pi-check', color: '#607D8B' }
|
|
||||||
],
|
|
||||||
selectFilter: {
|
selectFilter: {
|
||||||
'Filter Type': ['Sequence', 'Attributes', 'Trace', 'Timeframes'],
|
'Filter Type': ['Sequence', 'Attributes', 'Trace', 'Timeframes'],
|
||||||
'Activity Sequence':['Have activity(s)', 'Start activity & end activity', 'Sequence'],
|
'Activity Sequence':['Have activity(s)', 'Start activity / end activity', 'Sequence'],
|
||||||
'Start & End': ['Start', 'End', 'Start & End'],
|
'Start & End': ['Start', 'End', 'Start & End'],
|
||||||
'Mode': ['Directly follows', 'Eventually follows'],
|
'Mode': ['Directly follows', 'Eventually follows'],
|
||||||
'ModeAtt': ['Case', 'Activity'],
|
'ModeAtt': ['Case', 'Activity'],
|
||||||
@@ -208,7 +184,6 @@ export default {
|
|||||||
'Containment': ['Contained in', 'Started in', 'End in', 'Activity in', 'Trim'],
|
'Containment': ['Contained in', 'Started in', 'End in', 'Activity in', 'Trim'],
|
||||||
},
|
},
|
||||||
tab: 'filter', // filter | funnel
|
tab: 'filter', // filter | funnel
|
||||||
// selectValue: ['Sequence', 'Have activity(s)', 'Start', 'Directly follows', 'Case', 'Include', 'Contained in'],
|
|
||||||
selectValue: {
|
selectValue: {
|
||||||
0: 'Sequence',
|
0: 'Sequence',
|
||||||
1: 'Have activity(s)',
|
1: 'Have activity(s)',
|
||||||
@@ -229,7 +204,8 @@ export default {
|
|||||||
isEndSelected: null,
|
isEndSelected: null,
|
||||||
isActAllTask: true,
|
isActAllTask: true,
|
||||||
rowData: [],
|
rowData: [],
|
||||||
temporaryData: [],
|
ruleData: [],
|
||||||
|
isRuleData: [], // toggle button data
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
@@ -257,12 +233,25 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} switch Summary or Insight
|
* @param {string} switch Summary or Insight
|
||||||
*/
|
*/
|
||||||
switchTab(tab) {
|
switchTab(tab) {
|
||||||
this.tab = tab;
|
this.tab = tab;
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* @param {boolean} e ture | false
|
||||||
|
* @param {numble} index rule's index
|
||||||
|
*/
|
||||||
|
isRule(e, index){
|
||||||
|
let rule = this.isRuleData[index];
|
||||||
|
// 先取得 rule object
|
||||||
|
// 為了讓 data 順序不亂掉,將值指向 0,submitAll 時再刪掉
|
||||||
|
if(!e) this.temporaryData[index] = 0;
|
||||||
|
else this.temporaryData[index] = rule;
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* Number to percentage
|
* Number to percentage
|
||||||
* @param {number} val
|
* @param {number} val
|
||||||
@@ -379,6 +368,59 @@ export default {
|
|||||||
occurrence_ratio: this.getPercentLabel(item.occurrence_ratio),
|
occurrence_ratio: this.getPercentLabel(item.occurrence_ratio),
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* @param {object} e task's object
|
||||||
|
*/
|
||||||
|
setRule(e) {
|
||||||
|
let label = "";
|
||||||
|
let type = "";
|
||||||
|
let includeStr = e.is_exclude?" Exclude ":" Include ";
|
||||||
|
|
||||||
|
switch(e.type){
|
||||||
|
case "contains-task":
|
||||||
|
label = `${includeStr} ${e.task}`
|
||||||
|
type = "Sequence"
|
||||||
|
break
|
||||||
|
case "starts-with":
|
||||||
|
label = `Start with ${e.task} ${includeStr}`
|
||||||
|
type = "Sequence"
|
||||||
|
break
|
||||||
|
case "ends-with":
|
||||||
|
label = `End with ${e.task} ${includeStr}`
|
||||||
|
type = "Sequence"
|
||||||
|
break
|
||||||
|
case "start-end":
|
||||||
|
label = `Start with ${e.starts_with}, End with ${e.ends_with} ${includeStr}`
|
||||||
|
type = "Sequence"
|
||||||
|
break
|
||||||
|
case "directly-follows":
|
||||||
|
label = `Directly-follows ${e.task_seq.join(' -> ')}${includeStr}`
|
||||||
|
type = "Sequence"
|
||||||
|
break
|
||||||
|
case "eventually-follows":
|
||||||
|
label = `Eventually-follows ${e.task_seq.join(' -> ')}${includeStr}`
|
||||||
|
type = "Sequence"
|
||||||
|
break
|
||||||
|
case "occurred-in":
|
||||||
|
case "started-in":
|
||||||
|
case "completed-in":
|
||||||
|
case "occurred-around":
|
||||||
|
label = `${e.type} from ${moment(e.start).format("YYYY-MM-DD HH:mm:ss")} to ${moment(e.end).format("YYYY-MM-DD HH:mm:ss")} ${includeStr}`
|
||||||
|
type = "Timeframe"
|
||||||
|
break
|
||||||
|
case "trace-freq":
|
||||||
|
label = `from ${e.lower} to ${e.upper} ${includeStr}`
|
||||||
|
type = "Trace"
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
type:type,
|
||||||
|
label:label,
|
||||||
|
toggle:true,
|
||||||
|
}
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* 清空選項
|
* 清空選項
|
||||||
*/
|
*/
|
||||||
@@ -415,7 +457,7 @@ export default {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
}else if(sele[1] === 'Start activity & end activity') { // Activity Sequence 選 Start activity & end activity 的行為
|
}else if(sele[1] === 'Start activity / end activity') { // Activity Sequence 選 Start activity & end activity 的行為
|
||||||
if(sele[2] === 'Start') {
|
if(sele[2] === 'Start') {
|
||||||
if(this.selectFilterStart === null || this.selectFilterStart.length === 0) return this.$toast.error('Not selected');
|
if(this.selectFilterStart === null || this.selectFilterStart.length === 0) return this.$toast.error('Not selected');
|
||||||
else {
|
else {
|
||||||
@@ -429,7 +471,7 @@ export default {
|
|||||||
if(this.selectFilterEnd === null || this.selectFilterEnd.length === 0) return this.$toast.error('Not selected');
|
if(this.selectFilterEnd === null || this.selectFilterEnd.length === 0) return this.$toast.error('Not selected');
|
||||||
else {
|
else {
|
||||||
data = {
|
data = {
|
||||||
type: 'starts-with',
|
type: 'ends-with',
|
||||||
task: this.selectFilterEnd.label,
|
task: this.selectFilterEnd.label,
|
||||||
is_exclude: isExclude,
|
is_exclude: isExclude,
|
||||||
}
|
}
|
||||||
@@ -468,6 +510,8 @@ export default {
|
|||||||
if(this.hasResultRule === null) return;
|
if(this.hasResultRule === null) return;
|
||||||
else if(this.hasResultRule) {
|
else if(this.hasResultRule) {
|
||||||
this.temporaryData.push(...postData);
|
this.temporaryData.push(...postData);
|
||||||
|
this.isRuleData = Array.from(this.temporaryData);
|
||||||
|
this.ruleData = this.temporaryData.map(e => this.setRule(e));
|
||||||
this.reset(false);
|
this.reset(false);
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||||
@@ -482,21 +526,30 @@ export default {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
// header:Funnel 刪除全部的 Funnel
|
// header:Funnel 刪除全部的 Funnel
|
||||||
deleteAll() {
|
deleteRule(index) {
|
||||||
this.temporaryData = [];
|
if(index === 'all') {
|
||||||
this.$toast.success('All deleted.');
|
this.temporaryData = [];
|
||||||
|
this.isRuleData = [];
|
||||||
|
this.$toast.success('All deleted.');
|
||||||
|
}else{
|
||||||
|
this.$toast.success(`Delete ${this.ruleData[index].label}.`);
|
||||||
|
this.temporaryData.splice(index, 1);
|
||||||
|
this.isRuleData.splice(index, 1);
|
||||||
|
this.ruleData.splice(index, 1);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
// header:Funnel 發送暫存的選取資料
|
// header:Funnel 發送暫存的選取資料
|
||||||
async submitAll() {
|
async submitAll() {
|
||||||
if(this.temporaryData.length === 0) return this.$toast.error('No Filter.');
|
this.postRuleData = this.temporaryData; // 取得 submit 的資料
|
||||||
|
this.postRuleData = this.postRuleData.filter(item => item !== 0); // 有 toggle button 的話,找出並刪除陣列中為 0 的項目
|
||||||
this.postRuleData = this.temporaryData;
|
|
||||||
await this.allMapDataStore.checkHasResult();
|
await this.allMapDataStore.checkHasResult();
|
||||||
|
|
||||||
if(this.hasResultRule === null) return;
|
if(this.hasResultRule === null) return;
|
||||||
else if(this.hasResultRule) {
|
else if(this.hasResultRule) {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
await this.allMapDataStore.addTempFilterId();
|
await this.allMapDataStore.addTempFilterId();
|
||||||
|
await this.allMapDataStore.getAllMapData();
|
||||||
|
await this.$emit('submit-all');
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
this.$toast.success('Filter Success. View the Map.');
|
this.$toast.success('Filter Success. View the Map.');
|
||||||
}else {
|
}else {
|
||||||
@@ -517,10 +570,22 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* TimeLine */
|
/* TimeLine */
|
||||||
|
:deep(.p-timeline) {
|
||||||
|
@apply leading-none my-4
|
||||||
|
}
|
||||||
|
:deep(.p-timeline-event-opposite) {
|
||||||
|
@apply hidden
|
||||||
|
}
|
||||||
|
:deep(.p-timeline-event-separator) {
|
||||||
|
@apply mx-4
|
||||||
|
}
|
||||||
:deep(.p-timeline-event-marker) {
|
:deep(.p-timeline-event-marker) {
|
||||||
@apply !bg-primary !border-primary !h-2 !w-2
|
@apply !bg-primary !border-primary !w-2 !h-2
|
||||||
}
|
}
|
||||||
:deep(.p-timeline-event-connector) {
|
:deep(.p-timeline-event-connector) {
|
||||||
@apply !bg-primary my-2 !w-[1px]
|
@apply !bg-primary my-2 !w-[1px]
|
||||||
}
|
}
|
||||||
|
:deep(.p-timeline-event-content) {
|
||||||
|
@apply !px-0
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import Row from 'primevue/row'; // optional
|
|||||||
import RadioButton from 'primevue/radiobutton';
|
import RadioButton from 'primevue/radiobutton';
|
||||||
import PickList from 'primevue/picklist';
|
import PickList from 'primevue/picklist';
|
||||||
import Timeline from 'primevue/timeline';
|
import Timeline from 'primevue/timeline';
|
||||||
|
import InputSwitch from 'primevue/inputswitch';
|
||||||
|
|
||||||
const emitter = mitt();
|
const emitter = mitt();
|
||||||
const app = createApp(App);
|
const app = createApp(App);
|
||||||
@@ -62,7 +63,7 @@ app.use(router);
|
|||||||
app.use(VueAxios, axios);
|
app.use(VueAxios, axios);
|
||||||
app.use(ToastPlugin, { // use `this.$toast` in Vue.js
|
app.use(ToastPlugin, { // use `this.$toast` in Vue.js
|
||||||
position: 'bottom',
|
position: 'bottom',
|
||||||
duration: 5000,
|
duration: 3000,
|
||||||
});
|
});
|
||||||
app.use(PrimeVue);
|
app.use(PrimeVue);
|
||||||
app.component('Sidebar', Sidebar);
|
app.component('Sidebar', Sidebar);
|
||||||
@@ -79,6 +80,7 @@ app.component('Row', Row);
|
|||||||
app.component('RadioButton', RadioButton);
|
app.component('RadioButton', RadioButton);
|
||||||
app.component('PickList', PickList);
|
app.component('PickList', PickList);
|
||||||
app.component('Timeline', Timeline);
|
app.component('Timeline', Timeline);
|
||||||
|
app.component('InputSwitch', InputSwitch);
|
||||||
app.component('Draggable', draggable); // 拖曳
|
app.component('Draggable', draggable); // 拖曳
|
||||||
|
|
||||||
app.mount("#app");
|
app.mount("#app");
|
||||||
|
|||||||
@@ -29,7 +29,8 @@ export default defineStore('allMapDataStore', {
|
|||||||
allFilterTrace: [],
|
allFilterTrace: [],
|
||||||
httpStatus: 200,
|
httpStatus: 200,
|
||||||
hasResultRule: null, // click Apply 後檢查是否有 Data
|
hasResultRule: null, // click Apply 後檢查是否有 Data
|
||||||
postRuleData: [],
|
temporaryData: [], // 沒被 apply 的 Data
|
||||||
|
postRuleData: [], // has-result API & temp-filters API 的 Data
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
processMap: state => {
|
processMap: state => {
|
||||||
@@ -79,10 +80,7 @@ export default defineStore('allMapDataStore', {
|
|||||||
async getAllMapData() {
|
async getAllMapData() {
|
||||||
let logId = this.logId;
|
let logId = this.logId;
|
||||||
let tempFilterId = this.tempFilterId;
|
let tempFilterId = this.tempFilterId;
|
||||||
let api = tempFilterId !== null ? `/api/temp-filters/${tempFilterId}/discover` : `/api/logs/${logId}/discover`;
|
let api = tempFilterId != null ? `/api/temp-filters/${tempFilterId}/discover` : `/api/logs/${logId}/discover`;
|
||||||
console.log(tempFilterId);
|
|
||||||
// console.log(logId);
|
|
||||||
// const api = `/api/logs/${logId}/discover`;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await this.$axios.get(api);
|
const response = await this.$axios.get(api);
|
||||||
|
|||||||
@@ -48,7 +48,8 @@
|
|||||||
<SidebarView v-model:visible="sidebarView" @switch-map-type="switchMapType" @switch-curve-styles="switchCurveStyles" @switch-rank="switchRank" @switch-data-layer-type="switchDataLayerType" ></SidebarView>
|
<SidebarView v-model:visible="sidebarView" @switch-map-type="switchMapType" @switch-curve-styles="switchCurveStyles" @switch-rank="switchRank" @switch-data-layer-type="switchDataLayerType" ></SidebarView>
|
||||||
<SidebarState v-model:visible="sidebarState" :insights="insights" :stats="stats"></SidebarState>
|
<SidebarState v-model:visible="sidebarState" :insights="insights" :stats="stats"></SidebarState>
|
||||||
<SidebarTraces v-model:visible="sidebarTraces" :traces="traces" :cases="cases" :traceTaskSeq="traceTaskSeq" @switch-Trace-Id="switchTraceId" ref="tracesView"></SidebarTraces>
|
<SidebarTraces v-model:visible="sidebarTraces" :traces="traces" :cases="cases" :traceTaskSeq="traceTaskSeq" @switch-Trace-Id="switchTraceId" ref="tracesView"></SidebarTraces>
|
||||||
<SidebarFilter v-model:visible="sidebarFilter" :filterTasks="filterTasks" :filterStartToEnd="filterStartToEnd" :filterEndToStart="filterEndToStart" :filterTimeframe="filterTimeframe" :filterTrace="filterTrace"></SidebarFilter>
|
<SidebarFilter v-model:visible="sidebarFilter" :filterTasks="filterTasks" :filterStartToEnd="filterStartToEnd" :filterEndToStart="filterEndToStart" :filterTimeframe="filterTimeframe" :filterTrace="filterTrace"
|
||||||
|
@submit-all="createCy(mapType)"></SidebarFilter>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -125,14 +125,6 @@
|
|||||||
return recentlyUsedFiles;
|
return recentlyUsedFiles;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
watch:{
|
|
||||||
allFiles:{
|
|
||||||
handler:function(val,oldVal){
|
|
||||||
this.allFiles;
|
|
||||||
},
|
|
||||||
deep:true,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
/**
|
/**
|
||||||
* 選擇該 files 進入 Discover/Compare/Design 頁面
|
* 選擇該 files 進入 Discover/Compare/Design 頁面
|
||||||
|
|||||||
@@ -11,8 +11,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
import LoginStore from '@/stores/login.js';
|
import LoginStore from '@/stores/login.js';
|
||||||
import LoadingStore from '@/stores/loading.js';
|
import LoadingStore from '@/stores/loading.js';
|
||||||
|
import AllMapDataStore from '@/stores/allMapData.js';
|
||||||
import Header from "@/components/Header.vue";
|
import Header from "@/components/Header.vue";
|
||||||
import Navbar from "@/components/Navbar.vue";
|
import Navbar from "@/components/Navbar.vue";
|
||||||
import Loading from '@/components/Loading.vue';
|
import Loading from '@/components/Loading.vue';
|
||||||
@@ -22,11 +24,19 @@ export default {
|
|||||||
setup() {
|
setup() {
|
||||||
const loginStore = LoginStore();
|
const loginStore = LoginStore();
|
||||||
const loadingStore = LoadingStore();
|
const loadingStore = LoadingStore();
|
||||||
|
const allMapDataStore = AllMapDataStore();
|
||||||
const { checkLogin } = loginStore;
|
const { checkLogin } = loginStore;
|
||||||
|
const { tempFilterId, temporaryData, postRuleData } = storeToRefs(allMapDataStore);
|
||||||
|
|
||||||
return {
|
return { checkLogin, loadingStore, temporaryData, tempFilterId, postRuleData };
|
||||||
checkLogin,
|
},
|
||||||
loadingStore,
|
watch: {
|
||||||
|
$route: function(route) {
|
||||||
|
if(route.name !== 'Discover') {
|
||||||
|
this.tempFilterId = null;
|
||||||
|
this.temporaryData = []
|
||||||
|
this.postRuleData = []
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
|||||||
Reference in New Issue
Block a user