import { defineStore } from "pinia"; import moment from "moment"; import apiError from '@/module/apiError.js'; import { Decimal } from 'decimal.js'; export default defineStore('allMapDataStore', { state: () => ({ baseLogId: null, logId: null, traceId: null, baseTraceId: 1, tempFilterId: null, createFilterId: null, filterName: null, allProcessMap: {}, allBpmn: {}, allStats: {}, allInsights: {}, allTrace: [], allBaseTrace: [], allCase: [], allBaseCase: [], allTraceTaskSeq: [], allBaseTraceTaskSeq: [], allFilterTask: [], allFilterStartToEnd: [], allFilterEndToStart: [], allFilterTimeframe: {}, allFilterTrace: [], allFilterAttrs: [], hasResultRule: null, // click Apply 後檢查是否有 Data temporaryData: [], // 沒被 apply all 的 Data postRuleData: [], // has-result API & temp-filters API 的 Data ruleData: [], // Funnle view's data isRuleData: [], // toggle button data allFunnelData: [], isUpdataFilter: false, // 是否成功儲存 Filter 檔 selectTimeFrame: [], // user select time start and end infinite404: null, // 無限滾動式是否到底要換頁 infiniteStart: 0, // 無限滾動 case 開始的數字 baseInfiniteStart: 0, // 無限滾動 case 開始的數字 }), getters: { processMap: state => { return state.allProcessMap; }, bpmn: state => { return state.allBpmn; }, stats: state => { return state.allStats; }, insights: state => { return state.allInsights; }, traces: state => { return state.allTrace.sort((x, y) => x.id - y.id); }, baseTraces: state => { return state.allBaseTrace.sort((x, y) => x.id - y.id); }, cases: state => { return state.allCase; }, baseCases: state => { return state.allBaseCase; }, infiniteFirstCases: state => { if(state.infiniteStart === 0) return state.allCase; }, BaseInfiniteFirstCases: state => { if(state.BaseInfiniteStart === 0) return state.allBaseCase; }, traceTaskSeq: state => { return state.allTraceTaskSeq; }, baseTraceTaskSeq: state => { return state.allBaseTraceTaskSeq; }, // All tasks filterTasks: state => { return state.allFilterTask; }, // form start to end tasks filterStartToEnd: state => { return state.allFilterStartToEnd; }, // form end to start tasks filterEndToStart: state => { return state.allFilterEndToStart; }, filterTimeframe: state => { return state.allFilterTimeframe; }, filterTrace: state => { return state.allFilterTrace; }, filterAttrs: state => { if(state.allFilterAttrs !== null){ state.allFilterAttrs.map(att => { switch (att.type) { case 'date': att.min = att.min !== null ? moment(att.min).format('YYYY/MM/DD HH:mm') : null; att.max = att.max !== null ? moment(att.max).format('YYYY/MM/DD HH:mm') : null; break; case 'float': // Decimal.ROUND_UP|0: 無條件進位; Decimal.ROUND_DOWN|1: 無條件捨去。 att.min = att.min !== null ? Number(new Decimal(att.min).toFixed(2, 1)) : null; att.max = att.max !== null ? Number(new Decimal(att.max).toFixed(2, 0)) : null; break default: break; } return att; }); return state.allFilterAttrs; } }, allFunnels: state => { return state.allFunnelData; }, }, actions: { /** * fetch discover api, include '/process-map, /bpmn, /stats, /insights'. */ async getAllMapData() { let logId = this.logId; let tempFilterId = this.tempFilterId; let createfilterId = this.createFilterId let api = ''; // 先判斷暫存 再判斷 filter 最後 log if(tempFilterId != null) api = `/api/temp-filters/${tempFilterId}/discover`; else if(createfilterId!= null) api = `/api/filters/${createfilterId}/discover`; else api = `/api/logs/${logId}/discover`; try { const response = await this.$axios.get(api); this.allProcessMap = response.data.process_map; this.allBpmn = response.data.bpmn; this.allStats = response.data.stats; this.allInsights = response.data.insights; } catch(error) { apiError(error, 'Failed to load the Map.'); }; }, /** * fetch trace api. */ async getAllTrace() { let logId = this.logId; let tempFilterId = this.tempFilterId; let createfilterId = this.createFilterId; let baseLogId = this.baseLogId; let baseApi = `/api/logs/${baseLogId}/traces`; let api = ''; // 先判斷暫存 再判斷 filter 最後 log if(tempFilterId != null) api = `/api/temp-filters/${tempFilterId}/traces`; else if(createfilterId!= null) api = `/api/filters/${createfilterId}/traces`; else api = `/api/logs/${logId}/traces`; try { let baseResponse; const response = await this.$axios.get(api); this.allTrace = response.data; if(baseLogId) baseResponse = await this.$axios.get(baseApi); this.allBaseTrace = baseResponse.data; } catch(error) { apiError(error, 'Failed to load the Trace.'); } }, /** * fetch trace detail api. */ async getTraceDetail() { let logId = this.logId; let traceId = this.traceId; let tempFilterId = this.tempFilterId; let createfilterId = this.createFilterId; let start = this.infiniteStart; let api = ''; // 先判斷暫存 再判斷 filter 最後 log if(tempFilterId != null) api = `/api/temp-filters/${tempFilterId}/traces/${traceId}?start=${start}&page_size=20`; else if(createfilterId!= null) api = `/api/filters/${createfilterId}/traces/${traceId}?start=${start}&page_size=20`; else api = `/api/logs/${logId}/traces/${traceId}?start=${start}&page_size=20`; try { const response = await this.$axios.get(api); this.allTraceTaskSeq = response.data.task_seq; this.allCase = response.data.cases; this.allCase.map(c => { 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.attributes.map(att => { switch (att.type) { case 'date': att.value = att.value !== null ? moment(att.value).format('YYYY/MM/DD HH:mm') : null; break; case 'float': att.value = att.value !== null ? Number(new Decimal(att.value).toFixed(2)) : null; default: break; } }) return this.allCase; }); return this.allCase; } catch(error) { if(error.response.status === 404) return this.infinite404 = 404; apiError(error, 'Failed to load the Trace Detail.'); }; }, /** * fetch base log trace detail api. */ async getBaseTraceDetail() { let logId = this.baseLogId; let traceId = this.baseTraceId; let start = this.baseInfiniteStart; let api = `/api/logs/${logId}/traces/${traceId}?start=${start}&page_size=20`; try { const response = await this.$axios.get(api); this.allBaseTraceTaskSeq = response.data.task_seq; this.allBaseCase = response.data.cases; this.allBaseCase.map(c => { 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.attributes.map(att => { switch (att.type) { case 'date': att.value = att.value !== null ? moment(att.value).format('YYYY/MM/DD HH:mm') : null; break; case 'float': att.value = att.value !== null ? Number(new Decimal(att.value).toFixed(2)) : null; default: break; } }) return this.allBaseCase; }); return this.allBaseCase; } catch(error) { if(error.response.status === 404) return this.infinite404 = 404; apiError(error, 'Failed to load the Base Trace Detail.'); }; }, /** * fetch Filter Parameters api. */ async getFilterParams() { let logId = this.logId; const api = `/api/filters/params?log_id=${logId}`; try { const response = await this.$axios.get(api); this.allFilterTask = response.data.tasks; this.allFilterStartToEnd = response.data.sources; this.allFilterEndToStart = response.data.sinks; this.allFilterTimeframe = response.data.timeframe; this.allFilterTrace = response.data.trace; this.allFilterAttrs = response.data.attrs; let min = this.allFilterTimeframe.x_axis.min; let max = this.allFilterTimeframe.x_axis.max; // 給 Chart.js 原始資料,格式不同的畫會錯誤輸出 this.allFilterTimeframe.x_axis.min_base = min; this.allFilterTimeframe.x_axis.max_base = max; // 轉成無秒的時間格式 this.allFilterTimeframe.x_axis.min = min !== null ? moment(min).format('YYYY/MM/DD HH:mm') : null; this.allFilterTimeframe.x_axis.max = max !== null ? moment(max).format('YYYY/MM/DD HH:mm') : null; } catch(error) { apiError(error, 'Failed to load the Filter Parameters.'); }; }, /** * Test if the Filter Rules Result in Any Data */ async checkHasResult() { let logId = this.logId; const api = `/api/filters/has-result?log_id=${logId}`; try { const response = await this.$axios.post(api, this.postRuleData) this.hasResultRule = response.data.result; } catch(error) { apiError(error, 'Failed to load the Has Result.'); }; }, /** * Add a New Temporary Filter */ async addTempFilterId() { let logId = this.logId; const api = `/api/temp-filters?log_id=${logId}`; try { const response = await this.$axios.post(api, this.postRuleData) this.tempFilterId = response.data.id; } catch(error) { apiError(error, 'Failed to add the Temporary Filters.'); }; }, /** * Add a New Filter * @param {string} value file's name */ async addFilterId(value) { let logId = this.logId; const api = `/api/filters?log_id=${logId}`; let createFilterObj = { name: value, rules: this.postRuleData }; try { const response = await this.$axios.post(api, createFilterObj); this.createFilterId = response.data.id; this.tempFilterId = null; }catch(error) { apiError(error, 'Failed to load the Filters.'); }; }, /** * Get Filter Detail * @param {namber} createfilterId filter type ID */ async fetchFunnel(createfilterId) { const api = `/api/filters/${createfilterId}`; if(createfilterId){ try { const response = await this.$axios.get(api); this.temporaryData = response.data.rules; this.logId = response.data.log.id; this.filterName = response.data.name; this.baseLogId = response.data.log.id; }catch(error) { apiError(error, 'Failed to get Filter Detail.'); } } }, /** * Updata an Existing Filter */ async updataFilter() { let createFilterId = this.createFilterId const api = `/api/filters/${createFilterId}`; const data = this.postRuleData; try { const response = await this.$axios.put(api, data); this.isUpdataFilter = response.status === 200; this.tempFilterId = null; }catch(error) { apiError(error, 'Failed to updata an Existing Filter.'); } }, }, })