Merge branch 'sonar'
This commit is contained in:
@@ -2,8 +2,6 @@
|
|||||||
<RouterView />
|
<RouterView />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped></style>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { RouterView } from "vue-router";
|
import { RouterView } from "vue-router";
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
}
|
}
|
||||||
.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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,13 +38,6 @@
|
|||||||
</p>
|
</p>
|
||||||
<Chart type="bar" :data="casesChartData" :options="casesChartOptions" class="w-[99%]"/>
|
<Chart type="bar" :data="casesChartData" :options="casesChartOptions" class="w-[99%]"/>
|
||||||
</div>
|
</div>
|
||||||
<!-- Fitness 暫時不做 basis-1/3 → basis-1/2 -->
|
|
||||||
<!-- <div class="border rounded border-neutral-300 p-2 bg-neutral-10 basis-1/3">
|
|
||||||
<p class="h2 pl-2 flex justify-between items-center">
|
|
||||||
<span>Fitness<span class="material-symbols-outlined text-sm align-middle ml-2">info</span></span>
|
|
||||||
<span class="text-2xl">{{ data.charts.fitness }}</span>
|
|
||||||
</p>
|
|
||||||
</div> -->
|
|
||||||
</div>
|
</div>
|
||||||
<!-- effect -->
|
<!-- effect -->
|
||||||
<section>
|
<section>
|
||||||
@@ -104,6 +97,16 @@
|
|||||||
<div class="border rounded border-neutral-300 p-2 bg-neutral-10 w-full">
|
<div class="border rounded border-neutral-300 p-2 bg-neutral-10 w-full">
|
||||||
<p class="h2 pl-2 mb-2">Short Loop(s)</p>
|
<p class="h2 pl-2 mb-2">Short Loop(s)</p>
|
||||||
<table class="text-sm min-w-full table-fixed">
|
<table class="text-sm min-w-full table-fixed">
|
||||||
|
<caption class="hidden">Loop List</caption>
|
||||||
|
<thead class="hidden">
|
||||||
|
<tr>
|
||||||
|
<th class="w-1/5 px-4 py-2 hidden"></th>
|
||||||
|
<th class="w-1/5 px-4 py-2 hidden"></th>
|
||||||
|
<th class="w-1/5 px-4 py-2 hidden"></th>
|
||||||
|
<th class="w-1/5 px-4 py-2 hidden"></th>
|
||||||
|
<th class="w-1/5 px-4 py-2 hidden"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="(trace, key) in data.loops" :key="key">
|
<tr v-for="(trace, key) in data.loops" :key="key">
|
||||||
<td class="p-2 pl-6 truncate max-w-0 w-1/3">
|
<td class="p-2 pl-6 truncate max-w-0 w-1/3">
|
||||||
@@ -152,6 +155,16 @@
|
|||||||
<div v-else class="border rounded border-neutral-300 p-2 bg-neutral-10 " :class="data.timeTrend.chart !== null ? 'w-1/2' : 'w-full'">
|
<div v-else class="border rounded border-neutral-300 p-2 bg-neutral-10 " :class="data.timeTrend.chart !== null ? 'w-1/2' : 'w-full'">
|
||||||
<p class="h2 pl-2 mb-2">Issue List<span class="material-symbols-outlined !text-sm align-middle ml-2 cursor-pointer" v-tooltip.bottom="tooltip.issueList">info</span></p>
|
<p class="h2 pl-2 mb-2">Issue List<span class="material-symbols-outlined !text-sm align-middle ml-2 cursor-pointer" v-tooltip.bottom="tooltip.issueList">info</span></p>
|
||||||
<table class="text-sm min-w-full table-fixed">
|
<table class="text-sm min-w-full table-fixed">
|
||||||
|
<caption class="hidden">Issues List</caption>
|
||||||
|
<thead class="hidden">
|
||||||
|
<tr>
|
||||||
|
<th class="w-1/5 px-4 py-2 hidden"></th>
|
||||||
|
<th class="w-1/5 px-4 py-2 hidden"></th>
|
||||||
|
<th class="w-1/5 px-4 py-2 hidden"></th>
|
||||||
|
<th class="w-1/5 px-4 py-2 hidden"></th>
|
||||||
|
<th class="w-1/5 px-4 py-2 hidden"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="(trace, key) in data.issues" :key="key">
|
<tr v-for="(trace, key) in data.issues" :key="key">
|
||||||
<td class="p-2 pl-6 truncate max-w-0 w-1/3">
|
<td class="p-2 pl-6 truncate max-w-0 w-1/3">
|
||||||
@@ -500,8 +513,9 @@ export default {
|
|||||||
color: '#334155',
|
color: '#334155',
|
||||||
align: 'inner',
|
align: 'inner',
|
||||||
callback: function(value, index, values) {
|
callback: function(value, index, values) {
|
||||||
if (value === 0) return `${value * 100}%`;
|
if (value === 0 || value === 1) {
|
||||||
else if (value === 1) return `${value * 100}%`;
|
return `${value * 100}%`;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
grid: {
|
grid: {
|
||||||
@@ -585,8 +599,9 @@ export default {
|
|||||||
color: '#334155',
|
color: '#334155',
|
||||||
align: 'inner',
|
align: 'inner',
|
||||||
callback: function(value, index, values) {
|
callback: function(value, index, values) {
|
||||||
if (index === 0) return shortScaleNumber(value);
|
if (index === 0 || index === values.length - 1) {
|
||||||
else if (index === values.length - 1) return shortScaleNumber(value);
|
return shortScaleNumber(value);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
grid: {
|
grid: {
|
||||||
@@ -615,7 +630,7 @@ export default {
|
|||||||
let max = yMax * 1.1;
|
let max = yMax * 1.1;
|
||||||
let xVal = timeRange(xMin, xMax, 100);
|
let xVal = timeRange(xMin, xMax, 100);
|
||||||
let yVal = yTimeRange(data, 100, yMin, yMax);
|
let yVal = yTimeRange(data, 100, yMin, yMax);
|
||||||
data = xVal.map((x, index) => ({ x, y: yVal[index] }));
|
xVal.map((x, index) => ({ x, y: yVal[index] }));
|
||||||
let formattedXVal = xVal.map(value => formatTime(value));
|
let formattedXVal = xVal.map(value => formatTime(value));
|
||||||
formattedXVal = formatMaxTwo(formattedXVal);
|
formattedXVal = formatMaxTwo(formattedXVal);
|
||||||
let selectTimeMinIndex = getXIndex(xVal, this.selectDurationTime.min);
|
let selectTimeMinIndex = getXIndex(xVal, this.selectDurationTime.min);
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
datadata: function() {
|
datadata: function() {
|
||||||
// TODO Activity List 的 dblclick, drag & drop 要改假刪除
|
|
||||||
// Activity List 要排序
|
// Activity List 要排序
|
||||||
let newData;
|
let newData;
|
||||||
if(this.data !== null) {
|
if(this.data !== null) {
|
||||||
@@ -114,14 +113,16 @@ export default {
|
|||||||
// 拖曳結束要顯示箭頭,但最後一個不用
|
// 拖曳結束要顯示箭頭,但最後一個不用
|
||||||
const lastChild = evt.item.lastChild;
|
const lastChild = evt.item.lastChild;
|
||||||
const listIndex = this.listSequence.length - 1
|
const listIndex = this.listSequence.length - 1
|
||||||
evt.oldIndex !== listIndex ? lastChild.style.display = '' : null;
|
if (evt.oldIndex !== listIndex) {
|
||||||
|
lastChild.style.display = '';
|
||||||
|
}
|
||||||
// reset: 拖曳最後一個元素時,倒數第二的元素的箭頭要隱藏
|
// reset: 拖曳最後一個元素時,倒數第二的元素的箭頭要隱藏
|
||||||
this.lastItemIndex = null;
|
this.lastItemIndex = null;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
let newlist = JSON.parse(JSON.stringify(this.listSeq));
|
let newlist = JSON.parse(JSON.stringify(this.listSeq));
|
||||||
this.isSubmit ? this.listSequence = newlist : this.listSequence = [];
|
this.listSequence = this.isSubmit ? newlist : [];
|
||||||
this.$emitter.on('reset', (data) => {
|
this.$emitter.on('reset', (data) => {
|
||||||
this.listSequence = [];
|
this.listSequence = [];
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -182,116 +182,52 @@ export default {
|
|||||||
this.containstTasksData = data;
|
this.containstTasksData = data;
|
||||||
});
|
});
|
||||||
this.$emitter.on('actRadioData', (newData) => {
|
this.$emitter.on('actRadioData', (newData) => {
|
||||||
let data = JSON.parse(JSON.stringify(newData)); // 深拷貝原始 cases 的內容
|
let data = JSON.parse(JSON.stringify(newData)); // 深拷貝原始 cases 的內容
|
||||||
switch (data.category) {
|
|
||||||
// Activity sequence
|
const categoryMapping = {
|
||||||
case 'cfmSeqStart':
|
'cfmSeqStart': ['Start', 'selectCfmSeqStart', 'selectCfmSeqEnd'],
|
||||||
if(this.isStartSelected === true && data.task !== this.selectCfmSeqStart) this.selectCfmSeqEnd = null;
|
'cfmSeqEnd': ['End', 'selectCfmSeqEnd', 'selectCfmSeqStart'],
|
||||||
data.category = 'Start';
|
'cfmPtEteStart': ['Start', 'selectCfmPtEteStart'],
|
||||||
this.selectCfmSeqStart = data;
|
'cfmPtEteEnd': ['End', 'selectCfmPtEteEnd'],
|
||||||
break;
|
'cfmPtEteSEStart': ['Start', 'selectCfmPtEteSEStart', 'selectCfmPtEteSEEnd'],
|
||||||
case 'cfmSeqEnd':
|
'cfmPtEteSEEnd': ['End', 'selectCfmPtEteSEEnd', 'selectCfmPtEteSEStart'],
|
||||||
if(this.isEndSelected === true && data.task !== this.selectCfmSeqEnd)this.selectCfmSeqStart = null;
|
'cfmPtPStart': ['From', 'selectCfmPtPStart'],
|
||||||
data.category = 'End';
|
'cfmPtPEnd': ['To', 'selectCfmPtPEnd'],
|
||||||
this.selectCfmSeqEnd = data;
|
'cfmPtPSEStart': ['From', 'selectCfmPtPSEStart', 'selectCfmPtPSEEnd'],
|
||||||
break;
|
'cfmPtPSEEnd': ['To', 'selectCfmPtPSEEnd', 'selectCfmPtPSEStart'],
|
||||||
// Processing time
|
'cfmWtEteStart': ['Start', 'selectCfmWtEteStart'],
|
||||||
case 'cfmPtEteStart':
|
'cfmWtEteEnd': ['End', 'selectCfmWtEteEnd'],
|
||||||
data.category = 'Start';
|
'cfmWtEteSEStart': ['Start', 'selectCfmWtEteSEStart', 'selectCfmWtEteSEEnd'],
|
||||||
this.selectCfmPtEteStart = [data];
|
'cfmWtEteSEEnd': ['End', 'selectCfmWtEteSEEnd', 'selectCfmWtEteSEStart'],
|
||||||
break;
|
'cfmWtPStart': ['From', 'selectCfmWtPStart'],
|
||||||
case 'cfmPtEteEnd':
|
'cfmWtPEnd': ['To', 'selectCfmWtPEnd'],
|
||||||
data.category = 'End';
|
'cfmWtPSEStart': ['From', 'selectCfmWtPSEStart', 'selectCfmWtPSEEnd'],
|
||||||
this.selectCfmPtEteEnd = [data];
|
'cfmWtPSEEnd': ['To', 'selectCfmWtPSEEnd', 'selectCfmWtPSEStart'],
|
||||||
break;
|
'cfmCtEteStart': ['Start', 'selectCfmCtEteStart'],
|
||||||
case 'cfmPtEteSEStart':
|
'cfmCtEteEnd': ['End', 'selectCfmCtEteEnd'],
|
||||||
if(this.isStartSelected === true && data.task !== this.selectCfmPtEteSEStart) this.selectCfmPtEteSEEnd = null;
|
'cfmCtEteSEStart': ['Start', 'selectCfmCtEteSEStart', 'selectCfmCtEteSEEnd'],
|
||||||
data.category = 'Start';
|
'cfmCtEteSEEnd': ['End', 'selectCfmCtEteSEEnd', 'selectCfmCtEteSEStart']
|
||||||
this.selectCfmPtEteSEStart = data;
|
};
|
||||||
break;
|
|
||||||
case 'cfmPtEteSEEnd':
|
const updateSelection = (key, mainSelector, secondarySelector) => {
|
||||||
if(this.isEndSelected === true && data.task !== this.selectCfmPtEteSEEnd)this.selectCfmPtEteSEStart = null;
|
if (this[mainSelector]) {
|
||||||
data.category = 'End';
|
if (data.task !== this[mainSelector]) this[secondarySelector] = null;
|
||||||
this.selectCfmPtEteSEEnd = data;
|
}
|
||||||
break;
|
data.category = categoryMapping[key][0];
|
||||||
case 'cfmPtPStart':
|
this[mainSelector] = data;
|
||||||
data.category = 'From';
|
};
|
||||||
this.selectCfmPtPStart = [data];
|
|
||||||
break;
|
if (categoryMapping[data.category]) {
|
||||||
case 'cfmPtPEnd':
|
const [category, mainSelector, secondarySelector] = categoryMapping[data.category];
|
||||||
data.category = 'To';
|
if (secondarySelector) {
|
||||||
this.selectCfmPtPEnd = [data];
|
updateSelection(data.category, mainSelector, secondarySelector);
|
||||||
break;
|
} else {
|
||||||
case 'cfmPtPSEStart':
|
data.category = category;
|
||||||
if(this.isStartSelected === true && data.task !== this.selectCfmPtPSEStart) this.selectCfmPtPSEEnd = null;
|
this[mainSelector] = [data];
|
||||||
data.category = 'From';
|
}
|
||||||
this.selectCfmPtPSEStart = data;
|
} else if (this.selectedRuleType === 'Activity duration') {
|
||||||
break;
|
this.durationData = [data.task];
|
||||||
case 'cfmPtPSEEnd':
|
}
|
||||||
if(this.isEndSelected === true && data.task !== this.selectCfmPtPSEEnd)this.selectCfmPtPSEStart = null;
|
|
||||||
data.category = 'To';
|
|
||||||
this.selectCfmPtPSEEnd = data;
|
|
||||||
break;
|
|
||||||
// Waiting time
|
|
||||||
case 'cfmWtEteStart':
|
|
||||||
data.category = 'Start';
|
|
||||||
this.selectCfmWtEteStart = [data];
|
|
||||||
break;
|
|
||||||
case 'cfmWtEteEnd':
|
|
||||||
data.category = 'End';
|
|
||||||
this.selectCfmWtEteEnd = [data];
|
|
||||||
break;
|
|
||||||
case 'cfmWtEteSEStart':
|
|
||||||
if(this.isStartSelected === true && data.task !== this.selectCfmWtEteSEStart) this.selectCfmWtEteSEEnd = null;
|
|
||||||
data.category = 'Start';
|
|
||||||
this.selectCfmWtEteSEStart = data;
|
|
||||||
break;
|
|
||||||
case 'cfmWtEteSEEnd':
|
|
||||||
if(this.isEndSelected === true && data.task !== this.selectCfmWtEteSEEnd)this.selectCfmWtEteSEStart = null;
|
|
||||||
data.category = 'End';
|
|
||||||
this.selectCfmWtEteSEEnd = data;
|
|
||||||
break;
|
|
||||||
case 'cfmWtPStart':
|
|
||||||
data.category = 'From';
|
|
||||||
this.selectCfmWtPStart = [data];
|
|
||||||
break;
|
|
||||||
case 'cfmWtPEnd':
|
|
||||||
data.category = 'To';
|
|
||||||
this.selectCfmWtPEnd = [data];
|
|
||||||
break;
|
|
||||||
case 'cfmWtPSEStart':
|
|
||||||
if(this.isStartSelected === true && data.task !== this.selectCfmWtPSEStart) this.selectCfmWtPSEEnd = null;
|
|
||||||
data.category = 'From';
|
|
||||||
this.selectCfmWtPSEStart = data;
|
|
||||||
break;
|
|
||||||
case 'cfmWtPSEEnd':
|
|
||||||
if(this.isEndSelected === true && data.task !== this.selectCfmWtPSEEnd)this.selectCfmWtPSEStart = null;
|
|
||||||
data.category = 'To';
|
|
||||||
this.selectCfmWtPSEEnd = data;
|
|
||||||
break;
|
|
||||||
// Cycle time
|
|
||||||
case 'cfmCtEteStart':
|
|
||||||
data.category = 'Start';
|
|
||||||
this.selectCfmCtEteStart = [data];
|
|
||||||
break;
|
|
||||||
case 'cfmCtEteEnd':
|
|
||||||
data.category = 'End';
|
|
||||||
this.selectCfmCtEteEnd = [data];
|
|
||||||
break;
|
|
||||||
case 'cfmCtEteSEStart':
|
|
||||||
if(this.isStartSelected === true && data.task !== this.selectCfmCtEteSEStart) this.selectCfmCtEteSEEnd = null;
|
|
||||||
data.category = 'Start';
|
|
||||||
this.selectCfmCtEteSEStart = data;
|
|
||||||
break;
|
|
||||||
case 'cfmCtEteSEEnd':
|
|
||||||
if(this.isEndSelected === true && data.task !== this.selectCfmCtEteSEEnd)this.selectCfmCtEteSEStart = null;
|
|
||||||
data.category = 'End';
|
|
||||||
this.selectCfmCtEteSEEnd = data;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if(this.selectedRuleType === 'Activity duration') this.durationData = [data.task];
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
this.$emitter.on('getListSequence', (data) => {
|
this.$emitter.on('getListSequence', (data) => {
|
||||||
switch (data.category) {
|
switch (data.category) {
|
||||||
|
|||||||
@@ -288,7 +288,11 @@ export default {
|
|||||||
*/
|
*/
|
||||||
setStartAndEndData(data, category, task) {
|
setStartAndEndData(data, category, task) {
|
||||||
let oppositeCategory = '';
|
let oppositeCategory = '';
|
||||||
category === 'start' ? oppositeCategory = 'end' : oppositeCategory = 'start';
|
if (category === 'start') {
|
||||||
|
oppositeCategory = 'end';
|
||||||
|
} else {
|
||||||
|
oppositeCategory = 'start';
|
||||||
|
};
|
||||||
let newData = data.filter(i => i[category] === task).map(i => i[oppositeCategory]);
|
let newData = data.filter(i => i[category] === task).map(i => i[oppositeCategory]);
|
||||||
newData = [...new Set(newData)];
|
newData = [...new Set(newData)];
|
||||||
return newData;
|
return newData;
|
||||||
@@ -361,8 +365,6 @@ export default {
|
|||||||
this.task = this.isSubmitShowDataSeq.task;
|
this.task = this.isSubmitShowDataSeq.task;
|
||||||
this.isStartSelected = this.isSubmitShowDataSeq.isStartSelected;
|
this.isStartSelected = this.isSubmitShowDataSeq.isStartSelected;
|
||||||
this.isEndSelected = this.isSubmitShowDataSeq.isEndSelected;
|
this.isEndSelected = this.isSubmitShowDataSeq.isEndSelected;
|
||||||
// this.taskStart = this.isSubmitShowDataSeq.taskStart;
|
|
||||||
// this.taskEnd = this.isSubmitShowDataSeq.taskEnd;
|
|
||||||
break;
|
break;
|
||||||
case 'Processing time':
|
case 'Processing time':
|
||||||
switch (this.selectedProcessScope) {
|
switch (this.selectedProcessScope) {
|
||||||
@@ -370,45 +372,36 @@ export default {
|
|||||||
this.task = this.isSubmitShowDataPtEte.task;
|
this.task = this.isSubmitShowDataPtEte.task;
|
||||||
this.isStartSelected = this.isSubmitShowDataPtEte.isStartSelected;
|
this.isStartSelected = this.isSubmitShowDataPtEte.isStartSelected;
|
||||||
this.isEndSelected = this.isSubmitShowDataPtEte.isEndSelected;
|
this.isEndSelected = this.isSubmitShowDataPtEte.isEndSelected;
|
||||||
// this.taskStart = this.isSubmitShowDataPtEte.taskStart;
|
|
||||||
// this.taskEnd = this.isSubmitShowDataPtEte.taskEnd;
|
|
||||||
break;
|
break;
|
||||||
case 'Partial':
|
case 'Partial':
|
||||||
this.task = this.isSubmitShowDataPtP.task;
|
this.task = this.isSubmitShowDataPtP.task;
|
||||||
this.isStartSelected = this.isSubmitShowDataPtP.isStartSelected;
|
this.isStartSelected = this.isSubmitShowDataPtP.isStartSelected;
|
||||||
this.isEndSelected = this.isSubmitShowDataPtP.isEndSelected;
|
this.isEndSelected = this.isSubmitShowDataPtP.isEndSelected;
|
||||||
// this.taskStart = this.isSubmitShowDataPtP.taskStart;
|
|
||||||
// this.taskEnd = this.isSubmitShowDataPtP.taskEnd;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'Waiting time':
|
case 'Waiting time':
|
||||||
switch (this.selectedProcessScope) {
|
switch (this.selectedProcessScope) {
|
||||||
case 'End to end':
|
case 'End to end':
|
||||||
this.task = this.isSubmitShowDataWtEte.task;
|
this.task = this.isSubmitShowDataWtEte.task;
|
||||||
this.isStartSelected = this.isSubmitShowDataWtEte.isStartSelected;
|
this.isStartSelected = this.isSubmitShowDataWtEte.isStartSelected;
|
||||||
this.isEndSelected = this.isSubmitShowDataWtEte.isEndSelected;
|
this.isEndSelected = this.isSubmitShowDataWtEte.isEndSelected;
|
||||||
// this.taskStart = this.isSubmitShowDataWtEte.taskStart;
|
break;
|
||||||
// this.taskEnd = this.isSubmitShowDataWtEte.taskEnd;
|
case 'Partial':
|
||||||
break;
|
this.task = this.isSubmitShowDataWtP.task;
|
||||||
case 'Partial':
|
this.isStartSelected = this.isSubmitShowDataWtP.isStartSelected;
|
||||||
this.task = this.isSubmitShowDataWtP.task;
|
this.isEndSelected = this.isSubmitShowDataWtP.isEndSelected;
|
||||||
this.isStartSelected = this.isSubmitShowDataWtP.isStartSelected;
|
break;
|
||||||
this.isEndSelected = this.isSubmitShowDataWtP.isEndSelected;
|
default:
|
||||||
// this.taskStart = this.isSubmitShowDataWtP.taskStart;
|
break;
|
||||||
// this.taskEnd = this.isSubmitShowDataWtP.taskEnd;
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'Cycle time':
|
case 'Cycle time':
|
||||||
this.task = this.isSubmitShowDataCt.task;
|
this.task = this.isSubmitShowDataCt.task;
|
||||||
this.isStartSelected = this.isSubmitShowDataCt.isStartSelected;
|
this.isStartSelected = this.isSubmitShowDataCt.isStartSelected;
|
||||||
this.isEndSelected = this.isSubmitShowDataCt.isEndSelected;
|
this.isEndSelected = this.isSubmitShowDataCt.isEndSelected;
|
||||||
// this.taskStart = this.isSubmitShowDataCt.taskStart;
|
|
||||||
// this.taskEnd = this.isSubmitShowDataCt.taskEnd;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
</p>
|
</p>
|
||||||
<div class="overflow-y-scroll overflow-x-hidden scrollbar mx-[-8px] max-h-[calc(100%_-_96px)]" >
|
<div class="overflow-y-scroll overflow-x-hidden scrollbar mx-[-8px] max-h-[calc(100%_-_96px)]" >
|
||||||
<table class="border-separate border-spacing-x-2 text-sm">
|
<table class="border-separate border-spacing-x-2 text-sm">
|
||||||
|
<caption class="hidden">Trace List</caption>
|
||||||
<thead class="sticky top-0 z-10 bg-neutral-100">
|
<thead class="sticky top-0 z-10 bg-neutral-100">
|
||||||
<tr>
|
<tr>
|
||||||
<th class="h2 px-2 border-b border-neutral-500">Trace</th>
|
<th class="h2 px-2 border-b border-neutral-500">Trace</th>
|
||||||
@@ -285,7 +286,8 @@ export default {
|
|||||||
@apply sticky top-0 left-0 z-10 bg-neutral-10
|
@apply sticky top-0 left-0 z-10 bg-neutral-10
|
||||||
}
|
}
|
||||||
:deep(.p-datatable .p-datatable-thead > tr > th) {
|
:deep(.p-datatable .p-datatable-thead > tr > th) {
|
||||||
@apply !border-y-0 border-neutral-500 bg-neutral-100 after:absolute after:left-0 after:w-full after:h-full after:block after:top-0 after:border-b after:border-t after:border-neutral-500
|
@apply !border-y-0 border-neutral-500 bg-neutral-100 after:absolute after:left-0 after:w-full after:h-full after:block after:top-0 after:border-b after:border-t after:border-neutral-500;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
:deep(.p-datatable .p-datatable-tbody > tr > td) {
|
:deep(.p-datatable .p-datatable-tbody > tr > td) {
|
||||||
@apply border-neutral-500 !border-t-0 text-center
|
@apply border-neutral-500 !border-t-0 text-center
|
||||||
@@ -294,9 +296,6 @@ export default {
|
|||||||
:deep(.p-column-header-content) {
|
:deep(.p-column-header-content) {
|
||||||
@apply justify-center
|
@apply justify-center
|
||||||
}
|
}
|
||||||
:deep(.p-datatable .p-datatable-thead > tr > th) {
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
:deep(.p-datatable.p-datatable-gridlines .p-datatable-tbody > tr > td) {
|
:deep(.p-datatable.p-datatable-gridlines .p-datatable-tbody > tr > td) {
|
||||||
min-width: 72px;
|
min-width: 72px;
|
||||||
max-width: 184px;
|
max-width: 184px;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
<!-- Table -->
|
<!-- Table -->
|
||||||
<div class="overflow-y-auto overflow-x-auto scrollbar -mx-2 h-[calc(100%_-_64px)]">
|
<div class="overflow-y-auto overflow-x-auto scrollbar -mx-2 h-[calc(100%_-_64px)]">
|
||||||
<table class="border-separate border-spacing-x-2 table-auto min-w-full text-sm" :class="data.length === 0? 'h-full': null">
|
<table class="border-separate border-spacing-x-2 table-auto min-w-full text-sm" :class="data.length === 0? 'h-full': null">
|
||||||
|
<caption class="hidden">Activity List</caption>
|
||||||
<thead class="sticky top-0 left-0 z-10 bg-neutral-10">
|
<thead class="sticky top-0 left-0 z-10 bg-neutral-10">
|
||||||
<tr>
|
<tr>
|
||||||
<th class="text-start font-semibold leading-10 px-2 border-b border-neutral-500">Activity</th>
|
<th class="text-start font-semibold leading-10 px-2 border-b border-neutral-500">Activity</th>
|
||||||
@@ -85,8 +86,8 @@ export default {
|
|||||||
data: function() {
|
data: function() {
|
||||||
// Activity List 要排序
|
// Activity List 要排序
|
||||||
this.filteredData = this.filteredData.sort((x, y) => {
|
this.filteredData = this.filteredData.sort((x, y) => {
|
||||||
y.occurrences - x.occurrences
|
const diff = y.occurrences - x.occurrences;
|
||||||
if(y.occurrences === x.occurrences) sortNumEngZhtwForFilter(x.label, y.label);
|
return diff !== 0 ? diff : sortNumEngZhtwForFilter(x.label, y.label);
|
||||||
});
|
});
|
||||||
return this.filteredData;
|
return this.filteredData;
|
||||||
}
|
}
|
||||||
@@ -147,7 +148,9 @@ export default {
|
|||||||
// 拖曳結束要顯示箭頭,但最後一個不用
|
// 拖曳結束要顯示箭頭,但最後一個不用
|
||||||
const lastChild = evt.item.lastChild;
|
const lastChild = evt.item.lastChild;
|
||||||
const listIndex = this.listSequence.length - 1
|
const listIndex = this.listSequence.length - 1
|
||||||
evt.oldIndex !== listIndex ? lastChild.style.display = '' : null;
|
if (evt.oldIndex !== listIndex) {
|
||||||
|
lastChild.style.display = '';
|
||||||
|
}
|
||||||
// reset: 拖曳最後一個元素時,倒數第二的元素的箭頭要隱藏
|
// reset: 拖曳最後一個元素時,倒數第二的元素的箭頭要隱藏
|
||||||
this.lastItemIndex = null;
|
this.lastItemIndex = null;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
<div class="bg-neutral-10 border border-neutral-300 rounded-xl px-4 w-full h-full">
|
<div class="bg-neutral-10 border border-neutral-300 rounded-xl px-4 w-full h-full">
|
||||||
<div class="flex justify-between items-center my-2 flex-wrap">
|
<div class="flex justify-between items-center my-2 flex-wrap">
|
||||||
<p class="h2">{{ tableTitle }} ({{ tableData.length }})</p>
|
<p class="h2">{{ tableTitle }} ({{ tableData.length }})</p>
|
||||||
<!-- Search -->
|
|
||||||
<!-- <Search></Search> -->
|
|
||||||
</div>
|
</div>
|
||||||
<!-- Table -->
|
<!-- Table -->
|
||||||
<div class="overflow-y-auto overflow-x-auto scrollbar -mx-2 h-[calc(100%_-_64px)]">
|
<div class="overflow-y-auto overflow-x-auto scrollbar -mx-2 h-[calc(100%_-_64px)]">
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
<div class="bg-neutral-10 border border-neutral-300 rounded-xl px-4 h-full">
|
<div class="bg-neutral-10 border border-neutral-300 rounded-xl px-4 h-full">
|
||||||
<div class="flex justify-between items-center my-2">
|
<div class="flex justify-between items-center my-2">
|
||||||
<p class="h2">{{ tableTitle }} ({{ data.length }})</p>
|
<p class="h2">{{ tableTitle }} ({{ data.length }})</p>
|
||||||
<!-- Search -->
|
|
||||||
<!-- <Search></Search> -->
|
|
||||||
</div>
|
</div>
|
||||||
<!-- Table -->
|
<!-- Table -->
|
||||||
<div class="overflow-y-auto overflow-x-auto scrollbar -mx-2 h-[calc(100%_-_64px)]">
|
<div class="overflow-y-auto overflow-x-auto scrollbar -mx-2 h-[calc(100%_-_64px)]">
|
||||||
|
|||||||
@@ -134,6 +134,9 @@ export default {
|
|||||||
|
|
||||||
return { filterAttrs }
|
return { filterAttrs }
|
||||||
},
|
},
|
||||||
|
components: {
|
||||||
|
InputNumber,
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
selectedAttName: {},
|
selectedAttName: {},
|
||||||
@@ -182,9 +185,12 @@ export default {
|
|||||||
attRangeTotal: function() {
|
attRangeTotal: function() {
|
||||||
const type = this.selectedAttName.type;
|
const type = this.selectedAttName.type;
|
||||||
|
|
||||||
return !this.classTypes.includes(type) ? null
|
let result = null; // Initialize the result variable with null
|
||||||
: this.attRangeData ? `(${this.attRangeData.length})`
|
|
||||||
: null;
|
if (this.classTypes.includes(type) && this.attRangeData) {
|
||||||
|
result = `(${this.attRangeData.length})`; // Assign the length of attRangeData if it exists
|
||||||
|
}
|
||||||
|
return result;
|
||||||
},
|
},
|
||||||
attRangeData: function() {
|
attRangeData: function() {
|
||||||
let data = [];
|
let data = [];
|
||||||
@@ -203,7 +209,12 @@ export default {
|
|||||||
occ_ratio: this.getPercentLabel(ratio),
|
occ_ratio: this.getPercentLabel(ratio),
|
||||||
freq: item.freq
|
freq: item.freq
|
||||||
};
|
};
|
||||||
result.label = type !== 'boolean' ? null : item.value ? 'Yes' : 'No';
|
result.label = null;
|
||||||
|
if (type === 'boolean') {
|
||||||
|
result.label = item.value ? 'Yes' : 'No';
|
||||||
|
} else {
|
||||||
|
result.label = null;
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
})
|
})
|
||||||
return data.sort((x, y) => y.freq - x.freq);
|
return data.sort((x, y) => y.freq - x.freq);
|
||||||
@@ -224,6 +235,7 @@ export default {
|
|||||||
let max = this.valueData.max;
|
let max = this.valueData.max;
|
||||||
const type = this.valueData.type;
|
const type = this.valueData.type;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case 'dummy':
|
||||||
case 'date':
|
case 'date':
|
||||||
xAxisMin = new Date(min).getTime();
|
xAxisMin = new Date(min).getTime();
|
||||||
xAxisMax = new Date(max).getTime();
|
xAxisMax = new Date(max).getTime();
|
||||||
@@ -268,6 +280,7 @@ export default {
|
|||||||
const type = this.selectedAttName.type;
|
const type = this.selectedAttName.type;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case 'dummy': //sonar-qube
|
||||||
case 'date':
|
case 'date':
|
||||||
start = getMoment(this.startTime).format('YYYY-MM-DDTHH:mm:00');
|
start = getMoment(this.startTime).format('YYYY-MM-DDTHH:mm:00');
|
||||||
end = getMoment(this.endTime).format('YYYY-MM-DDTHH:mm:00');
|
end = getMoment(this.endTime).format('YYYY-MM-DDTHH:mm:00');
|
||||||
@@ -366,6 +379,7 @@ export default {
|
|||||||
const min = this.valueData.min;
|
const min = this.valueData.min;
|
||||||
const max = this.valueData.max;
|
const max = this.valueData.max;
|
||||||
switch (this.selectedAttName.type) {
|
switch (this.selectedAttName.type) {
|
||||||
|
case 'dummy': //sonar-qube
|
||||||
case 'date':
|
case 'date':
|
||||||
// 除了 date 外雙向綁定為空
|
// 除了 date 外雙向綁定為空
|
||||||
this.valueStart = null;
|
this.valueStart = null;
|
||||||
@@ -394,7 +408,7 @@ export default {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// 傳給後端
|
// 傳給後端
|
||||||
this.attValueTypeStartEnd;
|
// this.attValueTypeStartEnd; 是否有要呼叫函數? sonar-qube
|
||||||
// 建立圖表
|
// 建立圖表
|
||||||
this.createChart();
|
this.createChart();
|
||||||
}
|
}
|
||||||
@@ -470,9 +484,15 @@ export default {
|
|||||||
break;
|
break;
|
||||||
case 'float':
|
case 'float':
|
||||||
setLabels = data.map((item, index) => {
|
setLabels = data.map((item, index) => {
|
||||||
let x = index === 0 ? Math.floor(item.x * 100) / 100 :
|
let x;
|
||||||
index === data.length - 1 ? item.x = Math.ceil(item.x * 100) / 100 :
|
if (index === 0) {
|
||||||
Math.round(item.x * 100) / 100;
|
x = Math.floor(item.x * 100) / 100;
|
||||||
|
} else if (index === data.length - 1) {
|
||||||
|
item.x = Math.ceil(item.x * 100) / 100;
|
||||||
|
x = item.x;
|
||||||
|
} else {
|
||||||
|
x = Math.round(item.x * 100) / 100;
|
||||||
|
}
|
||||||
return x
|
return x
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
@@ -574,13 +594,21 @@ export default {
|
|||||||
maxRotation: 0, // 不旋轉 lable 0~50
|
maxRotation: 0, // 不旋轉 lable 0~50
|
||||||
color: '#334155',
|
color: '#334155',
|
||||||
callback: ((value, index, values) => {
|
callback: ((value, index, values) => {
|
||||||
|
let x;
|
||||||
switch (valueData.type) {
|
switch (valueData.type) {
|
||||||
case 'int':
|
case 'int':
|
||||||
return Math.round(value);
|
return Math.round(value);
|
||||||
case 'float':
|
case 'float':
|
||||||
let x = index === 0 ? Math.floor(value * 100) / 100 :
|
switch (index) {
|
||||||
index === values.length - 1 ? value = Math.ceil(value * 100) / 100 :
|
case 0:
|
||||||
Math.round(value * 100) / 100;
|
x = Math.floor(value * 100) / 100;
|
||||||
|
break;
|
||||||
|
case values.length - 1:
|
||||||
|
x = Math.ceil(value * 100) / 100;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
x = Math.round(value * 100) / 100;
|
||||||
|
}
|
||||||
// 處理科學記號等格式轉換
|
// 處理科學記號等格式轉換
|
||||||
// Decimal 無法處理超過 16 位數
|
// Decimal 無法處理超過 16 位數
|
||||||
x = new Intl.NumberFormat(undefined, {useGrouping: false}).format(x);
|
x = new Intl.NumberFormat(undefined, {useGrouping: false}).format(x);
|
||||||
@@ -607,6 +635,7 @@ export default {
|
|||||||
let end = sliderData[e[1].toFixed()]; // 取得 index,須為整數。
|
let end = sliderData[e[1].toFixed()]; // 取得 index,須為整數。
|
||||||
|
|
||||||
switch (this.selectedAttName.type) {
|
switch (this.selectedAttName.type) {
|
||||||
|
case 'dummy':
|
||||||
case 'date':
|
case 'date':
|
||||||
this.startTime = new Date(start);
|
this.startTime = new Date(start);
|
||||||
this.endTime = new Date(end);
|
this.endTime = new Date(end);
|
||||||
@@ -625,7 +654,7 @@ export default {
|
|||||||
// 重新算圖
|
// 重新算圖
|
||||||
this.resizeMask(this.chartComplete);
|
this.resizeMask(this.chartComplete);
|
||||||
// 執行 timeFrameStartEnd 才會改變數據
|
// 執行 timeFrameStartEnd 才會改變數據
|
||||||
this.attValueTypeStartEnd;
|
// this.attValueTypeStartEnd; 是否有要呼叫函數? sonar-qube
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 選取開始或結束時間時,要改變滑塊跟圖表
|
* 選取開始或結束時間時,要改變滑塊跟圖表
|
||||||
@@ -653,8 +682,20 @@ export default {
|
|||||||
this.selectArea = closestIndexes;
|
this.selectArea = closestIndexes;
|
||||||
// 重新設定 start end 日曆選取範圍
|
// 重新設定 start end 日曆選取範圍
|
||||||
if(!isDateType) inputValue = Number(e.value.replace(/,/g, '')) ;
|
if(!isDateType) inputValue = Number(e.value.replace(/,/g, '')) ;
|
||||||
if(direction === 'start') isDateType ? this.endMinDate = e : this.valueEndMin = inputValue;
|
if(direction === 'start') {
|
||||||
else if(direction === 'end') isDateType ? this.startMaxDate = e : this.valueStartMax = inputValue;
|
if(isDateType){
|
||||||
|
this.endMinDate = e;
|
||||||
|
} else {
|
||||||
|
this.valueEndMin = inputValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(direction === 'end') {
|
||||||
|
if(isDateType) {
|
||||||
|
this.startMaxDate = e;
|
||||||
|
} else {
|
||||||
|
this.valueStartMax = inputValue;
|
||||||
|
};
|
||||||
|
}
|
||||||
// 重新算圖
|
// 重新算圖
|
||||||
if(!isNaN(closestIndexes[0]) && !isNaN(closestIndexes[1])) this.resizeMask(this.chartComplete);
|
if(!isNaN(closestIndexes[0]) && !isNaN(closestIndexes[1])) this.resizeMask(this.chartComplete);
|
||||||
else return;
|
else return;
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ export default {
|
|||||||
const { isLoading } = storeToRefs(loadingStore);
|
const { isLoading } = storeToRefs(loadingStore);
|
||||||
const { hasResultRule, temporaryData, postRuleData, ruleData, isRuleData, tempFilterId } = storeToRefs(allMapDataStore);
|
const { hasResultRule, temporaryData, postRuleData, ruleData, isRuleData, tempFilterId } = storeToRefs(allMapDataStore);
|
||||||
|
|
||||||
return { isLoading, hasResultRule, temporaryData, postRuleData, ruleData, isRuleData, allMapDataStore, tempFilterId, allMapDataStore }
|
return { isLoading, hasResultRule, temporaryData, postRuleData, ruleData, isRuleData, allMapDataStore, tempFilterId }
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -103,17 +103,20 @@ export default{
|
|||||||
let d = this.filterTimeframe.data[0].y;
|
let d = this.filterTimeframe.data[0].y;
|
||||||
let e = 2;
|
let e = 2;
|
||||||
let f = this.filterTimeframe.data[1].y;
|
let f = this.filterTimeframe.data[1].y;
|
||||||
b = (e*d - a*d - f*a - f*c) / (e - c - a)
|
b = (e*d - a*d - f*a - f*c) / (e - c - a);
|
||||||
b < 0 ? b = 0 : b;
|
if(b < 0) {
|
||||||
|
b = 0;
|
||||||
|
}
|
||||||
// y 軸最大值
|
// y 軸最大值
|
||||||
let ma = 9;
|
let ma = 9;
|
||||||
let mb = this.filterTimeframe.data[8].y;
|
let mb = this.filterTimeframe.data[8].y;
|
||||||
let mc = 10;
|
let mc = 10;
|
||||||
let md = this.filterTimeframe.data[9].y;
|
let md = this.filterTimeframe.data[9].y;
|
||||||
let me = 11;
|
let me = 11;
|
||||||
let mf;
|
let mf = (mb*me - mb*mc -md*me + md*ma) / (ma - mc);
|
||||||
mf = (mb*me - mb*mc -md*me + md*ma) / (ma - mc);
|
if(mf < 0) {
|
||||||
mf < 0 ? mf = 0 : mf;
|
mf = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// 添加最小值
|
// 添加最小值
|
||||||
data.unshift({
|
data.unshift({
|
||||||
@@ -304,7 +307,7 @@ export default{
|
|||||||
// 重新算圖
|
// 重新算圖
|
||||||
this.resizeMask(this.chart);
|
this.resizeMask(this.chart);
|
||||||
// 執行 timeFrameStartEnd 才會改變數據
|
// 執行 timeFrameStartEnd 才會改變數據
|
||||||
this.timeFrameStartEnd;
|
this.timeFrameStartEnd();
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 選取開始或結束時間時,要改變滑塊跟圖表
|
* 選取開始或結束時間時,要改變滑塊跟圖表
|
||||||
@@ -347,7 +350,7 @@ export default{
|
|||||||
// 讓日曆的範圍等於時間軸的範圍
|
// 讓日曆的範圍等於時間軸的範圍
|
||||||
this.startTime = this.startMinDate;
|
this.startTime = this.startMinDate;
|
||||||
this.endTime = this.startMaxDate;
|
this.endTime = this.startMaxDate;
|
||||||
this.timeFrameStartEnd;
|
this.timeFrameStartEnd();
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
</p>
|
</p>
|
||||||
<div class="overflow-y-scroll overflow-x-hidden scrollbar mx-[-8px] max-h-[calc(100%_-_96px)]" >
|
<div class="overflow-y-scroll overflow-x-hidden scrollbar mx-[-8px] max-h-[calc(100%_-_96px)]" >
|
||||||
<table class="border-separate border-spacing-x-2 text-sm w-full">
|
<table class="border-separate border-spacing-x-2 text-sm w-full">
|
||||||
|
<caption class="hidden">Trace list</caption>
|
||||||
<thead class="sticky top-0 z-10 bg-neutral-10">
|
<thead class="sticky top-0 z-10 bg-neutral-10">
|
||||||
<tr>
|
<tr>
|
||||||
<th class="h2 px-2 border-b border-neutral-500">Trace</th>
|
<th class="h2 px-2 border-b border-neutral-500">Trace</th>
|
||||||
@@ -161,7 +162,7 @@ export default {
|
|||||||
{ field: 'id', header: 'Case Id' },
|
{ field: 'id', header: 'Case Id' },
|
||||||
{ field: 'started_at', header: 'Start time' },
|
{ field: 'started_at', header: 'Start time' },
|
||||||
{ field: 'completed_at', header: 'End time' },
|
{ field: 'completed_at', header: 'End time' },
|
||||||
...data[0]?.attributes.map((att, index) => ({ field: `att_${index}`, header: att.key })),
|
...(data[0]?.attributes ?? []).map((att, index) => ({ field: `att_${index}`, header: att.key })),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
@@ -256,7 +257,6 @@ export default {
|
|||||||
async switchCaseData(id, count) {
|
async switchCaseData(id, count) {
|
||||||
// 點同一筆 id 不要有動作
|
// 點同一筆 id 不要有動作
|
||||||
if(id == this.showTraceId) return;
|
if(id == this.showTraceId) return;
|
||||||
// if(count >= 1000) this.isLoading = true; // 超過 1000 筆要 loading 畫面
|
|
||||||
this.isLoading = true; // 都要 loading 畫面
|
this.isLoading = true; // 都要 loading 畫面
|
||||||
this.infinit404 = null;
|
this.infinit404 = null;
|
||||||
this.infinitMaxItems = false;
|
this.infinitMaxItems = false;
|
||||||
@@ -363,14 +363,12 @@ export default {
|
|||||||
@apply sticky top-0 left-0 z-10 bg-neutral-10
|
@apply sticky top-0 left-0 z-10 bg-neutral-10
|
||||||
}
|
}
|
||||||
:deep(.p-datatable .p-datatable-thead > tr > th) {
|
:deep(.p-datatable .p-datatable-thead > tr > th) {
|
||||||
@apply !border-y-0 border-neutral-500 bg-neutral-100 after:absolute after:left-0 after:w-full after:h-full after:block after:top-0 after:border-b after:border-t after:border-neutral-500
|
@apply !border-y-0 border-neutral-500 bg-neutral-100 after:absolute after:left-0 after:w-full after:h-full after:block after:top-0 after:border-b after:border-t after:border-neutral-500;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
:deep(.p-datatable .p-datatable-tbody > tr > td) {
|
:deep(.p-datatable .p-datatable-tbody > tr > td) {
|
||||||
@apply border-neutral-500 !border-t-0 text-center
|
@apply border-neutral-500 !border-t-0 text-center
|
||||||
}
|
}
|
||||||
:deep(.p-datatable .p-datatable-thead > tr > th) {
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
:deep(.p-datatable.p-datatable-gridlines .p-datatable-tbody > tr > td) {
|
:deep(.p-datatable.p-datatable-gridlines .p-datatable-tbody > tr > td) {
|
||||||
min-width: 72px;
|
min-width: 72px;
|
||||||
max-width: 184px;
|
max-width: 184px;
|
||||||
|
|||||||
@@ -38,14 +38,6 @@
|
|||||||
<label :for="item + index">{{ item }}</label>
|
<label :for="item + index">{{ item }}</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 目前只有 case -->
|
|
||||||
<!-- <div v-show="selectValue[0] === 'Attributes'">
|
|
||||||
<p class="h2">Mode</p>
|
|
||||||
<div v-for="(item, index) in selectFilter['ModeAtt']" :key="index">
|
|
||||||
<RadioButton v-model="selectValue[4]" :inputId="item + index" name="ModeAtt" :value="item" class="mb-1 mr-2"/>
|
|
||||||
<label :for="item + index">{{ item }}</label>
|
|
||||||
</div>
|
|
||||||
</div> -->
|
|
||||||
<div>
|
<div>
|
||||||
<p class="h2">Refine</p>
|
<p class="h2">Refine</p>
|
||||||
<div v-for="(item, index) in selectFilter['Refine']" :key="index">
|
<div v-for="(item, index) in selectFilter['Refine']" :key="index">
|
||||||
@@ -218,60 +210,22 @@ export default {
|
|||||||
// Apply Button disabled setting
|
// Apply Button disabled setting
|
||||||
isDisabledButton: function() {
|
isDisabledButton: function() {
|
||||||
let disabled = true;
|
let disabled = true;
|
||||||
let sele = this.selectValue;
|
const { selectValue: sele, selectAttType: type } = this;
|
||||||
const type = this.selectAttType;
|
const firstSelection = sele[0];
|
||||||
|
|
||||||
switch(sele[0]) {
|
if (firstSelection === 'Sequence') {
|
||||||
case 'Sequence': // Filter Type 選 Sequence 的行為
|
disabled = this.handleSequenceSelection(sele);
|
||||||
switch(sele[1]) {
|
} else if (firstSelection === 'Attributes') {
|
||||||
case 'Have activity(s)': // Activity Sequence 選 Have activity(s) 的行為
|
disabled = this.handleAttributesSelection(type);
|
||||||
if(this.selectFilterTask && this.selectFilterTask?.length !== 0) disabled = false;
|
} else if (firstSelection === 'Trace') {
|
||||||
break;
|
disabled = this.handleTraceSelection();
|
||||||
case 'Start & End': // Activity Sequence 選 Start & End 的行為
|
} else if (firstSelection === 'Timeframes') {
|
||||||
switch(sele[2]) {
|
disabled = this.handleTimeframesSelection();
|
||||||
case 'Start':
|
|
||||||
if(this.selectFilterStart) disabled = false;
|
|
||||||
break;
|
|
||||||
case 'End':
|
|
||||||
if(this.selectFilterEnd) disabled = false;
|
|
||||||
break;
|
|
||||||
case 'Start & End':
|
|
||||||
if(this.selectFilterStartToEnd && this.selectFilterEndToStart) disabled = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'Sequence': // Activity Sequence 選 Sequence 的行為
|
|
||||||
if(this.listSeq.length >= 2) disabled = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'Attributes': // Activity Sequence 選 Attributes 的行為
|
|
||||||
switch (type) {
|
|
||||||
case 'string':
|
|
||||||
if(this.selectAttribute && this.selectAttribute.length > 0) disabled = false;
|
|
||||||
break;
|
|
||||||
case 'boolean':
|
|
||||||
if(this.selectAttribute?.key && this.selectAttribute?.label) disabled = false;
|
|
||||||
break;
|
|
||||||
case 'int':
|
|
||||||
case 'float':
|
|
||||||
case 'date':
|
|
||||||
if(this.selectAttribute?.key && this.selectAttribute?.min != null && this.selectAttribute?.max != null) disabled = false;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'Trace': // Filter Type 選 Trace 的行為
|
|
||||||
if(this.selectTraceArea[0] !== this.selectTraceArea[1]) disabled = false;
|
|
||||||
break;
|
|
||||||
case 'Timeframes': // Filter Type 選 Timeframes 的行為
|
|
||||||
if(this.selectTimeFrame.length > 0) disabled = false;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.isDisabled = disabled;
|
this.isDisabled = disabled;
|
||||||
return disabled;
|
return disabled;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
/**
|
/**
|
||||||
@@ -442,60 +396,39 @@ export default {
|
|||||||
'occurred-around' : 'active in'
|
'occurred-around' : 'active in'
|
||||||
};
|
};
|
||||||
|
|
||||||
switch(e.type){
|
switch(e.type) { //sonar-qube
|
||||||
case "contains-task":
|
case "contains-task":
|
||||||
label = `${includeStr}, ${e.task}`;
|
|
||||||
type = "Sequence";
|
|
||||||
break;
|
|
||||||
case "starts-with":
|
case "starts-with":
|
||||||
label = `${includeStr}, start with ${e.task}`;
|
|
||||||
type = "Sequence";
|
|
||||||
break;
|
|
||||||
case "ends-with":
|
case "ends-with":
|
||||||
label = `${includeStr}, end with ${e.task}`;
|
|
||||||
type = "Sequence";
|
|
||||||
break;
|
|
||||||
case "start-end":
|
|
||||||
label = `${includeStr}, start with ${e.starts_with}, end with ${e.ends_with}`;
|
|
||||||
type = "Sequence";
|
|
||||||
break;
|
|
||||||
case "directly-follows":
|
case "directly-follows":
|
||||||
label = `${includeStr}, directly follows, ${e.task_seq.join(' -> ')}`;
|
|
||||||
type = "Sequence";
|
|
||||||
break;
|
|
||||||
case "eventually-follows":
|
case "eventually-follows":
|
||||||
label = `${includeStr}, eventually follows, ${e.task_seq.join(' -> ')}`;
|
label = `${includeStr}, ${getTaskLabel(e)}`;
|
||||||
type = "Sequence";
|
type = "Sequence";
|
||||||
break;
|
break;
|
||||||
|
case "start-end":
|
||||||
|
label = `${includeStr}, start with ${e.starts_with}, end with ${e.ends_with}`;
|
||||||
|
type = "Sequence";
|
||||||
|
break;
|
||||||
case "trace-freq":
|
case "trace-freq":
|
||||||
label = `${includeStr}, from #${e.lower} to #${e.upper}`;
|
label = `${includeStr}, from #${e.lower} to #${e.upper}`;
|
||||||
type = "Trace";
|
type = "Trace";
|
||||||
break;
|
break;
|
||||||
case 'string-attr':
|
case 'string-attr':
|
||||||
label = `${includeStr}, ${e.key}, ${e.value}`;
|
|
||||||
type = "Attributes";
|
|
||||||
break;
|
|
||||||
case 'boolean-attr':
|
case 'boolean-attr':
|
||||||
label = `${includeStr}, ${e.key}, ${this.selectAttribute?.label}`;
|
|
||||||
type = "Attributes";
|
|
||||||
break;
|
|
||||||
case 'int-attr':
|
case 'int-attr':
|
||||||
case 'float-attr':
|
case 'float-attr':
|
||||||
label = `${includeStr}, ${e.key}, from ${e.min} to ${e.max}`;
|
|
||||||
type = "Attributes";
|
|
||||||
break;
|
|
||||||
case 'date-attr':
|
case 'date-attr':
|
||||||
label = `${includeStr}, ${e.key}, from ${getMoment(e.min).format('YYYY-MM-DD HH:mm')} to ${getMoment(e.max).format('YYYY-MM-DD HH:mm')}`;
|
label = `${includeStr}, ${getAttributeLabel(e)}`;
|
||||||
type = "Attributes";
|
type = "Attributes";
|
||||||
break;
|
break;
|
||||||
case "occurred-in":
|
case "occurred-in":
|
||||||
case "started-in":
|
case "started-in":
|
||||||
case "completed-in":
|
case "completed-in":
|
||||||
case "occurred-around":
|
case "occurred-around":
|
||||||
label = `${containmentMap[e.type]}, ${includeStr}, from ${getMoment(e.start).format("YYYY-MM-DD HH:mm")} to ${getMoment(e.end).format("YYYY-MM-DD HH:mm")} `
|
label = `${containmentMap[e.type]}, ${includeStr}, from ${getMoment(e.start).format("YYYY-MM-DD HH:mm")} to ${getMoment(e.end).format("YYYY-MM-DD HH:mm")} `;
|
||||||
type = "Timeframe"
|
type = "Timeframe"
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
type,
|
type,
|
||||||
label,
|
label,
|
||||||
@@ -528,7 +461,9 @@ export default {
|
|||||||
this.$refs.filterTraceView.selectArea = [0, this.$refs.filterTraceView.traceTotal];
|
this.$refs.filterTraceView.selectArea = [0, this.$refs.filterTraceView.traceTotal];
|
||||||
};
|
};
|
||||||
// 成功訊息
|
// 成功訊息
|
||||||
massage ? this.$toast.success('Filter cleared.') : null;
|
if(message) {
|
||||||
|
this.$toast.success('Filter cleared.')
|
||||||
|
}
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* header:Filter 發送選取的資料
|
* header:Filter 發送選取的資料
|
||||||
@@ -537,7 +472,7 @@ export default {
|
|||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
let data;
|
let data;
|
||||||
let sele = this.selectValue;
|
let sele = this.selectValue;
|
||||||
let isExclude = sele[5] === 'Exclude' ? true : false;
|
let isExclude = sele[5] === 'Exclude';
|
||||||
let containmentMap = {
|
let containmentMap = {
|
||||||
'Contained in': 'occurred-in',
|
'Contained in': 'occurred-in',
|
||||||
'Started in': 'started-in',
|
'Started in': 'started-in',
|
||||||
@@ -641,16 +576,17 @@ export default {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'Trace': // Filter Type 選 Trace 的行為
|
case 'Trace': { // Filter Type 選 Trace 的行為
|
||||||
let lowerIndex = this.$refs.filterTraceView.selectArea[0];
|
const lowerIndex = this.$refs.filterTraceView.selectArea[0];
|
||||||
let upperIndex = this.$refs.filterTraceView.selectArea[1]-1;
|
const upperIndex = this.$refs.filterTraceView.selectArea[1]-1;
|
||||||
data = {
|
data = {
|
||||||
type: 'trace-freq',
|
type: 'trace-freq',
|
||||||
lower: this.allMapDataStore.traces[lowerIndex].id,
|
lower: this.allMapDataStore.traces[lowerIndex].id,
|
||||||
upper: this.allMapDataStore.traces[upperIndex].id,
|
upper: this.allMapDataStore.traces[upperIndex].id,
|
||||||
is_exclude: isExclude,
|
is_exclude: isExclude,
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 'Timeframes': // Filter Type 選 Timeframes 的行為
|
case 'Timeframes': // Filter Type 選 Timeframes 的行為
|
||||||
data = {
|
data = {
|
||||||
type: containmentMap[sele[6]],
|
type: containmentMap[sele[6]],
|
||||||
@@ -668,7 +604,10 @@ export default {
|
|||||||
await this.allMapDataStore.checkHasResult();
|
await this.allMapDataStore.checkHasResult();
|
||||||
|
|
||||||
// 有 Data 就加進 Funnel,沒有 Data 不加進 Funnel 和跳錯誤訊息
|
// 有 Data 就加進 Funnel,沒有 Data 不加進 Funnel 和跳錯誤訊息
|
||||||
if(this.hasResultRule === null) return this.isLoading = false;
|
if(this.hasResultRule === null) {
|
||||||
|
this.isLoading = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
else if(this.hasResultRule) {
|
else if(this.hasResultRule) {
|
||||||
if(!this.temporaryData?.length){
|
if(!this.temporaryData?.length){
|
||||||
this.temporaryData.push(...postData);
|
this.temporaryData.push(...postData);
|
||||||
@@ -680,13 +619,11 @@ export default {
|
|||||||
this.ruleData.push(...postData.map(e => this.setRule(e)))
|
this.ruleData.push(...postData.map(e => this.setRule(e)))
|
||||||
}
|
}
|
||||||
this.reset(false);
|
this.reset(false);
|
||||||
// this.isLoading = true;
|
|
||||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
this.$toast.success('Filter applied. Go to Funnel to verify.');
|
this.$toast.success('Filter applied. Go to Funnel to verify.');
|
||||||
}else {
|
}else {
|
||||||
this.reset(false);
|
this.reset(false);
|
||||||
// this.isLoading = true;
|
|
||||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
this.$toast.warning('No result.');
|
this.$toast.warning('No result.');
|
||||||
@@ -698,6 +635,78 @@ export default {
|
|||||||
sumbitAll() {
|
sumbitAll() {
|
||||||
this.$emit('submit-all');
|
this.$emit('submit-all');
|
||||||
},
|
},
|
||||||
|
handleSequenceSelection(sele) {
|
||||||
|
const secondSelection = sele[1];
|
||||||
|
|
||||||
|
switch (secondSelection) {
|
||||||
|
case 'Have activity(s)':
|
||||||
|
return !(this.selectFilterTask && this.selectFilterTask.length !== 0);
|
||||||
|
case 'Start & End':
|
||||||
|
return this.handleStartEndSelection(sele[2]);
|
||||||
|
case 'Sequence':
|
||||||
|
return this.listSeq.length < 2;
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleStartEndSelection(option) {
|
||||||
|
switch (option) {
|
||||||
|
case 'Start':
|
||||||
|
return !this.selectFilterStart;
|
||||||
|
case 'End':
|
||||||
|
return !this.selectFilterEnd;
|
||||||
|
case 'Start & End':
|
||||||
|
return !(this.selectFilterStartToEnd && this.selectFilterEndToStart);
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleAttributesSelection(type) {
|
||||||
|
switch (type) {
|
||||||
|
case 'string':
|
||||||
|
return !(this.selectAttribute && this.selectAttribute.length > 0);
|
||||||
|
case 'boolean':
|
||||||
|
return !(this.selectAttribute?.key && this.selectAttribute?.label);
|
||||||
|
case 'int':
|
||||||
|
case 'float':
|
||||||
|
case 'date':
|
||||||
|
return !(this.selectAttribute?.key && this.selectAttribute?.min != null && this.selectAttribute?.max != null);
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleTraceSelection() {
|
||||||
|
return this.selectTraceArea[0] === this.selectTraceArea[1];
|
||||||
|
},
|
||||||
|
handleTimeframesSelection() {
|
||||||
|
return this.selectTimeFrame.length === 0;
|
||||||
|
},
|
||||||
|
getTaskLabel(e) {
|
||||||
|
switch (e.type) {
|
||||||
|
case "contains-task":
|
||||||
|
return `${e.task}`;
|
||||||
|
case "starts-with":
|
||||||
|
return `start with ${e.task}`;
|
||||||
|
case "ends-with":
|
||||||
|
return `end with ${e.task}`;
|
||||||
|
case "directly-follows":
|
||||||
|
case "eventually-follows":
|
||||||
|
return `${e.type.replace('-', ' ')}, ${e.task_seq.join(' -> ')}`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getAttributeLabel(e) {
|
||||||
|
switch (e.type) {
|
||||||
|
case 'string-attr':
|
||||||
|
return `${e.key}, ${e.value}`;
|
||||||
|
case 'boolean-attr':
|
||||||
|
return `${e.key}, ${this.selectAttribute?.label}`;
|
||||||
|
case 'int-attr':
|
||||||
|
case 'float-attr':
|
||||||
|
return `${e.key}, from ${e.min} to ${e.max}`;
|
||||||
|
case 'date-attr':
|
||||||
|
return `${e.key}, from ${getMoment(e.min).format('YYYY-MM-DD HH:mm')} to ${getMoment(e.max).format('YYYY-MM-DD HH:mm')}`;
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -62,6 +62,8 @@
|
|||||||
<div class="pt-1 pb-4">
|
<div class="pt-1 pb-4">
|
||||||
<p class="h2">Case Duration</p>
|
<p class="h2">Case Duration</p>
|
||||||
<table class="text-sm caseDurationTable">
|
<table class="text-sm caseDurationTable">
|
||||||
|
<caption class="hidden">Case Duration</caption>
|
||||||
|
<th class="hidden"></th>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
@@ -189,7 +191,9 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel header="Most Frequent Trace" contentClass="text-sm">
|
<TabPanel header="Most Frequent Trace" contentClass="text-sm">
|
||||||
<li v-if="insights.most_freq_traces.length === 0">No data</li>
|
<ul v-if="insights.most_freq_traces.length === 0">
|
||||||
|
<li >No data</li>
|
||||||
|
</ul>
|
||||||
<ul v-else class="list-disc ml-6 space-y-1">
|
<ul v-else class="list-disc ml-6 space-y-1">
|
||||||
<li class="break-words" v-for="(item, key) in insights.most_freq_traces" :key="key">
|
<li class="break-words" v-for="(item, key) in insights.most_freq_traces" :key="key">
|
||||||
<span v-for="(value, index) in item" :key="index">{{ value }}<span v-if="index !== item.length - 1"> <span class="material-symbols-outlined !text-lg align-sub">arrow_forward</span> </span>
|
<span v-for="(value, index) in item" :key="index">{{ value }}<span v-if="index !== item.length - 1"> <span class="material-symbols-outlined !text-lg align-sub">arrow_forward</span> </span>
|
||||||
@@ -297,9 +301,6 @@ export default {
|
|||||||
:deep(.p-tabview-panel) {
|
:deep(.p-tabview-panel) {
|
||||||
@apply animate-fadein
|
@apply animate-fadein
|
||||||
}
|
}
|
||||||
/* .caseDurationTable td:first-child {
|
|
||||||
@apply pr-1
|
|
||||||
} */
|
|
||||||
.caseDurationTable td {
|
.caseDurationTable td {
|
||||||
@apply scroll-pb-12
|
@apply scroll-pb-12
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
</p>
|
</p>
|
||||||
<div class="overflow-y-scroll overflow-x-hidden scrollbar mx-[-8px] max-h-[calc(100%_-_96px)]" >
|
<div class="overflow-y-scroll overflow-x-hidden scrollbar mx-[-8px] max-h-[calc(100%_-_96px)]" >
|
||||||
<table class="border-separate border-spacing-x-2 text-sm">
|
<table class="border-separate border-spacing-x-2 text-sm">
|
||||||
|
<caption class="hidden">Trace List</caption>
|
||||||
<thead class="sticky top-0 z-10 bg-neutral-10">
|
<thead class="sticky top-0 z-10 bg-neutral-10">
|
||||||
<tr>
|
<tr>
|
||||||
<th class="h2 px-2 border-b border-neutral-500">Trace</th>
|
<th class="h2 px-2 border-b border-neutral-500">Trace</th>
|
||||||
@@ -125,7 +126,7 @@ export default {
|
|||||||
{ field: 'id', header: 'Case Id' },
|
{ field: 'id', header: 'Case Id' },
|
||||||
{ field: 'started_at', header: 'Start time' },
|
{ field: 'started_at', header: 'Start time' },
|
||||||
{ field: 'completed_at', header: 'End time' },
|
{ field: 'completed_at', header: 'End time' },
|
||||||
...data[0]?.attributes.map((att, index) => ({ field: `att_${index}`, header: att.key })),
|
...(data[0]?.attributes ?? []).map((att, index) => ({ field: `att_${index}`, header: att.key })),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
@@ -175,7 +176,6 @@ export default {
|
|||||||
async switchCaseData(id, count) {
|
async switchCaseData(id, count) {
|
||||||
// 點同一筆 id 不要有動作
|
// 點同一筆 id 不要有動作
|
||||||
if(id == this.showTraceId) return;
|
if(id == this.showTraceId) return;
|
||||||
// if(count >= 1000) this.isLoading = true; // 超過 1000 筆要 loading 畫面
|
|
||||||
this.isLoading = true; // 都要 loading 畫面
|
this.isLoading = true; // 都要 loading 畫面
|
||||||
this.infinit404 = null;
|
this.infinit404 = null;
|
||||||
this.infinitMaxItems = false;
|
this.infinitMaxItems = false;
|
||||||
@@ -287,14 +287,12 @@ export default {
|
|||||||
@apply sticky top-0 left-0 z-10 bg-neutral-10
|
@apply sticky top-0 left-0 z-10 bg-neutral-10
|
||||||
}
|
}
|
||||||
:deep(.p-datatable .p-datatable-thead > tr > th) {
|
:deep(.p-datatable .p-datatable-thead > tr > th) {
|
||||||
@apply !border-y-0 border-neutral-500 bg-neutral-100 after:absolute after:left-0 after:w-full after:h-full after:block after:top-0 after:border-b after:border-t after:border-neutral-500
|
@apply !border-y-0 border-neutral-500 bg-neutral-100 after:absolute after:left-0 after:w-full after:h-full after:block after:top-0 after:border-b after:border-t after:border-neutral-500;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
:deep(.p-datatable .p-datatable-tbody > tr > td) {
|
:deep(.p-datatable .p-datatable-tbody > tr > td) {
|
||||||
@apply border-neutral-500 !border-t-0 text-center
|
@apply border-neutral-500 !border-t-0 text-center
|
||||||
}
|
}
|
||||||
:deep(.p-datatable .p-datatable-thead > tr > th) {
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
:deep(.p-datatable.p-datatable-gridlines .p-datatable-tbody > tr > td) {
|
:deep(.p-datatable.p-datatable-gridlines .p-datatable-tbody > tr > td) {
|
||||||
min-width: 72px;
|
min-width: 72px;
|
||||||
max-width: 184px;
|
max-width: 184px;
|
||||||
|
|||||||
@@ -141,13 +141,13 @@ export default {
|
|||||||
if(e.target.value !== 'freq' && e.target.value !== 'duration') value = e.target.value;
|
if(e.target.value !== 'freq' && e.target.value !== 'duration') value = e.target.value;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'freq':
|
case 'freq':
|
||||||
value = value ? value : this.selectedFreq ? this.selectedFreq : 'total';
|
value = value || this.selectedFreq || 'total';
|
||||||
this.dataLayerType = type;
|
this.dataLayerType = type;
|
||||||
this.dataLayerOption = value;
|
this.dataLayerOption = value;
|
||||||
this.selectedFreq = value;
|
this.selectedFreq = value;
|
||||||
break;
|
break;
|
||||||
case 'duration':
|
case 'duration':
|
||||||
value = value ? value : this.selectedDuration ? this.selectedDuration : 'total';
|
value = value || this.selectedDuration || 'total';
|
||||||
this.dataLayerType = type;
|
this.dataLayerType = type;
|
||||||
this.dataLayerOption = value;
|
this.dataLayerOption = value;
|
||||||
this.selectedDuration = value;
|
this.selectedDuration = value;
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
<li class="bg-neutral-10 rounded p-3 w-full">
|
<li class="bg-neutral-10 rounded p-3 w-full">
|
||||||
<div class="flex justify-between items-center mb-5">
|
<div class="flex justify-between items-center mb-5">
|
||||||
<p class="font-bold text-sm leading-8">Cases</p>
|
<p class="font-bold text-sm leading-8">Cases</p>
|
||||||
<!-- <span class="material-symbols-outlined text-base">info</span> -->
|
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-between items-center">
|
<div class="flex justify-between items-center">
|
||||||
<div class="mr-2 w-full">
|
<div class="mr-2 w-full">
|
||||||
@@ -18,7 +17,6 @@
|
|||||||
<li class="bg-neutral-10 rounded p-3 w-full">
|
<li class="bg-neutral-10 rounded p-3 w-full">
|
||||||
<div class="flex justify-between items-center mb-5">
|
<div class="flex justify-between items-center mb-5">
|
||||||
<p class="font-bold text-sm leading-8">Traces</p>
|
<p class="font-bold text-sm leading-8">Traces</p>
|
||||||
<!-- <span class="material-symbols-outlined text-base">info</span> -->
|
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-between items-center">
|
<div class="flex justify-between items-center">
|
||||||
<div class="mr-2 w-full">
|
<div class="mr-2 w-full">
|
||||||
@@ -31,7 +29,6 @@
|
|||||||
<li class="bg-neutral-10 rounded p-3 w-full">
|
<li class="bg-neutral-10 rounded p-3 w-full">
|
||||||
<div class="flex justify-between items-center mb-5">
|
<div class="flex justify-between items-center mb-5">
|
||||||
<p class="font-bold text-sm leading-8">Activity Instances</p>
|
<p class="font-bold text-sm leading-8">Activity Instances</p>
|
||||||
<!-- <span class="material-symbols-outlined text-base">info</span> -->
|
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-between items-center">
|
<div class="flex justify-between items-center">
|
||||||
<div class="mr-2 w-full">
|
<div class="mr-2 w-full">
|
||||||
@@ -44,7 +41,6 @@
|
|||||||
<li class="bg-neutral-10 rounded p-3 w-full">
|
<li class="bg-neutral-10 rounded p-3 w-full">
|
||||||
<div class="flex justify-between items-center mb-5">
|
<div class="flex justify-between items-center mb-5">
|
||||||
<p class="font-bold text-sm leading-8">Activities</p>
|
<p class="font-bold text-sm leading-8">Activities</p>
|
||||||
<!-- <span class="material-symbols-outlined text-base">info</span> -->
|
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-between items-center">
|
<div class="flex justify-between items-center">
|
||||||
<div class="mr-2 w-full">
|
<div class="mr-2 w-full">
|
||||||
|
|||||||
@@ -75,7 +75,11 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.$route.name === 'Login' || this.$route.name === 'NotFound404' ? this.showMember = false : this.showMember = true;
|
if (this.$route.name === 'Login' || this.$route.name === 'NotFound404') {
|
||||||
|
this.showMember = false
|
||||||
|
} else {
|
||||||
|
this.showMember = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,22 +24,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- Files Page: Search and Upload -->
|
<!-- Files Page: Search and Upload -->
|
||||||
<div class="flex justify-end items-center" v-if="navViewName === 'FILES'">
|
<div class="flex justify-end items-center" v-if="navViewName === 'FILES'">
|
||||||
<!-- <form role="search">
|
|
||||||
<label for="searchFiles" class="mr-4 relative">
|
|
||||||
<input type="search" id="searchFiles" placeholder="Search" class="px-5 py-2 w-72 rounded-full text-sm align-middle duration-300 border border-neutral-500 hover:border-neutral-300 focus:outline-none focus:ring focus:border-neutral-300">
|
|
||||||
<span class="absolute top-2 bottom-1.5 right-0.5 flex justify-center items-center gap-2">
|
|
||||||
<IconSetting class="w-6 h-6 cursor-pointer"></IconSetting>
|
|
||||||
<span class="w-px h-6 block after:border after:border-neutral-300 after:content-['']"></span>
|
|
||||||
<button class="pr-2">
|
|
||||||
<IconSearch class="w-6 h-6"></IconSearch>
|
|
||||||
</button>
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</form> -->
|
|
||||||
<!-- <label class="btn btn-sm btn-neutral cursor-pointer">
|
|
||||||
<input id="uploadFiles" class="hidden" type="file">
|
|
||||||
Upload
|
|
||||||
</label> -->
|
|
||||||
<div id="import_btn" class="btn btn-sm btn-neutral cursor-pointer" @click="uploadModal = true">
|
<div id="import_btn" class="btn btn-sm btn-neutral cursor-pointer" @click="uploadModal = true">
|
||||||
Import
|
Import
|
||||||
<UploadModal :visible="uploadModal" @closeModal="uploadModal = $event"></UploadModal>
|
<UploadModal :visible="uploadModal" @closeModal="uploadModal = $event"></UploadModal>
|
||||||
@@ -54,7 +38,6 @@
|
|||||||
:disabled="disabledSave" @click="saveModal">
|
:disabled="disabledSave" @click="saveModal">
|
||||||
Save
|
Save
|
||||||
</button>
|
</button>
|
||||||
<!-- <button class="btn btn-sm btn-neutral">Download</button> -->
|
|
||||||
</div>
|
</div>
|
||||||
<AcctMenu/>
|
<AcctMenu/>
|
||||||
</div>
|
</div>
|
||||||
@@ -122,16 +105,16 @@ export default {
|
|||||||
case 'Map':
|
case 'Map':
|
||||||
case 'CheckMap':
|
case 'CheckMap':
|
||||||
// 沒有 filter Id, 沒有暫存 tempFilterId Id 就不能存檔
|
// 沒有 filter Id, 沒有暫存 tempFilterId Id 就不能存檔
|
||||||
return this.tempFilterId ? false : true;
|
return !this.tempFilterId;
|
||||||
case 'Conformance':
|
case 'Conformance':
|
||||||
case 'CheckConformance':
|
case 'CheckConformance':
|
||||||
return this.conformanceFilterTempCheckId || this.conformanceLogTempCheckId ? false : true;
|
return !(this.conformanceFilterTempCheckId || this.conformanceLogTempCheckId);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
showIcon: function() {
|
showIcon: function() {
|
||||||
let result = true;
|
let result = true;
|
||||||
|
|
||||||
result = ['FILES', 'UPLOAD'].includes(this.navViewName) ? false : true;
|
result = !['FILES', 'UPLOAD'].includes(this.navViewName);
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
noShowSaveButton: function() {
|
noShowSaveButton: function() {
|
||||||
@@ -157,7 +140,7 @@ export default {
|
|||||||
if(this.$route.params.type === 'filter') {
|
if(this.$route.params.type === 'filter') {
|
||||||
this.createFilterId= this.$route.params.fileId;
|
this.createFilterId= this.$route.params.fileId;
|
||||||
}
|
}
|
||||||
this.showNavbarBreadcrumb = this.$route.matched[0].name !== ('AuthContainer') ? true : false;
|
this.showNavbarBreadcrumb = this.$route.matched[0].name !== ('AuthContainer');
|
||||||
this.getNavViewName();
|
this.getNavViewName();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -251,9 +234,12 @@ export default {
|
|||||||
break;
|
break;
|
||||||
case 'COMPARE':
|
case 'COMPARE':
|
||||||
switch(name) {
|
switch(name) {
|
||||||
|
case 'dummy':
|
||||||
case 'CompareDashboard':
|
case 'CompareDashboard':
|
||||||
valueToSet = 'DASHBOARD';
|
valueToSet = 'DASHBOARD';
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -274,7 +260,6 @@ export default {
|
|||||||
*/
|
*/
|
||||||
async saveModal() {
|
async saveModal() {
|
||||||
// 協助判斷 MAP, CONFORMANCE 儲存有「送出」或「取消」。
|
// 協助判斷 MAP, CONFORMANCE 儲存有「送出」或「取消」。
|
||||||
let isSaved;
|
|
||||||
// 傳給 Map,通知 Sidebar 要關閉。
|
// 傳給 Map,通知 Sidebar 要關閉。
|
||||||
this.$emitter.emit('saveModal', false);
|
this.$emitter.emit('saveModal', false);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<form role="search">
|
<form role="search">
|
||||||
<label for="searchFiles" class="mr-4 relative">
|
<label for="searchFiles" class="mr-4 relative" htmlFor="searchFiles">
|
||||||
<input type="search" id="searchFiles" placeholder="Search Activity" class="px-5 py-2 w-52 rounded-full text-sm align-middle duration-300 border bg-neutral-100 border-neutral-300 hover:border-neutral-500 focus:outline-none focus:ring focus:border-neutral-500">
|
<input type="search" id="searchFiles" placeholder="Search Activity" class="px-5 py-2 w-52 rounded-full text-sm align-middle
|
||||||
|
duration-300 border bg-neutral-100 border-neutral-300 hover:border-neutral-500 focus:outline-none focus:ring
|
||||||
|
focus:border-neutral-500">
|
||||||
<span class="absolute top-2 bottom-0.5 right-0.5 flex justify-center items-center gap-2">
|
<span class="absolute top-2 bottom-0.5 right-0.5 flex justify-center items-center gap-2">
|
||||||
<IconSetting class="w-6 h-6 cursor-pointer"></IconSetting>
|
<IconSetting class="w-6 h-6 cursor-pointer"></IconSetting>
|
||||||
<span class="w-px h-6 block after:border after:border-neutral-300 after:content-['']"></span>
|
<span class="w-px h-6 block after:border after:border-neutral-300 after:content-['']"></span>
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
v-closable="{id: size, handler: onClose}">
|
v-closable="{id: size, handler: onClose}">
|
||||||
<div class="duration-box" v-for="(unit, index) in inputTypes" :key="unit">
|
<div class="duration-box" v-for="(unit, index) in inputTypes" :key="unit">
|
||||||
<input
|
<input
|
||||||
|
id="input_duration_dhms"
|
||||||
type="text"
|
type="text"
|
||||||
class="duration duration-val input-dhms-field"
|
class="duration duration-val input-dhms-field"
|
||||||
:data-index="index"
|
:data-index="index"
|
||||||
@@ -32,7 +33,7 @@
|
|||||||
@keyup="onKeyUp"
|
@keyup="onKeyUp"
|
||||||
v-model="inputTimeFields[index]"
|
v-model="inputTimeFields[index]"
|
||||||
/>
|
/>
|
||||||
<label class="duration">{{ tUnits[unit].dsp }}</label>
|
<label class="duration" for="input_duration_dhms">{{ tUnits[unit].dsp }}</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -123,7 +124,6 @@ export default {
|
|||||||
this[unit] = newValues[unit].val;
|
this[unit] = newValues[unit].val;
|
||||||
const input = document.querySelector(`[data-tunit="${unit}"]`);
|
const input = document.querySelector(`[data-tunit="${unit}"]`);
|
||||||
if (input) {
|
if (input) {
|
||||||
// input.value = newValues[unit].val.toString().padStart(2, '0'); // 前綴要補 0
|
|
||||||
input.value = newValues[unit].val.toString();
|
input.value = newValues[unit].val.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -144,14 +144,18 @@ export default {
|
|||||||
max: {
|
max: {
|
||||||
handler: function(newValue, oldValue) {
|
handler: function(newValue, oldValue) {
|
||||||
this.maxTotal = newValue;
|
this.maxTotal = newValue;
|
||||||
this.size === 'max' && newValue !== oldValue ? this.createData() : null;
|
if(this.size === 'max' && newValue !== oldValue) {
|
||||||
|
this.createData();
|
||||||
|
};
|
||||||
},
|
},
|
||||||
immediate: true,
|
immediate: true,
|
||||||
},
|
},
|
||||||
min: {
|
min: {
|
||||||
handler: function(newValue, oldValue) {
|
handler: function(newValue, oldValue) {
|
||||||
this.minTotal = newValue;
|
this.minTotal = newValue;
|
||||||
this.size === 'min' && newValue !== oldValue ? this.createData() : null;
|
if( this.size === 'min' && newValue !== oldValue){
|
||||||
|
this.createData();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
immediate: true,
|
immediate: true,
|
||||||
},
|
},
|
||||||
@@ -192,10 +196,11 @@ export default {
|
|||||||
let baseInputValue = event.target.value;
|
let baseInputValue = event.target.value;
|
||||||
let decoratedInputValue;
|
let decoratedInputValue;
|
||||||
// 讓前綴數字自動補 0
|
// 讓前綴數字自動補 0
|
||||||
isNaN(event.target.value) ?
|
if(isNaN(event.target.value)){
|
||||||
event.target.value = '00' :
|
event.target.value = '00';
|
||||||
// event.target.value = event.target.value.toString().padStart(2, '0'); // 前綴要補 0
|
} else {
|
||||||
event.target.value = event.target.value.toString();
|
event.target.value = event.target.value.toString();
|
||||||
|
}
|
||||||
decoratedInputValue = event.target.value.toString();
|
decoratedInputValue = event.target.value.toString();
|
||||||
|
|
||||||
// 手 key 數值大於最大值時,要等於最大值
|
// 手 key 數值大於最大值時,要等於最大值
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ export async function saveFilter(addFilterId, next = null) {
|
|||||||
* @param { string } value File's name
|
* @param { string } value File's name
|
||||||
*/
|
*/
|
||||||
export async function savedSuccessfully(value) {
|
export async function savedSuccessfully(value) {
|
||||||
value = value ? value : '';
|
value = value || '';
|
||||||
await Swal.fire({
|
await Swal.fire({
|
||||||
title: 'SAVE COMPLETE',
|
title: 'SAVE COMPLETE',
|
||||||
html: `<span class="text-primary">${value}</span> has been saved in Lucia.`,
|
html: `<span class="text-primary">${value}</span> has been saved in Lucia.`,
|
||||||
@@ -132,7 +132,9 @@ export async function leaveFilter(next, addFilterId, toPath, logOut) {
|
|||||||
// console.log("PageAdminStore.activePage", PageAdminStore.activePage);
|
// console.log("PageAdminStore.activePage", PageAdminStore.activePage);
|
||||||
pageAdminStore.keepPreviousPage();
|
pageAdminStore.keepPreviousPage();
|
||||||
|
|
||||||
logOut ? null : next(false);
|
if(!logOut){
|
||||||
|
next(false);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
@@ -209,7 +211,9 @@ export async function leaveConformance(next, addConformanceCreateCheckId, toPath
|
|||||||
conformanceStore.conformanceLogTempCheckId = null;
|
conformanceStore.conformanceLogTempCheckId = null;
|
||||||
logOut ? logOut() : next(toPath);
|
logOut ? logOut() : next(toPath);
|
||||||
} else if(result.dismiss === 'backdrop') {
|
} else if(result.dismiss === 'backdrop') {
|
||||||
logOut ? null : next(false);
|
if(!logOut){
|
||||||
|
next(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
@@ -262,7 +266,7 @@ export async function uploadFailedSecond(detail) {
|
|||||||
|
|
||||||
detail.forEach(i => {
|
detail.forEach(i => {
|
||||||
let content = '';
|
let content = '';
|
||||||
|
let key = '';
|
||||||
switch (i.type) {
|
switch (i.type) {
|
||||||
case 'too_many':
|
case 'too_many':
|
||||||
manySrt = 'There are more errors.';
|
manySrt = 'There are more errors.';
|
||||||
@@ -273,9 +277,7 @@ export async function uploadFailedSecond(detail) {
|
|||||||
case 'malformed':
|
case 'malformed':
|
||||||
content = `<li>Data malformed in Timestamp Column: (Row #${i.loc[1]}, "${i.input}")</li>`;
|
content = `<li>Data malformed in Timestamp Column: (Row #${i.loc[1]}, "${i.input}")</li>`;
|
||||||
break;
|
break;
|
||||||
case 'missing':
|
case 'missing':
|
||||||
let key = '';
|
|
||||||
|
|
||||||
switch (i.loc[2]) {
|
switch (i.loc[2]) {
|
||||||
case 'case id':
|
case 'case id':
|
||||||
key = 'Case ID';
|
key = 'Case ID';
|
||||||
@@ -403,8 +405,7 @@ export async function renameModal(rename, type, id, baseName) {
|
|||||||
|
|
||||||
// 改名成功
|
// 改名成功
|
||||||
if(isConfirmed) await rename(type, id, value);
|
if(isConfirmed) await rename(type, id, value);
|
||||||
// 清空欄位
|
// 清空欄位 fileName = '';
|
||||||
fileName = '';
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Delete File
|
* Delete File
|
||||||
@@ -464,7 +465,6 @@ export async function reallyDeldetInformation(files, reallyDeldetData) {
|
|||||||
const filesStore = FilesStore();
|
const filesStore = FilesStore();
|
||||||
const deleteCustomClass = { ...customClass };
|
const deleteCustomClass = { ...customClass };
|
||||||
const htmlText = `<div class="text-left mx-4 space-y-1"><p>The following file(s) have been deleted by other user(s):</p><ul class="list-disc ml-6">${files}</ul></div>`;
|
const htmlText = `<div class="text-left mx-4 space-y-1"><p>The following file(s) have been deleted by other user(s):</p><ul class="list-disc ml-6">${files}</ul></div>`;
|
||||||
let recordIdData = [];
|
|
||||||
|
|
||||||
deleteCustomClass.confirmButton = '!inline-block !rounded-full !text-sm !font-medium !text-center !align-middle !transition-colors !duration-300 !px-5 !py-2 !w-[100px] !h-[40px] !text-primary !bg-neutral-10 !border !border-primary';
|
deleteCustomClass.confirmButton = '!inline-block !rounded-full !text-sm !font-medium !text-center !align-middle !transition-colors !duration-300 !px-5 !py-2 !w-[100px] !h-[40px] !text-primary !bg-neutral-10 !border !border-primary';
|
||||||
deleteCustomClass.cancelButton = null;
|
deleteCustomClass.cancelButton = null;
|
||||||
@@ -481,7 +481,7 @@ export async function reallyDeldetInformation(files, reallyDeldetData) {
|
|||||||
confirmButton.style.border = '1px solid #0099FF';
|
confirmButton.style.border = '1px solid #0099FF';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
recordIdData = await Promise.all(reallyDeldetData.map(file => filesStore.deletionRecord(file.id)));
|
await Promise.all(reallyDeldetData.map(file => filesStore.deletionRecord(file.id)));
|
||||||
await filesStore.fetchAllFiles();
|
await filesStore.fetchAllFiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -113,10 +113,17 @@ export default function cytoscapeMap(mapData, dataLayerType, dataLayerOption, cu
|
|||||||
// 可使用 parseInt(整數) parseFloat(浮點數) 將字串轉為數字
|
// 可使用 parseInt(整數) parseFloat(浮點數) 將字串轉為數字
|
||||||
// Relative 要轉為百分比 %
|
// Relative 要轉為百分比 %
|
||||||
if(node.data('type') === 'activity') {
|
if(node.data('type') === 'activity') {
|
||||||
|
let textInt;
|
||||||
|
let textFloat;
|
||||||
|
let textDurRel;
|
||||||
|
let timeLabelInt;
|
||||||
|
let timeLabelFloat;
|
||||||
|
let textTimeLabel;
|
||||||
|
|
||||||
switch(dataLayerType) {
|
switch(dataLayerType) {
|
||||||
case 'freq': // Frequency
|
case 'freq': // Frequency
|
||||||
let textInt = dataLayerOption === 'rel_freq' ? text + optionValue * 100 + "%" : text + optionValue;
|
textInt = dataLayerOption === 'rel_freq' ? text + optionValue * 100 + "%" : text + optionValue;
|
||||||
let textFloat = dataLayerOption === 'rel_freq'? text + (optionValue * 100).toFixed(2) + "%" : text + optionValue.toFixed(2);
|
textFloat = dataLayerOption === 'rel_freq'? text + (optionValue * 100).toFixed(2) + "%" : text + optionValue.toFixed(2);
|
||||||
|
|
||||||
// 判斷是否為整數,若非整數要取小數點後面兩個值。
|
// 判斷是否為整數,若非整數要取小數點後面兩個值。
|
||||||
text = Math.trunc(optionValue) === optionValue ? textInt : textFloat;
|
text = Math.trunc(optionValue) === optionValue ? textInt : textFloat;
|
||||||
@@ -124,13 +131,13 @@ export default function cytoscapeMap(mapData, dataLayerType, dataLayerOption, cu
|
|||||||
|
|
||||||
case 'duration': // Duration 除了 Relative 為百分比 % ,其他要轉變時間單位。
|
case 'duration': // Duration 除了 Relative 為百分比 % ,其他要轉變時間單位。
|
||||||
// Relative %
|
// Relative %
|
||||||
let textDurRel = text + (optionValue * 100).toFixed(2) + "%";
|
textDurRel = text + (optionValue * 100).toFixed(2) + "%";
|
||||||
// Timelabel
|
// Timelabel
|
||||||
let timeLabelInt = text + getTimeLabel(optionValue);
|
timeLabelInt = text + getTimeLabel(optionValue);
|
||||||
let timeLabelFloat = text + getTimeLabel(optionValue.toFixed(2));
|
timeLabelFloat = text + getTimeLabel(optionValue.toFixed(2));
|
||||||
|
|
||||||
// 判斷是否為整數,若非整數要取小數點後面兩個值。
|
// 判斷是否為整數,若非整數要取小數點後面兩個值。
|
||||||
let textTimeLabel = Math.trunc(optionValue) === optionValue ? timeLabelInt : timeLabelFloat;
|
textTimeLabel = Math.trunc(optionValue) === optionValue ? timeLabelInt : timeLabelFloat;
|
||||||
|
|
||||||
text = dataLayerOption === 'rel_duration' ? textDurRel : textTimeLabel;
|
text = dataLayerOption === 'rel_duration' ? textDurRel : textTimeLabel;
|
||||||
break;
|
break;
|
||||||
@@ -169,13 +176,18 @@ export default function cytoscapeMap(mapData, dataLayerType, dataLayerOption, cu
|
|||||||
'content': function(edge) { // 關係線顯示的文字
|
'content': function(edge) { // 關係線顯示的文字
|
||||||
let optionValue = edge.data(`${dataLayerType}.${dataLayerOption}`);
|
let optionValue = edge.data(`${dataLayerType}.${dataLayerOption}`);
|
||||||
let result = '';
|
let result = '';
|
||||||
|
let edgeInt;
|
||||||
|
let edgeFloat;
|
||||||
|
let edgeDurRel;
|
||||||
|
let timeLabelInt;
|
||||||
|
let timeLabelFloat;
|
||||||
|
let edgeTimeLabel;
|
||||||
if(optionValue === '') return optionValue;
|
if(optionValue === '') return optionValue;
|
||||||
|
|
||||||
switch(dataLayerType) {
|
switch(dataLayerType) {
|
||||||
case 'freq':
|
case 'freq':
|
||||||
let edgeInt = dataLayerOption === 'rel_freq' ? optionValue * 100 + "%" : optionValue;
|
edgeInt = dataLayerOption === 'rel_freq' ? optionValue * 100 + "%" : optionValue;
|
||||||
let edgeFloat = dataLayerOption === 'rel_freq' ? (optionValue * 100).toFixed(2) + "%" : optionValue.toFixed(2);
|
edgeFloat = dataLayerOption === 'rel_freq' ? (optionValue * 100).toFixed(2) + "%" : optionValue.toFixed(2);
|
||||||
|
|
||||||
// 判斷是否為整數,若非整數要取小數點後面兩個值。
|
// 判斷是否為整數,若非整數要取小數點後面兩個值。
|
||||||
result = Math.trunc(optionValue) === optionValue ? edgeInt : edgeFloat;
|
result = Math.trunc(optionValue) === optionValue ? edgeInt : edgeFloat;
|
||||||
@@ -183,11 +195,11 @@ export default function cytoscapeMap(mapData, dataLayerType, dataLayerOption, cu
|
|||||||
|
|
||||||
case 'duration': // Duration 除了 Relative 為百分比 % ,其他要轉變時間單位。
|
case 'duration': // Duration 除了 Relative 為百分比 % ,其他要轉變時間單位。
|
||||||
// Relative %
|
// Relative %
|
||||||
let edgeDurRel = (optionValue * 100).toFixed(2) + "%";
|
edgeDurRel = (optionValue * 100).toFixed(2) + "%";
|
||||||
// Timelabel
|
// Timelabel
|
||||||
let timeLabelInt = getTimeLabel(optionValue);
|
timeLabelInt = getTimeLabel(optionValue);
|
||||||
let timeLabelFloat = getTimeLabel(optionValue.toFixed(2));
|
timeLabelFloat = getTimeLabel(optionValue.toFixed(2));
|
||||||
let edgeTimeLabel = Math.trunc(optionValue) === optionValue ? timeLabelInt : timeLabelFloat;
|
edgeTimeLabel = Math.trunc(optionValue) === optionValue ? timeLabelInt : timeLabelFloat;
|
||||||
|
|
||||||
result = dataLayerOption === 'rel_duration' ? edgeDurRel : edgeTimeLabel;
|
result = dataLayerOption === 'rel_duration' ? edgeDurRel : edgeTimeLabel;
|
||||||
break;
|
break;
|
||||||
@@ -210,7 +222,7 @@ export default function cytoscapeMap(mapData, dataLayerType, dataLayerOption, cu
|
|||||||
// creat tippy.js
|
// creat tippy.js
|
||||||
let tip;
|
let tip;
|
||||||
cy.on('mouseover', 'node', function(event) {
|
cy.on('mouseover', 'node', function(event) {
|
||||||
var node = event.target
|
const node = event.target;
|
||||||
let ref = node.popperRef()
|
let ref = node.popperRef()
|
||||||
let dummyDomEle = document.createElement('div');
|
let dummyDomEle = document.createElement('div');
|
||||||
let content = document.createElement('div');
|
let content = document.createElement('div');
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ export default function cytoscapeMapTrace(nodes, edges, graphId) {
|
|||||||
// creat tippy.js
|
// creat tippy.js
|
||||||
let tip;
|
let tip;
|
||||||
cy.on('mouseover', 'node', function(event) {
|
cy.on('mouseover', 'node', function(event) {
|
||||||
var node = event.target
|
const node = event.target
|
||||||
let ref = node.popperRef()
|
let ref = node.popperRef()
|
||||||
let dummyDomEle = document.createElement('div');
|
let dummyDomEle = document.createElement('div');
|
||||||
let content = document.createElement('div');
|
let content = document.createElement('div');
|
||||||
@@ -97,7 +97,6 @@ export default function cytoscapeMapTrace(nodes, edges, graphId) {
|
|||||||
content:content
|
content:content
|
||||||
});
|
});
|
||||||
tip.show();
|
tip.show();
|
||||||
// if(node.data("label").length > 18) tip.show();
|
|
||||||
})
|
})
|
||||||
cy.on('mouseout', 'node', function(event) {
|
cy.on('mouseout', 'node', function(event) {
|
||||||
tip.hide();
|
tip.hide();
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export default function numberLabel(num) {
|
export default function numberLabel(num) {
|
||||||
var parts = num.toString().split('.');
|
let parts = num.toString().split('.');
|
||||||
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
||||||
return parts.join('.');
|
return parts.join('.');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -177,7 +177,6 @@ export function yTimeRange(data, yAmount, yMax) {
|
|||||||
* @returns {numver} x index
|
* @returns {numver} x index
|
||||||
*/
|
*/
|
||||||
export function getXIndex(data, xValue) {
|
export function getXIndex(data, xValue) {
|
||||||
let closestElement = data[0]; // 假定第一个元素是最接近的
|
|
||||||
let closestIndex = xValue; // 假定第一个元素的索引是 0
|
let closestIndex = xValue; // 假定第一个元素的索引是 0
|
||||||
let smallestDifference = Math.abs(xValue - data[0]); // 初始差值设为第一个元素与目标数的差值
|
let smallestDifference = Math.abs(xValue - data[0]); // 初始差值设为第一个元素与目标数的差值
|
||||||
|
|
||||||
@@ -185,7 +184,6 @@ export function getXIndex(data, xValue) {
|
|||||||
let difference = Math.abs(xValue - data[i]);
|
let difference = Math.abs(xValue - data[i]);
|
||||||
|
|
||||||
if (difference <= smallestDifference) {
|
if (difference <= smallestDifference) {
|
||||||
closestElement = data[i];
|
|
||||||
closestIndex = i;
|
closestIndex = i;
|
||||||
smallestDifference = difference;
|
smallestDifference = difference;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
export function sortNumEngZhtw(data) {
|
export function sortNumEngZhtw(data) {
|
||||||
return data.sort((a, b) => {
|
return data.sort((a, b) => {
|
||||||
// 檢查兩個值是否都是數字
|
// 檢查兩個值是否都是數字
|
||||||
var isANumber = !isNaN(parseFloat(a)) && isFinite(a);
|
const isANumber = !isNaN(parseFloat(a)) && isFinite(a);
|
||||||
var isBNumber = !isNaN(parseFloat(b)) && isFinite(b);
|
const isBNumber = !isNaN(parseFloat(b)) && isFinite(b);
|
||||||
|
|
||||||
// 如果兩個值都是數字,直接比較大小
|
// 如果兩個值都是數字,直接比較大小
|
||||||
if (isANumber && isBNumber) return parseFloat(a) - parseFloat(b);
|
if (isANumber && isBNumber) return parseFloat(a) - parseFloat(b);
|
||||||
@@ -28,8 +28,8 @@ export function sortNumEngZhtw(data) {
|
|||||||
*/
|
*/
|
||||||
export function sortNumEngZhtwForFilter(a, b) {
|
export function sortNumEngZhtwForFilter(a, b) {
|
||||||
// 檢查兩個值是否都是數字
|
// 檢查兩個值是否都是數字
|
||||||
var isANumber = !isNaN(parseFloat(a)) && isFinite(a);
|
const isANumber = !isNaN(parseFloat(a)) && isFinite(a);
|
||||||
var isBNumber = !isNaN(parseFloat(b)) && isFinite(b);
|
const isBNumber = !isNaN(parseFloat(b)) && isFinite(b);
|
||||||
|
|
||||||
// 如果兩個值都是數字,直接比較大小
|
// 如果兩個值都是數字,直接比較大小
|
||||||
if (isANumber && isBNumber) return parseFloat(a) - parseFloat(b);
|
if (isANumber && isBNumber) return parseFloat(a) - parseFloat(b);
|
||||||
|
|||||||
@@ -125,11 +125,12 @@ export default defineStore('conformanceStore', {
|
|||||||
c.completed_at = moment(c.completed_at).format('YYYY/MM/DD HH:mm');
|
c.completed_at = moment(c.completed_at).format('YYYY/MM/DD HH:mm');
|
||||||
c.facets.map(fac => {
|
c.facets.map(fac => {
|
||||||
switch(fac.type) {
|
switch(fac.type) {
|
||||||
|
case 'dummy': //sonar-qube
|
||||||
case 'duration-list':
|
case 'duration-list':
|
||||||
fac.value = fac.value.map(v => v !== null ? abbreviateNumber(new Decimal(v.toFixed(2))) : null);
|
fac.value = fac.value.map(v => v !== null ? abbreviateNumber(new Decimal(v.toFixed(2))) : null);
|
||||||
fac.value = (fac.value).map(v => v = v.trim()).join(', ');
|
fac.value = (fac.value).map(v => v.trim()).join(', ');
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
return fac;
|
return fac;
|
||||||
|
|||||||
@@ -214,7 +214,7 @@ export default defineStore('filesStore', {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const response = await axios.put(api, data);
|
await axios.put(api, data);
|
||||||
this.uploadFileName = null;
|
this.uploadFileName = null;
|
||||||
await this.fetchAllFiles();
|
await this.fetchAllFiles();
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
@@ -277,7 +277,6 @@ export default defineStore('filesStore', {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const response = await axios.delete(api);
|
|
||||||
await this.fetchAllFiles();
|
await this.fetchAllFiles();
|
||||||
await deleteSuccess();
|
await deleteSuccess();
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
@@ -296,7 +295,6 @@ export default defineStore('filesStore', {
|
|||||||
loading.isLoading = true;
|
loading.isLoading = true;
|
||||||
api = `/api/deletion/${id}`;
|
api = `/api/deletion/${id}`;
|
||||||
try {
|
try {
|
||||||
const response = await axios.delete(api);
|
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
apiError(error, 'Failed to Remove a Deletion Record.')
|
apiError(error, 'Failed to Remove a Deletion Record.')
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -441,7 +441,7 @@ console.log("TODO:", datasetsPrimary, )
|
|||||||
let yDataPrimary;
|
let yDataPrimary;
|
||||||
let labelPrimary = chartData.data[0].label;
|
let labelPrimary = chartData.data[0].label;
|
||||||
let datasetsSecondary = chartData.data[1].data;
|
let datasetsSecondary = chartData.data[1].data;
|
||||||
let xDataSecondary;
|
// let xDataSecondary;
|
||||||
let yDataSecondary;
|
let yDataSecondary;
|
||||||
let labelSecondary = chartData.data[1].label;
|
let labelSecondary = chartData.data[1].label;
|
||||||
let primeVueSetData = {};
|
let primeVueSetData = {};
|
||||||
@@ -462,7 +462,7 @@ console.log("TODO:", datasetsPrimary, )
|
|||||||
y: value.y === null ? null : value.y * 100
|
y: value.y === null ? null : value.y * 100
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
xDataSecondary = datasetsSecondary.map(i => i.x);
|
// xDataSecondary = datasetsSecondary.map(i => i.x);
|
||||||
yDataSecondary = datasetsSecondary.map(i => i.y);
|
yDataSecondary = datasetsSecondary.map(i => i.y);
|
||||||
|
|
||||||
primeVueSetData = {
|
primeVueSetData = {
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ export default {
|
|||||||
// .*$:匹配剩餘的字符,確保完整的提取。
|
// .*$:匹配剩餘的字符,確保完整的提取。
|
||||||
// |^.*$:在找不到 "luciaToken" 的情況下,匹配整個字符串。
|
// |^.*$:在找不到 "luciaToken" 的情況下,匹配整個字符串。
|
||||||
// 實際應用
|
// 實際應用
|
||||||
const token = document.cookie.replace(/(?:(?:^|.*;\s*)luciaToken\s*\=\s*([^;]*).*$)|^.*$/, "$1");
|
const token = document.cookie.replace(/(?:(?:^|.*;\s*)luciaToken\s*=\s*([^;]*).*$)|^.*$/, "$1");
|
||||||
|
|
||||||
axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
|
axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
|
||||||
switch (to.params.type) {
|
switch (to.params.type) {
|
||||||
|
|||||||
@@ -468,7 +468,7 @@ export default {
|
|||||||
if (isCheckPage) {
|
if (isCheckPage) {
|
||||||
const conformanceStore = ConformanceStore();
|
const conformanceStore = ConformanceStore();
|
||||||
// Save token in Headers.
|
// Save token in Headers.
|
||||||
const token = document.cookie.replace(/(?:(?:^|.*;\s*)luciaToken\s*\=\s*([^;]*).*$)|^.*$/, "$1");
|
const token = document.cookie.replace(/(?:(?:^|.*;\s*)luciaToken\s*=\s*([^;]*).*$)|^.*$/, "$1");
|
||||||
|
|
||||||
axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
|
axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
|
||||||
switch (to.params.type) {
|
switch (to.params.type) {
|
||||||
|
|||||||
@@ -267,8 +267,6 @@ export default {
|
|||||||
* @param { object } content titels 標題文字
|
* @param { object } content titels 標題文字
|
||||||
*/
|
*/
|
||||||
getBarChart(chartData, content) {
|
getBarChart(chartData, content) {
|
||||||
const maxX = chartData.x_axis.max;
|
|
||||||
const minX = chartData.x_axis.min;
|
|
||||||
const getMoment = (time)=> this.$moment(time).format('YYYY/M/D hh:mm:ss');
|
const getMoment = (time)=> this.$moment(time).format('YYYY/M/D hh:mm:ss');
|
||||||
let datasets = chartData.data;
|
let datasets = chartData.data;
|
||||||
let xData;
|
let xData;
|
||||||
@@ -914,7 +912,7 @@ export default {
|
|||||||
if (isCheckPage) {
|
if (isCheckPage) {
|
||||||
const conformanceStore = ConformanceStore();
|
const conformanceStore = ConformanceStore();
|
||||||
// Save token in Headers.
|
// Save token in Headers.
|
||||||
const token = document.cookie.replace(/(?:(?:^|.*;\s*)luciaToken\s*\=\s*([^;]*).*$)|^.*$/, "$1");
|
const token = document.cookie.replace(/(?:(?:^|.*;\s*)luciaToken\s*=\s*([^;]*).*$)|^.*$/, "$1");
|
||||||
|
|
||||||
axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
|
axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
|
||||||
switch (to.params.type) {
|
switch (to.params.type) {
|
||||||
|
|||||||
@@ -116,26 +116,30 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<!-- All Files type of grid -->
|
<!-- All Files type of grid -->
|
||||||
<draggable tag="ul" :list="compareData" :group="{ name: 'files' }" itemKey="name" class="flex justify-start items-start gap-4 flex-wrap overflow-y-scroll overflow-x-hidden max-h-[calc(100vh_-_440px)] scrollbar" id="compareGridCards">
|
<ul>
|
||||||
<template #item="{ element, index }">
|
<draggable tag="ul" :list="compareData" :group="{ name: 'files' }" itemKey="name" class="flex justify-start items-start gap-4
|
||||||
<li class="w-[216px] h-[168px] p-4 border rounded border-neutral-300 hover:bg-primary/10 hover:border-primary duration-300 flex flex-col justify-between cursor-pointer" :title="element.name" :id="'compareFile' + index">
|
flex-wrap overflow-y-scroll overflow-x-hidden max-h-[calc(100vh_-_440px)] scrollbar" id="compareGridCards">
|
||||||
<div>
|
<template #item="{ element, index }">
|
||||||
<span class="material-symbols-outlined mb-2 !text-[32px] block">
|
<li class="w-[216px] h-[168px] p-4 border rounded border-neutral-300 hover:bg-primary/10 hover:border-primary duration-300
|
||||||
{{ element.icon }}
|
flex flex-col justify-between cursor-pointer" :title="element.name" :id="'compareFile' + index">
|
||||||
</span>
|
<div>
|
||||||
<h3 class="text-sm font-medium mb-2 whitespace-nowrap break-keep overflow-hidden text-ellipsis leading-tight">
|
<span class="material-symbols-outlined mb-2 !text-[32px] block">
|
||||||
{{ element.name }}
|
{{ element.icon }}
|
||||||
</h3>
|
</span>
|
||||||
<p class="text-sm text-neutral-500 whitespace-nowrap break-keep text-ellipsis overflow-hidden leading-tight">
|
<h3 class="text-sm font-medium mb-2 whitespace-nowrap break-keep overflow-hidden text-ellipsis leading-tight">
|
||||||
{{ element.parentLog }}
|
{{ element.name }}
|
||||||
|
</h3>
|
||||||
|
<p class="text-sm text-neutral-500 whitespace-nowrap break-keep text-ellipsis overflow-hidden leading-tight">
|
||||||
|
{{ element.parentLog }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<p class="text-sm text-neutral-500">
|
||||||
|
{{ element.updated_at }}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</li>
|
||||||
<p class="text-sm text-neutral-500">
|
</template>
|
||||||
{{ element.updated_at }}
|
</draggable>
|
||||||
</p>
|
</ul>
|
||||||
</li>
|
|
||||||
</template>
|
|
||||||
</draggable>
|
|
||||||
</section>
|
</section>
|
||||||
<!-- All & Discover -->
|
<!-- All & Discover -->
|
||||||
<section v-else>
|
<section v-else>
|
||||||
@@ -320,7 +324,7 @@
|
|||||||
* Compare Submit button disabled
|
* Compare Submit button disabled
|
||||||
*/
|
*/
|
||||||
isCompareDisabledButton: function() {
|
isCompareDisabledButton: function() {
|
||||||
let result = this.primaryDragData.length === 0 || this.secondaryDragData.length === 0 ? true : false;
|
let result = this.primaryDragData.length === 0 || this.secondaryDragData.length === 0;
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
@@ -398,17 +402,14 @@
|
|||||||
this.$router.push({name: 'Map', params: params});
|
this.$router.push({name: 'Map', params: params});
|
||||||
break;
|
break;
|
||||||
case 'log-check':
|
case 'log-check':
|
||||||
fileId = file.id;
|
|
||||||
type = file.parent.type;
|
|
||||||
params = { type: type, fileId: fileId };
|
|
||||||
this.$router.push({name: 'CheckConformance', params: params});
|
|
||||||
break
|
|
||||||
case 'filter-check':
|
case 'filter-check':
|
||||||
fileId = file.id;
|
fileId = file.id;
|
||||||
type = file.parent.type;
|
type = file.parent.type;
|
||||||
params = { type: type, fileId: fileId };
|
params = { type: type, fileId: fileId };
|
||||||
this.$router.push({name: 'CheckConformance', params: params});
|
this.$router.push({name: 'CheckConformance', params: params});
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
@@ -482,10 +483,11 @@
|
|||||||
switch (i.type) {
|
switch (i.type) {
|
||||||
case 'log-check':
|
case 'log-check':
|
||||||
i.type = 'rule';
|
i.type = 'rule';
|
||||||
break;
|
|
||||||
case 'filter-check':
|
case 'filter-check':
|
||||||
i.type = 'rule';
|
i.type = 'rule';
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
let content = `<li>[${i.type}] ${i.name}</li>`;
|
let content = `<li>[${i.type}] ${i.name}</li>`;
|
||||||
srt += content;
|
srt += content;
|
||||||
@@ -504,9 +506,8 @@
|
|||||||
this.reallyDeldetData.forEach(file => {
|
this.reallyDeldetData.forEach(file => {
|
||||||
switch (file.type) {
|
switch (file.type) {
|
||||||
case 'log-check':
|
case 'log-check':
|
||||||
file.type = 'rule';
|
|
||||||
break;
|
|
||||||
case 'filter-check':
|
case 'filter-check':
|
||||||
|
default:
|
||||||
file.type = 'rule';
|
file.type = 'rule';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ export default {
|
|||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
// Save token in Headers.
|
// Save token in Headers.
|
||||||
const token = document.cookie.replace(/(?:(?:^|.*;\s*)luciaToken\s*\=\s*([^;]*).*$)|^.*$/, "$1");
|
const token = document.cookie.replace(/(?:(?:^|.*;\s*)luciaToken\s*=\s*([^;]*).*$)|^.*$/, "$1");
|
||||||
this.$http.defaults.headers.common['Authorization'] = `Bearer ${token}`;
|
this.$http.defaults.headers.common['Authorization'] = `Bearer ${token}`;
|
||||||
},
|
},
|
||||||
// 重新整理畫面以及第一次進入網頁時,beforeRouteEnter這個hook會被執行,然而beforeRouteUpdate不會被執行
|
// 重新整理畫面以及第一次進入網頁時,beforeRouteEnter這個hook會被執行,然而beforeRouteUpdate不會被執行
|
||||||
|
|||||||
@@ -34,7 +34,9 @@
|
|||||||
<!-- Upload table -->
|
<!-- Upload table -->
|
||||||
<div class="overflow-y-auto overflow-x-auto scrollbar max-h-[calc(100%_-_94px)]">
|
<div class="overflow-y-auto overflow-x-auto scrollbar max-h-[calc(100%_-_94px)]">
|
||||||
<table class="text-sm border-separate border-spacing-0 h-full overflow-y-auto overflow-x-auto scrollbar">
|
<table class="text-sm border-separate border-spacing-0 h-full overflow-y-auto overflow-x-auto scrollbar">
|
||||||
|
<caption class="hidden">Upload</caption>
|
||||||
<thead class="sticky top-0 bg-neutral-10">
|
<thead class="sticky top-0 bg-neutral-10">
|
||||||
|
<tr class="hidden"><th></th></tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td v-for="(item, index) in uploadDetail?.columns" :key="index" class="border border-neutral-500 p-2 truncate max-w-[198px]">{{ item }}</td>
|
<td v-for="(item, index) in uploadDetail?.columns" :key="index" class="border border-neutral-500 p-2 truncate max-w-[198px]">{{ item }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -125,7 +127,8 @@ export default {
|
|||||||
// 1. 長度一樣,強制每一個都要選
|
// 1. 長度一樣,強制每一個都要選
|
||||||
// 2. 不為 null undefind
|
// 2. 不為 null undefind
|
||||||
let hasValue = !this.selectedColumns.includes(undefined);
|
let hasValue = !this.selectedColumns.includes(undefined);
|
||||||
let result = !(this.selectedColumns.length === this.uploadDetail?.columns.length && this.informData.length === 0 && this.repeatedData.length === 0 && hasValue) ? true : false;
|
let result = !(this.selectedColumns.length === this.uploadDetail?.columns.length
|
||||||
|
&& this.informData.length === 0 && this.repeatedData.length === 0 && hasValue);
|
||||||
return result
|
return result
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -208,7 +211,9 @@ export default {
|
|||||||
if(!code || code === 'case_attributes') return;
|
if(!code || code === 'case_attributes') return;
|
||||||
nameOccurrences[name]++;
|
nameOccurrences[name]++;
|
||||||
// 重複的選項只出現一次
|
// 重複的選項只出現一次
|
||||||
nameOccurrences[name] === 2 ? noSortedRepeatedData.push(item) : false;
|
if(nameOccurrences[name] === 2){
|
||||||
|
noSortedRepeatedData.push(item)
|
||||||
|
}
|
||||||
// 要按照選單的順序排序
|
// 要按照選單的順序排序
|
||||||
this.repeatedData = this.columnType.filter(column => noSortedRepeatedData.includes(column));
|
this.repeatedData = this.columnType.filter(column => noSortedRepeatedData.includes(column));
|
||||||
}else {
|
}else {
|
||||||
@@ -318,7 +323,6 @@ export default {
|
|||||||
if(vm.uploadId == null) {
|
if(vm.uploadId == null) {
|
||||||
vm.$router.push({name: 'Files', replace: true});
|
vm.$router.push({name: 'Files', replace: true});
|
||||||
vm.$toast.default('Please upload your file.', {position: 'bottom'});
|
vm.$toast.default('Please upload your file.', {position: 'bottom'});
|
||||||
return
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -59,8 +59,8 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
'fadeout': {
|
'fadeout': {
|
||||||
'0%': { opacity: '1' },
|
'0%': { opacity: '1' },
|
||||||
'0%': { opacity: '0.5' },
|
'50%': { opacity: '0.5' },
|
||||||
'0%': { opacity: '0' },
|
'100%': { opacity: '0' },
|
||||||
},
|
},
|
||||||
'edit': {
|
'edit': {
|
||||||
'0%, 100%': { transform: 'rotate(0deg)' },
|
'0%, 100%': { transform: 'rotate(0deg)' },
|
||||||
|
|||||||
Reference in New Issue
Block a user