Conformance: Activity sequence Start & End linkage done.

This commit is contained in:
chiayin
2023-08-30 14:19:20 +08:00
parent 1e49e11a1b
commit 187ce7afcc
6 changed files with 103 additions and 84 deletions

View File

@@ -69,8 +69,8 @@ export default {
visibleLeft: false, visibleLeft: false,
selectConformanceTask: null, selectConformanceTask: null,
selectConformanceStartAndEnd: null, selectConformanceStartAndEnd: null,
selectConformanceStart: null, selectCfmSeqStart: null,
selectConformanceEnd: null, selectCfmSeqEnd: null,
selectConformanceFrom: null, selectConformanceFrom: null,
selectConformanceTo: null, selectConformanceTo: null,
listSeq: [], listSeq: [],
@@ -165,8 +165,8 @@ export default {
// 不包含 this.selectDurationTime // 不包含 this.selectDurationTime
this.selectConformanceTask = null; // Have activity this.selectConformanceTask = null; // Have activity
this.selectConformanceStartAndEnd = null; // Activity Sequence this.selectConformanceStartAndEnd = null; // Activity Sequence
this.selectConformanceStart = null; this.selectCfmSeqStart = null;
this.selectConformanceEnd = null; this.selectCfmSeqEnd = null;
this.selectConformanceFrom = null; this.selectConformanceFrom = null;
this.selectConformanceTo = null; this.selectConformanceTo = null;
this.listSeq = []; this.listSeq = [];
@@ -247,8 +247,10 @@ export default {
default: default:
break; break;
}; };
this.selectDurationTime.min = this.selectTimeRangeMin; this.selectDurationTime = {
this.selectDurationTime.max = this.selectTimeRangeMax; min: this.selectTimeRangeMin,
max: this.selectTimeRangeMax
};
switch (this.selectedRuleType) { switch (this.selectedRuleType) {
case 'Have activity': // Rule Type 選 Have activity 的行為 case 'Have activity': // Rule Type 選 Have activity 的行為
@@ -533,17 +535,12 @@ export default {
}); });
this.$emitter.on('actRadioData', (data) => { this.$emitter.on('actRadioData', (data) => {
switch (data.category) { switch (data.category) {
case 'Start': // Activity sequence
this.selectConformanceStart = data.task; case 'cfmSeqStart':
this.selectCfmSeqStart = data.task;
break; break;
case 'End': case 'cfmSeqEnd':
this.selectConformanceEnd = data.task; this.selectCfmSeqEnd = data.task;
break;
case 'From':
this.selectConformanceFrom = data.task;
break;
case 'To':
this.selectConformanceTo = data.task;
break; break;
// Processing time // Processing time
case 'cfmPtEteStart': case 'cfmPtEteStart':
@@ -636,9 +633,6 @@ export default {
}; };
break; break;
}; };
if(this.selectConformanceStart !== null && this.selectConformanceEnd !== null){
this.selectConformanceStartAndEnd = [this.selectConformanceStart, this.selectConformanceEnd];
};
}); });
this.$emitter.on('getListSequence', (data) => { this.$emitter.on('getListSequence', (data) => {
this.listSeq = data; this.listSeq = data;

View File

@@ -1,9 +1,9 @@
<template> <template>
<div class="px-4 text-sm"> <div class="px-4 text-sm">
<!-- Have activity --> <!-- Have activity -->
<ResultCheck v-if="selectedRuleType === 'Have activity'" :data="containstTasksData" :select="isSubmitTask"></ResultCheck> <ResultCheck v-if="selectedRuleType === 'Have activity'" :data="containstTasksData" :select="isSubmitTask"></ResultCheck>
<!-- Activity sequence --> <!-- Activity sequence -->
<ResultDot v-if="selectedRuleType === 'Activity sequence' && selectedActivitySequence === 'Start & End'" :timeResultData="startEndData" :select="isSubmitStartAndEnd"></ResultDot> <ResultDot v-if="selectedRuleType === 'Activity sequence' && selectedActivitySequence === 'Start & End'" :timeResultData="selectCfmSeqSE" :select="isSubmitStartAndEnd"></ResultDot>
<ResultArrow v-if="selectedRuleType === 'Activity sequence' && selectedActivitySequence === 'Sequence'" :data="listSequence" :select="isSubmitListSeq"></ResultArrow> <ResultArrow v-if="selectedRuleType === 'Activity sequence' && selectedActivitySequence === 'Sequence'" :data="listSequence" :select="isSubmitListSeq"></ResultArrow>
<!-- Activity duration --> <!-- Activity duration -->
<ResultCheck v-if="selectedRuleType === 'Activity duration'" :title="'Activities include'" :data="durationData" :select="isSubmitDurationData"></ResultCheck> <ResultCheck v-if="selectedRuleType === 'Activity duration'" :title="'Activities include'" :data="durationData" :select="isSubmitDurationData"></ResultCheck>
@@ -25,7 +25,6 @@
<ResultDot v-if="selectedRuleType === 'Cycle time' && selectedProcessScope === 'End to end' && selectedActSeqMore === 'Start'" :timeResultData="selectCfmCtEteStart"></ResultDot> <ResultDot v-if="selectedRuleType === 'Cycle time' && selectedProcessScope === 'End to end' && selectedActSeqMore === 'Start'" :timeResultData="selectCfmCtEteStart"></ResultDot>
<ResultDot v-if="selectedRuleType === 'Cycle time' && selectedProcessScope === 'End to end' && selectedActSeqMore === 'End'" :timeResultData="selectCfmCtEteEnd"></ResultDot> <ResultDot v-if="selectedRuleType === 'Cycle time' && selectedProcessScope === 'End to end' && selectedActSeqMore === 'End'" :timeResultData="selectCfmCtEteEnd"></ResultDot>
<ResultDot v-if="selectedRuleType === 'Cycle time' && selectedProcessScope === 'End to end' && selectedActSeqMore === 'Start & End'" :timeResultData="selectCfmCtEteSE"></ResultDot> <ResultDot v-if="selectedRuleType === 'Cycle time' && selectedProcessScope === 'End to end' && selectedActSeqMore === 'Start & End'" :timeResultData="selectCfmCtEteSE"></ResultDot>
</div> </div>
</template> </template>
<script> <script>
@@ -52,10 +51,8 @@ export default {
return { return {
containstTasksData: null, containstTasksData: null,
startEndData: null, startEndData: null,
start: null, selectCfmSeqStart: null,
end: null, selectCfmSeqEnd: null,
from: null,
to: null,
listSequence: null, listSequence: null,
durationData: null, durationData: null,
selectCfmPtEteStart: null, // Processing time selectCfmPtEteStart: null, // Processing time
@@ -82,6 +79,17 @@ export default {
} }
}, },
computed: { computed: {
selectCfmSeqSE: function() {
let data = [];
console.log(this.selectCfmSeqStart);
if(this.selectCfmSeqStart) data.push(this.selectCfmSeqStart);
if(this.selectCfmSeqEnd) data.push(this.selectCfmSeqEnd);
data.sort((a, b) => {
const order = { 'Start': 1, 'End': 2};
return order[a.category] - order[b.category];
});
return data;
},
selectCfmPtEteSE: function() { selectCfmPtEteSE: function() {
let data = []; let data = [];
if(this.selectCfmPtEteSEStart) data.push(this.selectCfmPtEteSEStart); if(this.selectCfmPtEteSEStart) data.push(this.selectCfmPtEteSEStart);
@@ -162,10 +170,8 @@ export default {
reset() { reset() {
this.containstTasksData = null; this.containstTasksData = null;
this.startEndData = null; this.startEndData = null;
this.start = null; this.selectCfmSeqStart = null;
this.end = null; this.selectCfmSeqEnd = null;
this.from = null;
this.to = null;
this.listSequence = null; this.listSequence = null;
this.durationData = null; this.durationData = null;
this.selectCfmPtEteStart = null; this.selectCfmPtEteStart = null;
@@ -197,17 +203,14 @@ export default {
}); });
this.$emitter.on('actRadioData', (data) => { this.$emitter.on('actRadioData', (data) => {
switch (data.category) { switch (data.category) {
case 'Start': // Activity sequence
this.start = [data]; case 'cfmSeqStart':
data.category = 'Start';
this.selectCfmSeqStart = data;
break; break;
case 'End': case 'cfmSeqEnd':
this.end = [data]; data.category = 'End';
break; this.selectCfmSeqEnd = data;
case 'From':
this.from = [data];
break;
case 'To':
this.to = [data];
break; break;
// Processing time // Processing time
case 'cfmPtEteStart': case 'cfmPtEteStart':
@@ -297,9 +300,6 @@ export default {
else if(this.selectedRuleType === 'Activity duration') this.durationData = [data.task]; else if(this.selectedRuleType === 'Activity duration') this.durationData = [data.task];
break; break;
}; };
if(this.start !== null && this.end !== null){
this.startEndData = [...this.start, ...this.end];
};
}); });
this.$emitter.on('getListSequence', (data) => { this.$emitter.on('getListSequence', (data) => {
this.listSequence = data; this.listSequence = data;

View File

@@ -4,8 +4,8 @@
<ActList v-if="selectedRuleType === 'Have activity'" :data="conformanceTask" :select="isSubmitTask"></ActList> <ActList v-if="selectedRuleType === 'Have activity'" :data="conformanceTask" :select="isSubmitTask"></ActList>
<!-- Activity sequence --> <!-- Activity sequence -->
<div v-if="selectedRuleType === 'Activity sequence' && selectedActivitySequence === 'Start & End'" class="flex justify-between items-center w-full h-full"> <div v-if="selectedRuleType === 'Activity sequence' && selectedActivitySequence === 'Start & End'" class="flex justify-between items-center w-full h-full">
<ActRadio :title="'Start activity'" :select="isSubmitStartAndEnd?.[0].task" :data="conformanceStart" :category="'Start'" class="w-1/2" /> <ActRadio :title="'Start activity'" :select="isSubmitStartAndEnd?.[0].task" :data="cfmSeqStartData" :category="'cfmSeqStart'" @selected-task="selectStart" class="w-1/2" />
<ActRadio :title="'End activity'" :select="isSubmitStartAndEnd?.[1].task" :data="conformanceEnd" :category="'End'" class="w-1/2" /> <ActRadio :title="'End activity'" :select="isSubmitStartAndEnd?.[1].task" :data="cfmSeqEndData" :category="'cfmSeqEnd'" @selected-task="selectEnd" class="w-1/2" />
</div> </div>
<!-- actSeqDrag --> <!-- actSeqDrag -->
<ActSeqDrag v-if="selectedRuleType === 'Activity sequence' && selectedActivitySequence === 'Sequence'" :data="conformanceTask" :listSeq="isSubmitListSeq" :isSubmit="isSubmit"></ActSeqDrag> <ActSeqDrag v-if="selectedRuleType === 'Activity sequence' && selectedActivitySequence === 'Sequence'" :data="conformanceTask" :listSeq="isSubmitListSeq" :isSubmit="isSubmit"></ActSeqDrag>
@@ -59,9 +59,9 @@ export default {
const loadingStore = LoadingStore(); const loadingStore = LoadingStore();
const conformanceStore = ConformanceStore(); const conformanceStore = ConformanceStore();
const { isLoading } = storeToRefs(loadingStore); const { isLoading } = storeToRefs(loadingStore);
const { selectedRuleType, selectedActivitySequence, selectedMode, selectedProcessScope, selectedActSeqMore, selectedActSeqFromTo, conformanceTask, conformanceStart, conformanceEnd, cfmPtEteStart, cfmPtEteEnd, cfmPtEteSE, cfmPtPStart, cfmPtPEnd, cfmPtPSE, cfmWtEteStart, cfmWtEteEnd, cfmWtEteSE, cfmWtPStart, cfmWtPEnd, cfmWtPSE, cfmCtEteStart, cfmCtEteEnd, cfmCtEteSE } = storeToRefs(conformanceStore); const { selectedRuleType, selectedActivitySequence, selectedMode, selectedProcessScope, selectedActSeqMore, selectedActSeqFromTo, conformanceTask, cfmSeqStart, cfmSeqEnd, cfmPtEteStart, cfmPtEteEnd, cfmPtEteSE, cfmPtPStart, cfmPtPEnd, cfmPtPSE, cfmWtEteStart, cfmWtEteEnd, cfmWtEteSE, cfmWtPStart, cfmWtPEnd, cfmWtPSE, cfmCtEteStart, cfmCtEteEnd, cfmCtEteSE } = storeToRefs(conformanceStore);
return { isLoading, selectedRuleType, selectedActivitySequence, selectedMode, selectedProcessScope, selectedActSeqMore, selectedActSeqFromTo, conformanceTask, conformanceStart, conformanceEnd, cfmPtEteStart, cfmPtEteEnd, cfmPtEteSE, cfmPtPStart, cfmPtPEnd, cfmPtPSE, cfmWtEteStart, cfmWtEteEnd, cfmWtEteSE, cfmWtPStart, cfmWtPEnd, cfmWtPSE, cfmCtEteStart, cfmCtEteEnd, cfmCtEteSE } return { isLoading, selectedRuleType, selectedActivitySequence, selectedMode, selectedProcessScope, selectedActSeqMore, selectedActSeqFromTo, conformanceTask, cfmSeqStart, cfmSeqEnd, cfmPtEteStart, cfmPtEteEnd, cfmPtEteSE, cfmPtPStart, cfmPtPEnd, cfmPtPSE, cfmWtEteStart, cfmWtEteEnd, cfmWtEteSE, cfmWtPStart, cfmWtPEnd, cfmWtPSE, cfmCtEteStart, cfmCtEteEnd, cfmCtEteSE }
}, },
props: ['isSubmit', 'isSubmitTask', 'isSubmitStartAndEnd', 'isSubmitListSeq', 'isSubmitDurationData'], props: ['isSubmit', 'isSubmitTask', 'isSubmitStartAndEnd', 'isSubmitListSeq', 'isSubmitDurationData'],
components: { components: {
@@ -77,6 +77,13 @@ export default {
} }
}, },
computed: { computed: {
// Activity sequence
cfmSeqStartData: function() {
return this.isEndSelected ? this.setSeqStartAndEndData(this.cfmSeqEnd, 'sources', this.task) : this.cfmSeqStart.map(i => i.label);
},
cfmSeqEndData: function() {
return this.isStartSelected ? this.setSeqStartAndEndData(this.cfmSeqStart, 'sinks', this.task) : this.cfmSeqEnd.map(i => i.label);
},
// Processing time // Processing time
cfmPtEteStartData: function() { cfmPtEteStartData: function() {
return this.cfmPtEteStart.map(i => i.task); return this.cfmPtEteStart.map(i => i.task);
@@ -144,7 +151,7 @@ export default {
methods: { methods: {
/** /**
* 設定 start and end 的 Radio Data * 設定 start and end 的 Radio Data
* @param {object} data cfmPtEteSE | cfmPtPSE | cfmWtEteSE | cfmWtPSE | cfmCtEteSE * @param {object} data cfmSeqStart | cfmSeqEnd | cfmPtEteSE | cfmPtPSE | cfmWtEteSE | cfmWtPSE | cfmCtEteSE
* @param {string} category start | end * @param {string} category start | end
* @returns {array} * @returns {array}
*/ */
@@ -167,6 +174,22 @@ export default {
newData = [...new Set(newData)]; newData = [...new Set(newData)];
return newData; return newData;
}, },
/**
* 重新設定 Activity sequence 連動的 start and end 的 Radio Data
* @param {object} data cfmSeqStart | cfmSeqEnd
* @param {string} category sources | sinks
* @param {string} task task
* @returns {array}
*/
setSeqStartAndEndData(data, category, task = 'a') {
let newData = data.filter(i => i.label === task).map(i => i[category]);
newData = [...new Set(...newData)];
return newData;
},
/**
* select start list's task
* @param {event} e
*/
selectStart(e) { selectStart(e) {
if(this.isStartSelected === null || this.isStartSelected === true){ if(this.isStartSelected === null || this.isStartSelected === true){
this.isStartSelected = true; this.isStartSelected = true;
@@ -174,6 +197,10 @@ export default {
this.task = e; this.task = e;
}; };
}, },
/**
* select End list's task
* @param {event} e
*/
selectEnd(e) { selectEnd(e) {
if(this.isEndSelected === null || this.isEndSelected === true){ if(this.isEndSelected === null || this.isEndSelected === true){
this.isEndSelected = true; this.isEndSelected = true;

View File

@@ -71,6 +71,7 @@ export default {
minTotalSeconds(e) { minTotalSeconds(e) {
this.timeRangeMin = e; this.timeRangeMin = e;
this.$emit('min-total-seconds', e); this.$emit('min-total-seconds', e);
// console.log('min',e);
}, },
/** /**
* get min total seconds * get min total seconds
@@ -80,6 +81,7 @@ export default {
this.timeRangeMax = e; this.timeRangeMax = e;
this.updateMax = e; this.updateMax = e;
this.$emit('max-total-seconds', e); this.$emit('max-total-seconds', e);
// console.log('max',e);
}, },
}, },
} }

View File

@@ -43,7 +43,6 @@
<div id="cfmTrace" ref="cfmTrace" class="h-full min-w-full relative"></div> <div id="cfmTrace" ref="cfmTrace" class="h-full min-w-full relative"></div>
</div> </div>
</div> </div>
{{ caseData }}
<div class="overflow-y-auto overflow-x-auto scrollbar h-[calc(100%_-_264px)] infiniteTable" @scroll="handleScroll"> <div class="overflow-y-auto overflow-x-auto scrollbar h-[calc(100%_-_264px)] infiniteTable" @scroll="handleScroll">
<DataTable :value="caseData" showGridlines tableClass="text-sm " breakpoint="0"> <DataTable :value="caseData" showGridlines tableClass="text-sm " breakpoint="0">
<div v-for="(col, index) in columnData" :key="index"> <div v-for="(col, index) in columnData" :key="index">
@@ -100,12 +99,12 @@ export default {
caseData: function() { caseData: function() {
if(this.infiniteData !== null){ if(this.infiniteData !== null){
const data = JSON.parse(JSON.stringify(this.infiniteData)); // 深拷貝原始 cases 的內容 const data = JSON.parse(JSON.stringify(this.infiniteData)); // 深拷貝原始 cases 的內容
console.log(data);
data.forEach(item => { data.forEach(item => {
// item.facets.forEach((facet, index) => { item.facets.forEach((facet, index) => {
// console.log(facet.value); item[`fac_${index}`] = facet.value; // 建立新的 key-value pair
// item[`fac_${index}`] = facet.value.join(', '); // 建立新的 key-value pair });
// }); delete item.facets; // 刪除原本的 attributes 屬性
// delete item.facets; // 刪除原本的 attributes 屬性
item.attributes.forEach((attribute, index) => { item.attributes.forEach((attribute, index) => {
item[`att_${index}`] = attribute.value; // 建立新的 key-value pair item[`att_${index}`] = attribute.value; // 建立新的 key-value pair
@@ -121,6 +120,7 @@ export default {
{ field: 'id', header: 'Case Id' }, { field: 'id', header: 'Case Id' },
{ field: 'started_at', header: 'Start Date' }, { field: 'started_at', header: 'Start Date' },
{ field: 'completed_at', header: 'End Date' }, { field: 'completed_at', header: 'End Date' },
...data[0].facets.map((fac, index) => ({ field: `fac_${index}`, header: fac.name })),
...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

View File

@@ -18,8 +18,8 @@ export default defineStore('conformanceStore', {
conformanceFilterId: null, conformanceFilterId: null,
conformanceTempCheckerId: null, conformanceTempCheckerId: null,
allConformanceTask: [], allConformanceTask: [],
allConformanceStart: [], allCfmSeqStart: [],
allConformanceEnd: [], allCfmSeqEnd: [],
allProcessingTime: {}, allProcessingTime: {},
allWaitingTime: {}, allWaitingTime: {},
allCycleTime: {}, allCycleTime: {},
@@ -45,11 +45,11 @@ export default defineStore('conformanceStore', {
conformanceTask: state => { conformanceTask: state => {
return state.allConformanceTask.map(i => i.label); return state.allConformanceTask.map(i => i.label);
}, },
conformanceStart: state => { cfmSeqStart: state => {
return state.allConformanceStart; return state.allCfmSeqStart;
}, },
conformanceEnd: state => { cfmSeqEnd: state => {
return state.allConformanceEnd; return state.allCfmSeqEnd;
}, },
cfmPtEteWhole: state => { cfmPtEteWhole: state => {
return state.allProcessingTime.end_to_end.whole; return state.allProcessingTime.end_to_end.whole;
@@ -116,9 +116,20 @@ export default defineStore('conformanceStore', {
}, },
cases: state => { cases: state => {
if(state.allCases !== null){ if(state.allCases !== null){
state.allCases.map(c => { const newData = state.allCases.map(c => {
c.started_at = moment(c.started_at).format('YYYY/MM/DD HH:MM'); c.started_at = moment(c.started_at).format('YYYY/MM/DD HH:MM');
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 => {
switch(fac.type) {
case 'float-list':
fac.value = fac.value.map(v => v !== null ? new Decimal(v.toFixed(2)) : null);
fac.value = fac.value.join(', ');
break;
default:
break;
};
return fac;
});
c.attributes.map(att => { c.attributes.map(att => {
switch (att.type) { switch (att.type) {
case 'date': case 'date':
@@ -131,11 +142,12 @@ export default defineStore('conformanceStore', {
break; break;
} }
return att; return att;
})
return c;
}); });
const { facets, attributes, ...rest } = c;
return { ...rest, facets, attributes };
});
return newData
}; };
return state.allCases;
}, },
loopTraces: state => { loopTraces: state => {
return state.allLoopTraces; return state.allLoopTraces;
@@ -145,25 +157,9 @@ export default defineStore('conformanceStore', {
}, },
loopCases: state => { loopCases: state => {
if(state.allLoopCases !== null){ if(state.allLoopCases !== null){
state.allLoopCases.map(c => { const newData = state.allLoopCases.map(c => {
c.started_at = moment(c.started_at).format('YYYY/MM/DD HH:MM'); c.started_at = moment(c.started_at).format('YYYY/MM/DD HH:MM');
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');
// if(c.facets) {
// c.facets = '111';
// c.facets.map(att => {
// switch(att.type) {
// case 'float-list':
// console.log(att.value);
// att.value ='111'
// // att.value = att.value.map(v => v !== null ? new Decimal(v.toFixed(2)) : null);
// // att.value = att.value.join(', ');
// break;
// default:
// break;
// };
// return att;
// });
// };
c.attributes.map(att => { c.attributes.map(att => {
switch (att.type) { switch (att.type) {
case 'date': case 'date':
@@ -179,8 +175,8 @@ export default defineStore('conformanceStore', {
}); });
return c; return c;
}); });
return newData;
}; };
return state.allLoopCases;
}, },
}, },
actions: { actions: {
@@ -194,8 +190,8 @@ export default defineStore('conformanceStore', {
try { try {
const response = await this.$axios.get(api); const response = await this.$axios.get(api);
this.allConformanceTask = response.data.tasks; this.allConformanceTask = response.data.tasks;
this.allConformanceStart = response.data.sources; this.allCfmSeqStart = response.data.sources;
this.allConformanceEnd = response.data.sinks; this.allCfmSeqEnd = response.data.sinks;
this.allProcessingTime = response.data.processing_time; this.allProcessingTime = response.data.processing_time;
this.allWaitingTime = response.data.waiting_time; this.allWaitingTime = response.data.waiting_time;
this.allCycleTime = response.data.cycle_time; this.allCycleTime = response.data.cycle_time;