Conformance: infinite scroll done.

This commit is contained in:
chiayin
2023-07-28 12:11:31 +08:00
parent 765278bada
commit 864b7bf0ae
3 changed files with 83 additions and 58 deletions

View File

@@ -134,12 +134,9 @@
</table> </table>
</div> </div>
</div> </div>
</div> </div>
</section> </section>
<MoreModal :issusModal="issusModal" @update:visible="issusModal = $event" :issueTraces="issueTraces" :issusNo="issusNo" ref="moreModal"></MoreModal> <MoreModal :issusModal="issusModal" @update:visible="issusModal = $event" :issueTraces="issueTraces" :issusNo="issusNo" :traceId="traceId" :firstCases="firstCases" ref="moreModal"></MoreModal>
</section> </section>
</template> </template>
<script> <script>
@@ -192,6 +189,8 @@ export default {
casesChartData: null, casesChartData: null,
casesChartOptions: null, casesChartOptions: null,
issusNo: null, issusNo: null,
traceId: null,
firstCases: null,
tooltip: { tooltip: {
results: { results: {
value: 'This page will perform a conformance check based on the filtering results of the map.', value: 'This page will perform a conformance check based on the filtering results of the map.',
@@ -243,7 +242,8 @@ export default {
// async await 解決非同步資料延遲傳遞導致未讀取到而出錯的問題 // async await 解決非同步資料延遲傳遞導致未讀取到而出錯的問題
this.issusNo = no; this.issusNo = no;
await this.conformanceStore.getLogConformanceIssue(no); await this.conformanceStore.getLogConformanceIssue(no);
await this.conformanceStore.getLogConformanceTraceDetail(no, this.issueTraces[0].id, 0, 20); this.traceId = await this.issueTraces[0].id;
this.firstCases = await this.conformanceStore.getLogConformanceTraceDetail(no, this.issueTraces[0].id, 0);
this.issusModal = await true; this.issusModal = await true;
await this.$refs.moreModal.createCy() await this.$refs.moreModal.createCy()
}, },

View File

@@ -43,15 +43,12 @@
<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>
<div class="overflow-y-auto overflow-x-auto scrollbar h-[calc(100%_-_264px)]"> <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">
<Column :field="col.field" :header="col.header" sortable></Column> <Column :field="col.field" :header="col.header" sortable></Column>
</div> </div>
</DataTable> </DataTable>
<!-- <infinite-loading @infinite="infiniteHandler"></infinite-loading> -->
<!-- <div v-if="!maxItems">Loading more...</div>
<div v-else>No more data available.</div> -->
</div> </div>
</section> </section>
</div> </div>
@@ -63,22 +60,20 @@ import ConformanceStore from '@/stores/conformance.js';
import cytoscapeMapTrace from '@/module/cytoscapeMapTrace.js'; import cytoscapeMapTrace from '@/module/cytoscapeMapTrace.js';
export default { export default {
props: ['issusModal', 'issusNo'], props: ['issusModal', 'issusNo', 'traceId', 'firstCases'],
setup() { setup() {
const conformanceStore = ConformanceStore(); const conformanceStore = ConformanceStore();
const { issueTraces, taskSeq, cases } = storeToRefs(conformanceStore); const { issueTraces, taskSeq, cases, infinite404 } = storeToRefs(conformanceStore);
return { issueTraces, taskSeq, cases, conformanceStore } return { issueTraces, taskSeq, cases, infinite404, conformanceStore }
}, },
data() { data() {
return { return {
contentClass: '!bg-neutral-100 border-t border-neutral-300 h-full', contentClass: '!bg-neutral-100 border-t border-neutral-300 h-full',
showTraceId: 1, showTraceId: null,
infiniteData: [], infiniteData: null,
busy: false,
maxItems: false, maxItems: false,
start: 0, startNum: 0,
pageSize: 20,
processMap:{ processMap:{
nodes:[], nodes:[],
edges:[], edges:[],
@@ -102,7 +97,8 @@ export default {
}).sort((x, y) => x.id - y.id); }).sort((x, y) => x.id - y.id);
}, },
caseData: function() { caseData: function() {
const data = JSON.parse(JSON.stringify(this.cases)); // 深拷貝原始 cases 的內容 if(this.infiniteData !== null){
const data = JSON.parse(JSON.stringify(this.infiniteData)); // 深拷貝原始 cases 的內容
data.forEach(item => { data.forEach(item => {
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
@@ -110,6 +106,7 @@ export default {
delete item.attributes; // 刪除原本的 attributes 屬性 delete item.attributes; // 刪除原本的 attributes 屬性
}) })
return data; return data;
}
}, },
columnData: function() { columnData: function() {
const data = JSON.parse(JSON.stringify(this.cases)); // 深拷貝原始 cases 的內容 const data = JSON.parse(JSON.stringify(this.cases)); // 深拷貝原始 cases 的內容
@@ -122,6 +119,28 @@ export default {
return result return result
}, },
}, },
watch: {
taskSeq: function(newValue){
if(newValue !== null) this.createCy();
},
traceId: function(newValue) {
// 當 traceId 屬性變化時更新 showTraceId
this.showTraceId = newValue;
},
showTraceId: function(newValue, oldValue) {
let isScrollTop = document.querySelector('.infiniteTable');
if(typeof isScrollTop.scrollTop !== 'undefined') if(newValue !== oldValue) isScrollTop.scrollTop = 0;
},
firstCases: function(newValue, oldValue){
this.infiniteData = newValue;
},
infinite404: function(newValue, oldValue){
if (newValue === 404) {
this.maxItems = true;
this.loading = false;
}
},
},
methods: { methods: {
/** /**
* Number to percentage * Number to percentage
@@ -143,9 +162,13 @@ export default {
* switch case data * switch case data
* @param {number} id * @param {number} id
*/ */
switchCaseData(id) { async switchCaseData(id) {
this.infinite404 = null;
this.maxItems = false;
this.showTraceId = id; this.showTraceId = id;
this.conformanceStore.getLogConformanceTraceDetail(this.issusNo, id, 0, 20) this.startNum = 0;
let result = await this.conformanceStore.getLogConformanceTraceDetail(this.issusNo, id, 0);
this.infiniteData = await result;
}, },
/** /**
* 將 trace element nodes 資料彙整 * 將 trace element nodes 資料彙整
@@ -198,32 +221,29 @@ export default {
cytoscapeMapTrace(this.processMap.nodes, this.processMap.edges, graphId); cytoscapeMapTrace(this.processMap.nodes, this.processMap.edges, graphId);
}); });
}, },
async infiniteHandler() { async fetchData() {
console.log('TT');
try { try {
await this.conformanceStore.getLogConformanceTraceDetail(this.issusNo, this.issueTraces[0], this.start, this.pageSize) this.loading = true;
this.cases = [...this.infiniteData, ...this.cases]; this.startNum += 20
console.log(this.cases); const result = await this.conformanceStore.getLogConformanceTraceDetail(this.issusNo, this.showTraceId, this.startNum);
(this.cases.length < this.pageSize) ? this.maxItems = true : this.pageSize += 20; this.infiniteData = [...this.infiniteData, ...result];
$state.loaded();
} catch(error) { } catch(error) {
if (error.response && error.response.status === 404) { // console.error('Failed to load data:', error);
$state.complete();
} else {
console.error('Failed to load data:', error);
}
} finally { } finally {
this.busy = false; this.loading = false;
} }
}, },
}, handleScroll(event) {
watch: { if(this.loading || this.maxItems) return;
taskSeq: function(newValue){
if(newValue !== null) this.createCy(); const container = event.target;
const overScrollHeight = container.scrollTop + container.clientHeight + 20 >= container.scrollHeight;
if (overScrollHeight) {
this.fetchData();
this.loading = true;
} }
}, },
mounted(){
}, },
} }
</script> </script>

View File

@@ -5,6 +5,7 @@ import {useToast} from 'vue-toast-notification';
import 'vue-toast-notification/dist/theme-sugar.css'; import 'vue-toast-notification/dist/theme-sugar.css';
import moment from "moment"; import moment from "moment";
import { Decimal } from 'decimal.js'; import { Decimal } from 'decimal.js';
import { resolveTransitionHooks } from "vue";
const loading = loadingStore(pinia); const loading = loadingStore(pinia);
const $toast = useToast(); const $toast = useToast();
@@ -28,6 +29,7 @@ export default defineStore('conformanceStore', {
selectedProcessScope: 'End to end', // radio selectedProcessScope: 'End to end', // radio
selectedActSeqMore: 'All', // radio selectedActSeqMore: 'All', // radio
selectedActSeqFromTo: 'From', // radio selectedActSeqFromTo: 'From', // radio
infinite404: null,
}), }),
getters: { getters: {
conformanceTask: state => { conformanceTask: state => {
@@ -148,22 +150,25 @@ export default defineStore('conformanceStore', {
/** /**
* Get the Trace Details of a Temporary Log Conformance lssue. * Get the Trace Details of a Temporary Log Conformance lssue.
*/ */
async getLogConformanceTraceDetail(issueNo, traceId, start, pageSize) { async getLogConformanceTraceDetail(issueNo, traceId, start) {
let checkerId = this.conformanceTempCheckerId; let checkerId = this.conformanceTempCheckerId;
const api = `/api/temp-log-checkers/${checkerId}/issues/${issueNo}/traces/${traceId}?start=${start}&page_size=${pageSize}`; const api = `/api/temp-log-checkers/${checkerId}/issues/${issueNo}/traces/${traceId}?start=${start}&page_size=20`;
try { try {
const response = await this.$axios.get(api); const response = await this.$axios.get(api);
this.allTaskSeq = response.data.task_seq; this.allTaskSeq = response.data.task_seq;
this.allCases = response.data.cases; this.allCases = response.data.cases;
return response.data.cases;
} catch(error) { } catch(error) {
if(error.response.status === 404) this.infinite404 = 404;
else {
await delay(); await delay();
loading.isLoading = true; loading.isLoading = true;
await delay(1000); await delay(1000);
loading.isLoading = false; loading.isLoading = false;
await delay(500); await delay(500);
$toast.default('Failed to Get the detail of a temporary log conformance issue.',{position: 'bottom'}); $toast.default('Failed to Get the detail of a temporary log conformance issue.',{position: 'bottom'});
};
} }
}, },
}, },