Add JSDoc documentation and file headers to all source files
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -192,6 +192,18 @@
|
||||
</section>
|
||||
</template>
|
||||
<script setup>
|
||||
// The Lucia project.
|
||||
// Copyright 2023-2026 DSP, inc. All rights reserved.
|
||||
// Authors:
|
||||
// chiayin.kuo@dsp.im (chiayin), 2023/1/31
|
||||
// cindy.chang@dsp.im (Cindy Chang), 2024/5/30
|
||||
// imacat.yang@dsp.im (imacat), 2023/9/23
|
||||
/**
|
||||
* @module components/Discover/Conformance/ConformanceResults
|
||||
* Conformance checking results panel displaying rule
|
||||
* check outcomes in a data table with status indicators.
|
||||
*/
|
||||
|
||||
import { ref, watch } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useConformanceStore } from '@/stores/conformance';
|
||||
@@ -274,8 +286,8 @@ const tooltip = ref({
|
||||
|
||||
/**
|
||||
* set progress bar width
|
||||
* @param {number} value 百分比數字
|
||||
* @returns {string} 樣式的寬度設定
|
||||
* @param {number} value - The percentage value.
|
||||
* @returns {string} The CSS width style string.
|
||||
*/
|
||||
const progressWidth = (value) => {
|
||||
return `width:${value}%;`
|
||||
@@ -283,8 +295,8 @@ const progressWidth = (value) => {
|
||||
|
||||
/**
|
||||
* Number to percentage
|
||||
* @param {number} val 原始數字
|
||||
* @returns {string} 轉換完成的百分比字串
|
||||
* @param {number} val - The raw ratio value.
|
||||
* @returns {string} The formatted percentage string.
|
||||
*/
|
||||
const getPercentLabel = (val) => {
|
||||
if((val * 100).toFixed(1) >= 100) return 100;
|
||||
@@ -293,7 +305,7 @@ const getPercentLabel = (val) => {
|
||||
|
||||
/**
|
||||
* Convert seconds to days
|
||||
* @param {number} sec 秒數
|
||||
* @param {number} sec - The number of seconds.
|
||||
* @returns {number} day
|
||||
*/
|
||||
const convertSecToDay = (sec) => {
|
||||
@@ -302,7 +314,7 @@ const convertSecToDay = (sec) => {
|
||||
|
||||
/**
|
||||
* Open Issues Modal.
|
||||
* @param {number} no trace 編號
|
||||
* @param {number} no - The trace number.
|
||||
*/
|
||||
const openMore = async (no) => {
|
||||
// async await 解決非同步資料延遲傳遞導致未讀取到而出錯的問題
|
||||
@@ -315,7 +327,7 @@ const openMore = async (no) => {
|
||||
|
||||
/**
|
||||
* Open Loop Modal.
|
||||
* @param {number} no trace 編號
|
||||
* @param {number} no - The trace number.
|
||||
*/
|
||||
const openLoopMore = async (no) => {
|
||||
// async await 解決非同步資料延遲傳遞導致未讀取到而出錯的問題
|
||||
@@ -328,7 +340,7 @@ const openLoopMore = async (no) => {
|
||||
|
||||
/**
|
||||
* set conformance report data
|
||||
* @param {object} data new watch's value 監聽到後端傳來的報告 data
|
||||
* @param {object} data - The report data received from the backend.
|
||||
*/
|
||||
const setConformanceTempReportData = (newData) => {
|
||||
const total = getNumberLabel(Object.values(newData.counts).reduce((acc, val) => acc + val, 0));
|
||||
|
||||
@@ -122,6 +122,19 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// The Lucia project.
|
||||
// Copyright 2023-2026 DSP, inc. All rights reserved.
|
||||
// Authors:
|
||||
// chiayin.kuo@dsp.im (chiayin), 2023/1/31
|
||||
// imacat.yang@dsp.im (imacat), 2023/9/23
|
||||
// cindy.chang@dsp.im (Cindy Chang), 2024/5/30
|
||||
/**
|
||||
* @module components/Discover/Conformance/ConformanceSidebar
|
||||
* Main sidebar for conformance checking with rule
|
||||
* configuration, activity selection, and submit/reset
|
||||
* actions.
|
||||
*/
|
||||
|
||||
import { ref, computed, watch, onBeforeUnmount } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useToast } from 'vue-toast-notification';
|
||||
@@ -622,14 +635,14 @@ watch(conformanceTempReportData, (newValue) => {
|
||||
// methods
|
||||
/**
|
||||
* get min total seconds
|
||||
* @param {Number} e 最小值總秒數
|
||||
* @param {number} e - The minimum total seconds.
|
||||
*/
|
||||
function minTotalSeconds(e) {
|
||||
selectTimeRangeMin.value = e;
|
||||
}
|
||||
/**
|
||||
* get min total seconds
|
||||
* @param {Number} e 最大值總秒數
|
||||
* @param {number} e - The maximum total seconds.
|
||||
*/
|
||||
function maxTotalSeconds(e) {
|
||||
selectTimeRangeMax.value = e;
|
||||
@@ -715,7 +728,7 @@ function isSubmitReset() {
|
||||
isSubmitTimeCfmCtEteSE.value = { base: {}, rule: {}};
|
||||
}
|
||||
/**
|
||||
* 清空選單的行為
|
||||
* Clears all form selections and resets the sidebar state.
|
||||
*/
|
||||
function reset() {
|
||||
// Results page Cover Plate(遮罩為 ture)
|
||||
@@ -733,7 +746,7 @@ function reset() {
|
||||
isShowBarOpen.value = true;
|
||||
}
|
||||
/**
|
||||
* 設定 Start & End Data 連動資料
|
||||
* Sets linked Start & End data for activity selection.
|
||||
* @param {string} start task
|
||||
* @param {string} end task
|
||||
* @returns {object}
|
||||
@@ -758,7 +771,7 @@ function setSubmitShowDataByStartEnd(start, end) {
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Apply button 發送選項,取得 Check Id.
|
||||
* Submits the selected options via the Apply button and retrieves the Check ID.
|
||||
*/
|
||||
async function submitConformance() {
|
||||
let dataToSave;
|
||||
@@ -810,6 +823,9 @@ async function submitConformance() {
|
||||
$toast.success(i18next.t("Conformance.RuleApplied"));
|
||||
}
|
||||
|
||||
/** Builds the data payload for the 'Have activity' rule.
|
||||
* @returns {object} The rule data to submit.
|
||||
*/
|
||||
function getHaveActivityData() {
|
||||
const dataToSave = {
|
||||
type: 'contains-tasks',
|
||||
@@ -820,6 +836,9 @@ function getHaveActivityData() {
|
||||
return dataToSave;
|
||||
}
|
||||
|
||||
/** Builds the data payload for the 'Activity sequence' rule.
|
||||
* @returns {object} The rule data to submit.
|
||||
*/
|
||||
function getActivitySequenceData() {
|
||||
let dataToSave;
|
||||
switch (selectedActivitySequence.value) {
|
||||
@@ -843,6 +862,9 @@ function getActivitySequenceData() {
|
||||
return dataToSave;
|
||||
}
|
||||
|
||||
/** Builds the data payload for sequence sub-rules.
|
||||
* @returns {object} The rule data to submit.
|
||||
*/
|
||||
function getSequenceData() {
|
||||
let dataToSave;
|
||||
switch (selectedMode.value) {
|
||||
@@ -872,6 +894,9 @@ function getSequenceData() {
|
||||
return dataToSave;
|
||||
}
|
||||
|
||||
/** Builds the data payload for the 'Activity duration' rule.
|
||||
* @returns {object} The rule data to submit.
|
||||
*/
|
||||
function getActivityDurationData() {
|
||||
const dataToSave = {
|
||||
type: 'task-duration',
|
||||
@@ -885,6 +910,9 @@ function getActivityDurationData() {
|
||||
return dataToSave;
|
||||
}
|
||||
|
||||
/** Builds the data payload for the 'Processing time' rule.
|
||||
* @returns {object} The rule data to submit.
|
||||
*/
|
||||
function getProcessingTimeData() {
|
||||
let dataToSave;
|
||||
switch (selectedProcessScope.value) {
|
||||
@@ -898,6 +926,9 @@ function getProcessingTimeData() {
|
||||
return dataToSave;
|
||||
}
|
||||
|
||||
/** Builds end-to-end processing time rule data.
|
||||
* @returns {object} The rule data to submit.
|
||||
*/
|
||||
function getEndToEndProcessingTimeData() {
|
||||
let dataToSave;
|
||||
switch (selectedActSeqMore.value) {
|
||||
@@ -952,6 +983,9 @@ function getEndToEndProcessingTimeData() {
|
||||
return dataToSave;
|
||||
}
|
||||
|
||||
/** Builds partial processing time rule data.
|
||||
* @returns {object} The rule data to submit.
|
||||
*/
|
||||
function getPartialProcessingTimeData() {
|
||||
let dataToSave;
|
||||
switch (selectedActSeqFromTo.value) {
|
||||
@@ -997,6 +1031,9 @@ function getPartialProcessingTimeData() {
|
||||
return dataToSave;
|
||||
}
|
||||
|
||||
/** Builds the data payload for the 'Waiting time' rule.
|
||||
* @returns {object} The rule data to submit.
|
||||
*/
|
||||
function getWaitingTimeData() {
|
||||
let dataToSave;
|
||||
switch (selectedProcessScope.value) {
|
||||
@@ -1010,6 +1047,9 @@ function getWaitingTimeData() {
|
||||
return dataToSave;
|
||||
}
|
||||
|
||||
/** Builds end-to-end waiting time rule data.
|
||||
* @returns {object} The rule data to submit.
|
||||
*/
|
||||
function getEndToEndWaitingTimeData() {
|
||||
let dataToSave;
|
||||
switch (selectedActSeqMore.value) {
|
||||
@@ -1064,6 +1104,9 @@ function getEndToEndWaitingTimeData() {
|
||||
return dataToSave;
|
||||
}
|
||||
|
||||
/** Builds partial waiting time rule data.
|
||||
* @returns {object} The rule data to submit.
|
||||
*/
|
||||
function getPartialWaitingTimeData() {
|
||||
let dataToSave;
|
||||
switch (selectedActSeqFromTo.value) {
|
||||
@@ -1109,6 +1152,9 @@ function getPartialWaitingTimeData() {
|
||||
return dataToSave;
|
||||
}
|
||||
|
||||
/** Builds the data payload for the 'Cycle time' rule.
|
||||
* @returns {object} The rule data to submit.
|
||||
*/
|
||||
function getCycleTimeData() {
|
||||
let dataToSave;
|
||||
switch (selectedActSeqMore.value) {
|
||||
@@ -1164,7 +1210,7 @@ function getCycleTimeData() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 設置根據類別的任務選擇邏輯
|
||||
* Sets up category-based task selection logic.
|
||||
*/
|
||||
function setTaskByCategoryOnRadioEmitting() {
|
||||
emitter.on('actRadioData', (data) => {
|
||||
@@ -1201,6 +1247,10 @@ function setTaskByCategoryOnRadioEmitting() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles start task selection for activity sequence.
|
||||
* @param {string} task - The selected task.
|
||||
*/
|
||||
function handleCfmSeqStart(task) {
|
||||
if (isStartSelected.value && task !== selectCfmSeqStart.value) {
|
||||
selectCfmSeqEnd.value = null;
|
||||
@@ -1208,6 +1258,10 @@ function handleCfmSeqStart(task) {
|
||||
selectCfmSeqStart.value = task;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles end task selection for activity sequence.
|
||||
* @param {string} task - The selected task.
|
||||
*/
|
||||
function handleCfmSeqEnd(task) {
|
||||
if (isEndSelected.value && task !== selectCfmSeqEnd.value) {
|
||||
selectCfmSeqStart.value = null;
|
||||
@@ -1215,64 +1269,109 @@ function handleCfmSeqEnd(task) {
|
||||
selectCfmSeqEnd.value = task;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a simple task selection on a ref field.
|
||||
* @param {object} field - The ref to set.
|
||||
* @param {string} task - The selected task.
|
||||
*/
|
||||
function handleSimpleSelection(field, task) {
|
||||
selectFieldRefs[field].value = task;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles start task for end-to-end processing time.
|
||||
* @param {string} task - The selected task.
|
||||
*/
|
||||
function handleCfmPtEteSEStart(task) {
|
||||
if (isStartSelected.value && task !== selectCfmPtEteSEStart.value) {
|
||||
selectCfmPtEteSEEnd.value = null;
|
||||
}
|
||||
selectCfmPtEteSEStart.value = task;
|
||||
}
|
||||
/**
|
||||
* Handles end task for end-to-end processing time.
|
||||
* @param {string} task - The selected task.
|
||||
*/
|
||||
function handleCfmPtEteSEEnd(task) {
|
||||
if (isEndSelected.value && task !== selectCfmPtEteSEEnd.value) {
|
||||
selectCfmPtEteSEStart.value = null;
|
||||
}
|
||||
selectCfmPtEteSEEnd.value = task;
|
||||
}
|
||||
/**
|
||||
* Handles start task for partial processing time.
|
||||
* @param {string} task - The selected task.
|
||||
*/
|
||||
function handleCfmPtPSEStart(task) {
|
||||
if (isStartSelected.value && task !== selectCfmPtPSEStart.value) {
|
||||
selectCfmPtPSEEnd.value = null;
|
||||
}
|
||||
selectCfmPtPSEStart.value = task;
|
||||
}
|
||||
/**
|
||||
* Handles end task for partial processing time.
|
||||
* @param {string} task - The selected task.
|
||||
*/
|
||||
function handleCfmPtPSEEnd(task) {
|
||||
if (isEndSelected.value && task !== selectCfmPtPSEEnd.value) {
|
||||
selectCfmPtPSEStart.value = null;
|
||||
}
|
||||
selectCfmPtPSEEnd.value = task;
|
||||
}
|
||||
/**
|
||||
* Handles start task for end-to-end waiting time.
|
||||
* @param {string} task - The selected task.
|
||||
*/
|
||||
function handleCfmWtEteSEStart(task) {
|
||||
if (isStartSelected.value && task !== selectCfmWtEteSEStart.value) {
|
||||
selectCfmWtEteSEEnd.value = null;
|
||||
}
|
||||
selectCfmWtEteSEStart.value = task;
|
||||
}
|
||||
/**
|
||||
* Handles end task for end-to-end waiting time.
|
||||
* @param {string} task - The selected task.
|
||||
*/
|
||||
function handleCfmWtEteSEEnd(task) {
|
||||
if (isEndSelected.value && task !== selectCfmWtEteSEEnd.value) {
|
||||
selectCfmWtEteSEStart.value = null;
|
||||
}
|
||||
selectCfmWtEteSEEnd.value = task;
|
||||
}
|
||||
/**
|
||||
* Handles start task for partial waiting time.
|
||||
* @param {string} task - The selected task.
|
||||
*/
|
||||
function handleCfmWtPSEStart(task) {
|
||||
if (isStartSelected.value && task !== selectCfmWtPSEStart.value) {
|
||||
selectCfmWtPSEEnd.value = null;
|
||||
}
|
||||
selectCfmWtPSEStart.value = task;
|
||||
}
|
||||
/**
|
||||
* Handles end task for partial waiting time.
|
||||
* @param {string} task - The selected task.
|
||||
*/
|
||||
function handleCfmWtPSEEnd(task) {
|
||||
if (isEndSelected.value && task !== selectCfmWtPSEEnd.value) {
|
||||
selectCfmWtPSEStart.value = null;
|
||||
}
|
||||
selectCfmWtPSEEnd.value = task;
|
||||
}
|
||||
/**
|
||||
* Handles start task for end-to-end cycle time.
|
||||
* @param {string} task - The selected task.
|
||||
*/
|
||||
function handleCfmCtEteSEStart(task) {
|
||||
if (isStartSelected.value && task !== selectCfmCtEteSEStart.value) {
|
||||
selectCfmCtEteSEEnd.value = null;
|
||||
}
|
||||
selectCfmCtEteSEStart.value = task;
|
||||
}
|
||||
/**
|
||||
* Handles end task for end-to-end cycle time.
|
||||
* @param {string} task - The selected task.
|
||||
*/
|
||||
function handleCfmCtEteSEEnd(task) {
|
||||
if (isEndSelected.value && task !== selectCfmCtEteSEEnd.value) {
|
||||
selectCfmCtEteSEStart.value = null;
|
||||
@@ -1280,6 +1379,7 @@ function handleCfmCtEteSEEnd(task) {
|
||||
selectCfmCtEteSEEnd.value = task;
|
||||
}
|
||||
|
||||
/** Sets task data when the list sequence emits a change. */
|
||||
function setTaskByCategoryOnListSeqEmitting(){
|
||||
emitter.on('getListSequence', (data) => {
|
||||
switch (data.category) {
|
||||
@@ -1295,15 +1395,21 @@ function setTaskByCategoryOnListSeqEmitting(){
|
||||
});
|
||||
}
|
||||
|
||||
/** Checks if the 'Have activity' rule has valid selections.
|
||||
* @returns {boolean} Whether the button should be disabled.
|
||||
*/
|
||||
function checkHaveActivity() {
|
||||
return !(selectConformanceTask.value?.length);
|
||||
}
|
||||
/** Checks if the 'Activity duration' rule has valid selections.
|
||||
* @returns {boolean} Whether the button should be disabled.
|
||||
*/
|
||||
function checkActivityDuration() {
|
||||
return !selectDurationData.value?.length;
|
||||
}
|
||||
/**
|
||||
* 檢查活動序列的邏輯
|
||||
* @returns {boolean} 是否禁用按鈕
|
||||
* Checks the activity sequence logic.
|
||||
* @returns {boolean} Whether the button should be disabled.
|
||||
*/
|
||||
function checkActivitySequence() {
|
||||
switch (selectedActivitySequence.value) {
|
||||
@@ -1316,15 +1422,18 @@ function checkActivitySequence() {
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 檢查 Start & End 活動序列
|
||||
* @param {string} start 活動開始
|
||||
* @param {string} end 活動結束
|
||||
* @returns {boolean} 是否禁用按鈕
|
||||
* Checks the Start & End activity sequence.
|
||||
* @param {string} start - The start activity.
|
||||
* @param {string} end - The end activity.
|
||||
* @returns {boolean} Whether the button should be disabled.
|
||||
*/
|
||||
function checkStartAndEndSequence(start, end) {
|
||||
return !(start && end);
|
||||
}
|
||||
|
||||
/** Checks if the 'Processing time' rule has valid selections.
|
||||
* @returns {boolean} Whether the button should be disabled.
|
||||
*/
|
||||
function checkProcessingTime() {
|
||||
let disabled = true;
|
||||
switch (selectedProcessScope.value) {
|
||||
@@ -1339,6 +1448,9 @@ function checkProcessingTime() {
|
||||
}
|
||||
return disabled;
|
||||
}
|
||||
/** Checks end-to-end scope selections.
|
||||
* @returns {boolean} Whether the button should be disabled.
|
||||
*/
|
||||
function checkEndToEnd() {
|
||||
let disabled = true;
|
||||
switch (selectedActSeqMore.value) {
|
||||
@@ -1362,6 +1474,9 @@ function checkEndToEnd() {
|
||||
}
|
||||
return disabled;
|
||||
}
|
||||
/** Checks partial scope selections.
|
||||
* @returns {boolean} Whether the button should be disabled.
|
||||
*/
|
||||
function checkPartial() {
|
||||
let disabled = true;
|
||||
switch (selectedActSeqFromTo.value) {
|
||||
|
||||
@@ -10,6 +10,16 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
// The Lucia project.
|
||||
// Copyright 2023-2026 DSP, inc. All rights reserved.
|
||||
// Authors:
|
||||
// chiayin.kuo@dsp.im (chiayin), 2023/1/31
|
||||
// imacat.yang@dsp.im (imacat), 2023/9/23
|
||||
/**
|
||||
* @module components/Discover/Conformance/ConformanceSidebar/ActList
|
||||
* Checkbox-based activity list for conformance checking input.
|
||||
*/
|
||||
|
||||
import { ref, watch } from 'vue';
|
||||
import { sortNumEngZhtw } from '@/module/sortNumEngZhtw.js';
|
||||
import emitter from '@/utils/emitter';
|
||||
@@ -27,9 +37,7 @@ watch(() => props.select, (newValue) => {
|
||||
actList.value = newValue;
|
||||
});
|
||||
|
||||
/**
|
||||
* 將選取的 Activities 傳出去
|
||||
*/
|
||||
/** Emits the selected activities list via the event bus. */
|
||||
function actListData() {
|
||||
emitter.emit('actListData', actList.value);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,18 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
// The Lucia project.
|
||||
// Copyright 2023-2026 DSP, inc. All rights reserved.
|
||||
// Authors:
|
||||
// chiayin.kuo@dsp.im (chiayin), 2023/1/31
|
||||
// cindy.chang@dsp.im (Cindy Chang), 2024/5/30
|
||||
// imacat.yang@dsp.im (imacat), 2023/9/23
|
||||
/**
|
||||
* @module components/Discover/Conformance/ConformanceSidebar/ActRadio
|
||||
* Radio-button activity selector for conformance checking
|
||||
* start/end activity input.
|
||||
*/
|
||||
|
||||
import { ref, computed, watch } from 'vue';
|
||||
import { useConformanceInputStore } from "@/stores/conformanceInput";
|
||||
import { sortNumEngZhtw } from '@/module/sortNumEngZhtw.js';
|
||||
@@ -37,9 +49,7 @@ const inputActivityRadioData = computed(() => ({
|
||||
task: selectedRadio.value,
|
||||
}));
|
||||
|
||||
/**
|
||||
* 將選取的 Activity 傳出去
|
||||
*/
|
||||
/** Emits the selected activity via event bus and updates the store. */
|
||||
function actRadioData() {
|
||||
localSelect.value = null;
|
||||
emitter.emit('actRadioData', inputActivityRadioData.value);
|
||||
@@ -47,6 +57,7 @@ function actRadioData() {
|
||||
conformanceInputStore.setActivityRadioStartEndData(inputActivityRadioData.value.task);
|
||||
}
|
||||
|
||||
/** Sets the global activity radio data state in the conformance input store. */
|
||||
function setGlobalActivityRadioDataState() {
|
||||
//this.title: value might be "From" or "To"
|
||||
conformanceInputStore.setActivityRadioStartEndData(inputActivityRadioData.value.task, props.title);
|
||||
|
||||
@@ -42,6 +42,18 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
// The Lucia project.
|
||||
// Copyright 2023-2026 DSP, inc. All rights reserved.
|
||||
// Authors:
|
||||
// chiayin.kuo@dsp.im (chiayin), 2023/1/31
|
||||
// cindy.chang@dsp.im (Cindy Chang), 2024/5/30
|
||||
// imacat.yang@dsp.im (imacat), 2023/9/23
|
||||
/**
|
||||
* @module components/Discover/Conformance/ConformanceSidebar/ActSeqDrag
|
||||
* Drag-and-drop activity sequence builder for
|
||||
* conformance rule configuration.
|
||||
*/
|
||||
|
||||
import { ref, computed } from 'vue';
|
||||
import { sortNumEngZhtw } from '@/module/sortNumEngZhtw.js';
|
||||
import emitter from '@/utils/emitter';
|
||||
|
||||
@@ -51,6 +51,17 @@
|
||||
</section>
|
||||
</template>
|
||||
<script setup>
|
||||
// The Lucia project.
|
||||
// Copyright 2023-2026 DSP, inc. All rights reserved.
|
||||
// Authors:
|
||||
// chiayin.kuo@dsp.im (chiayin), 2023/1/31
|
||||
// imacat.yang@dsp.im (imacat), 2023/9/23
|
||||
/**
|
||||
* @module components/Discover/Conformance/ConformanceSidebar/ConformanceRadioGroup
|
||||
* Radio button groups for conformance rule type, activity
|
||||
* sequence, mode, and process scope selection.
|
||||
*/
|
||||
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useConformanceStore } from '@/stores/conformance';
|
||||
import emitter from '@/utils/emitter';
|
||||
@@ -92,9 +103,7 @@ const actSeqFromTo = [
|
||||
{id: 3, name: 'From & To'},
|
||||
];
|
||||
|
||||
/**
|
||||
* 切換 Rule Type 的選項時的行為
|
||||
*/
|
||||
/** Resets dependent selections when the rule type radio changes. */
|
||||
function changeRadio() {
|
||||
selectedActivitySequence.value = 'Start & End';
|
||||
selectedMode.value = 'Directly follows';
|
||||
@@ -103,27 +112,19 @@ function changeRadio() {
|
||||
selectedActSeqFromTo.value = 'From';
|
||||
emitter.emit('isRadioChange', true); // Radio 切換時,資料要清空
|
||||
}
|
||||
/**
|
||||
* 切換 Activity sequence 的選項時的行為
|
||||
*/
|
||||
/** Emits event when the activity sequence radio changes. */
|
||||
function changeRadioSeq() {
|
||||
emitter.emit('isRadioSeqChange',true);
|
||||
}
|
||||
/**
|
||||
* 切換 Processing time 的選項時的行為
|
||||
*/
|
||||
/** Emits event when the process scope radio changes. */
|
||||
function changeRadioProcessScope() {
|
||||
emitter.emit('isRadioProcessScopeChange', true);
|
||||
}
|
||||
/**
|
||||
* 切換 Process Scope 的選項時的行為
|
||||
*/
|
||||
/** Emits event when the extended activity sequence radio changes. */
|
||||
function changeRadioActSeqMore() {
|
||||
emitter.emit('isRadioActSeqMoreChange', true);
|
||||
}
|
||||
/**
|
||||
* 切換 Activity Sequence 的選項時的行為
|
||||
*/
|
||||
/** Emits event when the from/to activity sequence radio changes. */
|
||||
function changeRadioActSeqFromTo() {
|
||||
emitter.emit('isRadioActSeqFromToChange', true);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,18 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
// The Lucia project.
|
||||
// Copyright 2023-2026 DSP, inc. All rights reserved.
|
||||
// Authors:
|
||||
// chiayin.kuo@dsp.im (chiayin), 2023/1/31
|
||||
// cindy.chang@dsp.im (Cindy Chang), 2024/5/30
|
||||
// imacat.yang@dsp.im (imacat), 2023/9/23
|
||||
/**
|
||||
* @module components/Discover/Conformance/ConformanceSidebar/ConformanceSelectResult
|
||||
* Conformance result list with selectable items and
|
||||
* scrollable display of check results.
|
||||
*/
|
||||
|
||||
import { reactive, computed } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useConformanceStore } from '@/stores/conformance';
|
||||
|
||||
@@ -98,6 +98,18 @@
|
||||
</section>
|
||||
</template>
|
||||
<script setup>
|
||||
// The Lucia project.
|
||||
// Copyright 2023-2026 DSP, inc. All rights reserved.
|
||||
// Authors:
|
||||
// chiayin.kuo@dsp.im (chiayin), 2023/1/31
|
||||
// cindy.chang@dsp.im (Cindy Chang), 2024/5/30
|
||||
// imacat.yang@dsp.im (imacat), 2023/9/23
|
||||
/**
|
||||
* @module components/Discover/Conformance/ConformanceSidebar/ConformanceShowBar
|
||||
* Horizontal bar chart component displaying conformance
|
||||
* check result statistics.
|
||||
*/
|
||||
|
||||
import { ref, computed, watch } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useLoadingStore } from '@/stores/loading';
|
||||
@@ -239,10 +251,9 @@ watch(() => props.isSubmitShowDataCt, (newValue) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* 設定 start and end 的 Radio Data
|
||||
* @param {object} data cfmSeqStart | cfmSeqEnd | cfmPtEteSE | cfmPtPSE | cfmWtEteSE | cfmWtPSE | cfmCtEteSE,
|
||||
* 傳入以上任一後端接到的 Activities 列表 Data。
|
||||
* @param {string} category 'start' | 'end',傳入 'start' 或 'end'。
|
||||
* Sets the start and end radio data.
|
||||
* @param {object} data - Activities list data from the backend (cfmSeqStart, cfmSeqEnd, cfmPtEteSE, etc.).
|
||||
* @param {string} category - 'start' or 'end'.
|
||||
* @returns {array}
|
||||
*/
|
||||
function setTaskData(data, category) {
|
||||
@@ -251,11 +262,10 @@ function setTaskData(data, category) {
|
||||
return newData;
|
||||
}
|
||||
/**
|
||||
* 重新設定連動的 start and end 的 Radio Data
|
||||
* @param {object} data cfmPtEteSE | cfmPtPSE | cfmWtEteSE | cfmWtPSE | cfmCtEteSE,
|
||||
* 傳入以上任一後端接到的 Activities 列表 Data。
|
||||
* @param {string} category 'start' | 'end',傳入 'start' 或 'end'。
|
||||
* @param {string} task 已選擇的 Activity task
|
||||
* Resets the linked start and end radio data.
|
||||
* @param {object} data - Activities list data from the backend (cfmPtEteSE, cfmPtPSE, etc.).
|
||||
* @param {string} category - 'start' or 'end'.
|
||||
* @param {string} task - The selected activity task.
|
||||
* @returns {array}
|
||||
*/
|
||||
function setStartAndEndData(data, category, taskVal) {
|
||||
@@ -270,10 +280,10 @@ function setStartAndEndData(data, category, taskVal) {
|
||||
return newData;
|
||||
}
|
||||
/**
|
||||
* 重新設定 Activity sequence 連動的 start and end 的 Radio Data
|
||||
* @param {object} data cfmSeqStart | cfmSeqEnd,傳入以上任一後端接到的 Activities 列表 Data。
|
||||
* @param {string} category 'sources' | 'sinks',傳入 'sources' 或 'sinks'。
|
||||
* @param {string} task 已選擇的 Activity task
|
||||
* Resets the activity sequence linked start and end radio data.
|
||||
* @param {object} data - Activities list data from the backend (cfmSeqStart or cfmSeqEnd).
|
||||
* @param {string} category - 'sources' or 'sinks'.
|
||||
* @param {string} task - The selected activity task.
|
||||
* @returns {array}
|
||||
*/
|
||||
function setSeqStartAndEndData(data, category, taskVal) {
|
||||
@@ -283,7 +293,7 @@ function setSeqStartAndEndData(data, category, taskVal) {
|
||||
}
|
||||
/**
|
||||
* select start list's task
|
||||
* @param {event} e 觸發 input 的詳細事件
|
||||
* @param {Event} e - The input event.
|
||||
*/
|
||||
function selectStart(e) {
|
||||
taskStart.value = e;
|
||||
@@ -300,7 +310,7 @@ function selectStart(e) {
|
||||
}
|
||||
/**
|
||||
* select End list's task
|
||||
* @param {event} e 觸發 input 的詳細事件
|
||||
* @param {Event} e - The input event.
|
||||
*/
|
||||
function selectEnd(e) {
|
||||
taskEnd.value = e;
|
||||
@@ -326,8 +336,8 @@ function reset() {
|
||||
taskEnd.value = null;
|
||||
}
|
||||
/**
|
||||
* Radio 切換時,Start & End Data 連動改變
|
||||
* @param {boolean} data true | false,傳入 true 或 false
|
||||
* Updates linked Start & End data when radio selection changes.
|
||||
* @param {boolean} data - Whether data should be restored from submission state.
|
||||
*/
|
||||
function setResetData(data) {
|
||||
if(data) {
|
||||
|
||||
@@ -68,6 +68,18 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
// The Lucia project.
|
||||
// Copyright 2023-2026 DSP, inc. All rights reserved.
|
||||
// Authors:
|
||||
// chiayin.kuo@dsp.im (chiayin), 2023/1/31
|
||||
// cindy.chang@dsp.im (Cindy Chang), 2024/5/30
|
||||
// imacat.yang@dsp.im (imacat), 2023/9/23
|
||||
/**
|
||||
* @module components/Discover/Conformance/ConformanceSidebar/ConformanceTimeRange
|
||||
* Time range picker for conformance time-based rule
|
||||
* configuration with calendar inputs.
|
||||
*/
|
||||
|
||||
import { reactive } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useConformanceStore } from '@/stores/conformance';
|
||||
@@ -149,22 +161,22 @@ const storeRefs = {
|
||||
|
||||
/**
|
||||
* get min total seconds
|
||||
* @param {Number} e 最小值總秒數
|
||||
* @param {number} e - The minimum total seconds.
|
||||
*/
|
||||
function minTotalSeconds(e) {
|
||||
emit('min-total-seconds', e);
|
||||
}
|
||||
/**
|
||||
* get min total seconds
|
||||
* @param {Number} e 最大值總秒數
|
||||
* @param {number} e - The maximum total seconds.
|
||||
*/
|
||||
function maxTotalSeconds(e) {
|
||||
emit('max-total-seconds', e);
|
||||
}
|
||||
/**
|
||||
* get Time Range(duration)
|
||||
* @param {array} data API data,Activity 列表
|
||||
* @param {string} category 'act' | 'single' | 'double',傳入以上任一值。
|
||||
* @param {Array} data - Activity list data from the API.
|
||||
* @param {string} category - 'act', 'single', or 'double'.
|
||||
* @param {string} task select Radio task or start
|
||||
* @param {string} taskTwo end
|
||||
* @returns {object} {min:12, max:345}
|
||||
|
||||
@@ -9,5 +9,16 @@
|
||||
</ul>
|
||||
</template>
|
||||
<script setup>
|
||||
// The Lucia project.
|
||||
// Copyright 2023-2026 DSP, inc. All rights reserved.
|
||||
// Authors:
|
||||
// chiayin.kuo@dsp.im (chiayin), 2023/1/31
|
||||
// imacat.yang@dsp.im (imacat), 2023/9/23
|
||||
/**
|
||||
* @module components/Discover/Conformance/ConformanceSidebar/ResultArrow
|
||||
* Conformance result display with arrow icons showing activity
|
||||
* sequences.
|
||||
*/
|
||||
|
||||
defineProps(['data', 'select']);
|
||||
</script>
|
||||
|
||||
@@ -9,6 +9,17 @@
|
||||
</ul>
|
||||
</template>
|
||||
<script setup>
|
||||
// The Lucia project.
|
||||
// Copyright 2023-2026 DSP, inc. All rights reserved.
|
||||
// Authors:
|
||||
// chiayin.kuo@dsp.im (chiayin), 2023/1/31
|
||||
// imacat.yang@dsp.im (imacat), 2023/9/23
|
||||
/**
|
||||
* @module components/Discover/Conformance/ConformanceSidebar/ResultCheck
|
||||
* Conformance result display with check-circle icons showing
|
||||
* matched activities.
|
||||
*/
|
||||
|
||||
import { ref, watch } from 'vue';
|
||||
import emitter from '@/utils/emitter';
|
||||
|
||||
|
||||
@@ -8,6 +8,17 @@
|
||||
</ul>
|
||||
</template>
|
||||
<script setup>
|
||||
// The Lucia project.
|
||||
// Copyright 2023-2026 DSP, inc. All rights reserved.
|
||||
// Authors:
|
||||
// chiayin.kuo@dsp.im (chiayin), 2023/1/31
|
||||
// imacat.yang@dsp.im (imacat), 2023/9/23
|
||||
/**
|
||||
* @module components/Discover/Conformance/ConformanceSidebar/ResultDot
|
||||
* Conformance result display with dot icons showing category
|
||||
* and task pairs.
|
||||
*/
|
||||
|
||||
import { ref, watch } from 'vue';
|
||||
import emitter from '@/utils/emitter';
|
||||
|
||||
|
||||
@@ -10,6 +10,18 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
// The Lucia project.
|
||||
// Copyright 2023-2026 DSP, inc. All rights reserved.
|
||||
// Authors:
|
||||
// chiayin.kuo@dsp.im (chiayin), 2023/1/31
|
||||
// cindy.chang@dsp.im (Cindy Chang), 2024/5/30
|
||||
// imacat.yang@dsp.im (imacat), 2023/9/23
|
||||
/**
|
||||
* @module components/Discover/Conformance/ConformanceSidebar/TimeRangeDuration
|
||||
* Time range duration picker with min/max duration inputs
|
||||
* for conformance time-based rules.
|
||||
*/
|
||||
|
||||
import { ref, watch } from 'vue';
|
||||
import Durationjs from '@/components/durationjs.vue';
|
||||
|
||||
@@ -28,9 +40,7 @@ const updateMin = ref(null);
|
||||
const durationMin = ref(null);
|
||||
const durationMax = ref(null);
|
||||
|
||||
/**
|
||||
* set props values
|
||||
*/
|
||||
/** Deep-copies timeData min/max values to the Vue component boundaries. */
|
||||
function setTimeValue() {
|
||||
// 深拷貝原始 timeData 的內容
|
||||
minVuemin.value = JSON.parse(JSON.stringify(timeData.value.min));
|
||||
@@ -40,8 +50,8 @@ function setTimeValue() {
|
||||
}
|
||||
|
||||
/**
|
||||
* get min total seconds
|
||||
* @param {Number} e 元件傳來的最小值總秒數
|
||||
* Handles the minimum duration total seconds update.
|
||||
* @param {number} e - The total seconds from the min duration component.
|
||||
*/
|
||||
function minTotalSeconds(e) {
|
||||
timeRangeMin.value = e;
|
||||
@@ -50,8 +60,8 @@ function minTotalSeconds(e) {
|
||||
}
|
||||
|
||||
/**
|
||||
* get min total seconds
|
||||
* @param {Number} e 元件傳來的最大值總秒數
|
||||
* Handles the maximum duration total seconds update.
|
||||
* @param {number} e - The total seconds from the max duration component.
|
||||
*/
|
||||
function maxTotalSeconds(e) {
|
||||
timeRangeMax.value = e;
|
||||
|
||||
@@ -62,6 +62,18 @@
|
||||
</Dialog>
|
||||
</template>
|
||||
<script setup>
|
||||
// The Lucia project.
|
||||
// Copyright 2023-2026 DSP, inc. All rights reserved.
|
||||
// Authors:
|
||||
// chiayin.kuo@dsp.im (chiayin), 2023/1/31
|
||||
// cindy.chang@dsp.im (Cindy Chang), 2024/5/30
|
||||
// imacat.yang@dsp.im (imacat), 2023/9/23
|
||||
/**
|
||||
* @module components/Discover/Conformance/MoreModal
|
||||
* Modal dialog showing detailed conformance check
|
||||
* results with expandable activity sequences.
|
||||
*/
|
||||
|
||||
import { ref, computed, watch, nextTick, useTemplateRef } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useConformanceStore } from '@/stores/conformance';
|
||||
@@ -169,8 +181,8 @@ watch(infinite404, (newValue) => {
|
||||
// methods
|
||||
/**
|
||||
* Number to percentage
|
||||
* @param {number} val 原始數字
|
||||
* @returns {string} 轉換完成的百分比字串
|
||||
* @param {number} val - The raw ratio value.
|
||||
* @returns {string} The formatted percentage string.
|
||||
*/
|
||||
function getPercentLabel(val){
|
||||
if((val * 100).toFixed(1) >= 100) return 100;
|
||||
@@ -178,8 +190,8 @@ function getPercentLabel(val){
|
||||
}
|
||||
/**
|
||||
* set progress bar width
|
||||
* @param {number} value 百分比數字
|
||||
* @returns {string} 樣式的寬度設定
|
||||
* @param {number} value - The percentage value.
|
||||
* @returns {string} The CSS width style string.
|
||||
*/
|
||||
function progressWidth(value){
|
||||
return `width:${value}%;`
|
||||
@@ -201,7 +213,7 @@ async function switchCaseData(id) {
|
||||
showTraceId.value = id; // 放 getDetail 為了 case table 載入完再切換 showTraceId
|
||||
}
|
||||
/**
|
||||
* 將 trace element nodes 資料彙整
|
||||
* Assembles the trace element nodes data for Cytoscape rendering.
|
||||
*/
|
||||
function setNodesData(){
|
||||
// 避免每次渲染都重複累加
|
||||
@@ -224,7 +236,7 @@ function setNodesData(){
|
||||
};
|
||||
}
|
||||
/**
|
||||
* 將 trace edge line 資料彙整
|
||||
* Assembles the trace edge line data for Cytoscape rendering.
|
||||
*/
|
||||
function setEdgesData(){
|
||||
processMap.value.edges = [];
|
||||
@@ -256,7 +268,7 @@ function createCy(){
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 無限滾動: 載入數據
|
||||
* Infinite scroll: loads more data.
|
||||
*/
|
||||
async function fetchData() {
|
||||
try {
|
||||
@@ -270,8 +282,8 @@ async function fetchData() {
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 無限滾動: 監聽 scroll 有沒有滾到底部
|
||||
* @param {element} event 監聽時回傳的事件
|
||||
* Infinite scroll: listens for scroll reaching the bottom.
|
||||
* @param {Event} event - The scroll event.
|
||||
*/
|
||||
function handleScroll(event) {
|
||||
if(maxItems.value || infiniteData.value.length < 20 || infiniteFinish.value === false) return;
|
||||
|
||||
@@ -58,6 +58,16 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
// The Lucia project.
|
||||
// Copyright 2023-2026 DSP, inc. All rights reserved.
|
||||
// Authors:
|
||||
// chiayin.kuo@dsp.im (chiayin), 2023/1/31
|
||||
/**
|
||||
* @module components/Discover/Map/Filter/ActAndSeq Activity list
|
||||
* with drag-and-drop sequence builder for creating filter
|
||||
* rules.
|
||||
*/
|
||||
|
||||
import { ref, computed, watch } from 'vue';
|
||||
import { sortNumEngZhtwForFilter } from '@/module/sortNumEngZhtw.js';
|
||||
|
||||
@@ -100,33 +110,31 @@ watch(() => props.filterTaskData, (newval) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* double click Activity List
|
||||
* @param {number} index data item index
|
||||
* @param {object} element data item
|
||||
* Moves an activity from the list to the sequence on double-click.
|
||||
* @param {number} index - The item index in the activity list.
|
||||
* @param {Object} element - The activity data object.
|
||||
*/
|
||||
function moveActItem(index, element) {
|
||||
listSequence.value.push(element);
|
||||
}
|
||||
|
||||
/**
|
||||
* double click Sequence List
|
||||
* @param {number} index data item index
|
||||
* @param {object} element data item
|
||||
* Removes an activity from the sequence on double-click.
|
||||
* @param {number} index - The item index in the sequence.
|
||||
* @param {Object} element - The activity data object.
|
||||
*/
|
||||
function moveSeqItem(index, element) {
|
||||
listSequence.value.splice(index, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* get listSequence
|
||||
*/
|
||||
/** Emits the current sequence list to the parent component. */
|
||||
function getComponentData() {
|
||||
emit('update:listSeq', listSequence.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Element dragging started
|
||||
* @param {event} evt input 傳入的事件
|
||||
* Handles drag start: hides original element and last arrow.
|
||||
* @param {Event} evt - The drag start event.
|
||||
*/
|
||||
function onStart(evt) {
|
||||
const lastChild = evt.to.lastChild.lastChild;
|
||||
@@ -140,8 +148,8 @@ function onStart(evt) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Element dragging ended
|
||||
* @param {event} evt input 傳入的事件
|
||||
* Handles drag end: restores element visibility.
|
||||
* @param {Event} evt - The drag end event.
|
||||
*/
|
||||
function onEnd(evt) {
|
||||
// 顯示拖曳元素
|
||||
|
||||
@@ -29,6 +29,15 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
// The Lucia project.
|
||||
// Copyright 2023-2026 DSP, inc. All rights reserved.
|
||||
// Authors:
|
||||
// chiayin.kuo@dsp.im (chiayin), 2023/1/31
|
||||
/**
|
||||
* @module components/Discover/Map/Filter/ActOcc Activity
|
||||
* occurrences filter table with single-row radio selection.
|
||||
*/
|
||||
|
||||
import { ref, watch } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
@@ -60,8 +69,8 @@ watch(() => props.tableSelect, (newval) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* 將選取的 row 傳到父層
|
||||
* @param {event} e input 傳入的事件
|
||||
* Emits the selected row to the parent component.
|
||||
* @param {Event} e - The row selection event.
|
||||
*/
|
||||
function onRowSelect(e) {
|
||||
emit('on-row-select', e);
|
||||
|
||||
@@ -40,6 +40,16 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// The Lucia project.
|
||||
// Copyright 2023-2026 DSP, inc. All rights reserved.
|
||||
// Authors:
|
||||
// chiayin.kuo@dsp.im (chiayin), 2023/1/31
|
||||
/**
|
||||
* @module components/Discover/Map/Filter/ActOccCase Activity
|
||||
* occurrences and cases filter table with multi-row checkbox
|
||||
* selection.
|
||||
*/
|
||||
|
||||
import { ref, watch } from 'vue';
|
||||
|
||||
const props = defineProps(['tableTitle', 'tableData', 'tableSelect', 'progressWidth']);
|
||||
@@ -53,23 +63,19 @@ watch(() => props.tableSelect, (newval) => {
|
||||
select.value = newval;
|
||||
});
|
||||
|
||||
/**
|
||||
* 選擇 Row 的行為
|
||||
*/
|
||||
/** Emits the current selection when a row is selected. */
|
||||
function onRowSelect() {
|
||||
emit('on-row-select', select.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消選取 Row 的行為
|
||||
*/
|
||||
/** Emits the current selection when a row is unselected. */
|
||||
function onRowUnselect() {
|
||||
emit('on-row-select', select.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 全選 Row 的行為
|
||||
* @param {event} e input 傳入的事件
|
||||
* Handles select-all rows action.
|
||||
* @param {Event} e - The select-all event with data property.
|
||||
*/
|
||||
function onRowSelectAll(e) {
|
||||
select.value = e.data;
|
||||
@@ -77,8 +83,8 @@ function onRowSelectAll(e) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消全選 Row 的行為
|
||||
* @param {event} e input 傳入的事件
|
||||
* Handles unselect-all rows action.
|
||||
* @param {Event} e - The unselect-all event.
|
||||
*/
|
||||
function onRowUnelectAll(e) {
|
||||
select.value = null;
|
||||
|
||||
@@ -120,6 +120,18 @@
|
||||
</section>
|
||||
</template>
|
||||
<script setup>
|
||||
// The Lucia project.
|
||||
// Copyright 2023-2026 DSP, inc. All rights reserved.
|
||||
// Authors:
|
||||
// chiayin.kuo@dsp.im (chiayin), 2023/1/31
|
||||
// cindy.chang@dsp.im (Cindy Chang), 2024/5/30
|
||||
// imacat.yang@dsp.im (imacat), 2023/9/23
|
||||
/**
|
||||
* @module components/Discover/Map/Filter/Attributes
|
||||
* Case attribute filter with dynamic form fields
|
||||
* for filtering by attribute values.
|
||||
*/
|
||||
|
||||
import { ref, computed, onMounted, onBeforeUnmount } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useAllMapDataStore } from '@/stores/allMapData';
|
||||
@@ -313,7 +325,7 @@ const labelsData = computed(() => {
|
||||
});
|
||||
|
||||
/**
|
||||
* 選取類別型 table 的選項
|
||||
* Selects an option in the categorical table.
|
||||
*/
|
||||
function onRowSelect() {
|
||||
const type = selectedAttName.value.type;
|
||||
@@ -325,7 +337,7 @@ function onRowSelect() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消類別型 table 的選項
|
||||
* Deselects an option in the categorical table.
|
||||
*/
|
||||
function onRowUnselect() {
|
||||
const type = selectedAttName.value.type;
|
||||
@@ -337,8 +349,8 @@ function onRowUnselect() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 選取類別型 table 的全選項
|
||||
* @param {event} e input 傳入的事件
|
||||
* Selects all options in the categorical table.
|
||||
* @param {Event} e - The input event.
|
||||
*/
|
||||
function onRowSelectAll(e) {
|
||||
selectedAttRange.value = e.data;
|
||||
@@ -351,7 +363,7 @@ function onRowSelectAll(e) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消類別型 table 的全選項
|
||||
* Deselects all options in the categorical table.
|
||||
*/
|
||||
function onRowUnelectAll() {
|
||||
selectedAttRange.value = null;
|
||||
@@ -364,8 +376,8 @@ function onRowUnelectAll() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 切換 Attribute Name Radio
|
||||
* @param {event} e input 傳入的事件
|
||||
* Switches the attribute name radio selection.
|
||||
* @param {Event} e - The input event.
|
||||
*/
|
||||
function switchAttNameRadio(e) {
|
||||
selectedAttRange.value = null;
|
||||
@@ -416,8 +428,8 @@ function switchAttNameRadio(e) {
|
||||
|
||||
/**
|
||||
* set progress bar width
|
||||
* @param {number} value 百分比數字
|
||||
* @returns {string} 樣式的寬度設定
|
||||
* @param {number} value - The percentage value.
|
||||
* @returns {string} The CSS width style string.
|
||||
*/
|
||||
function progressWidth(value){
|
||||
return `width:${value}%;`
|
||||
@@ -425,8 +437,8 @@ function progressWidth(value){
|
||||
|
||||
/**
|
||||
* Number to percentage
|
||||
* @param {number} val 原始數字
|
||||
* @returns {string} 轉換完成的百分比字串
|
||||
* @param {number} val - The raw ratio value.
|
||||
* @returns {string} The formatted percentage string.
|
||||
*/
|
||||
function getPercentLabel(val){
|
||||
if((val * 100).toFixed(1) >= 100) return `100%`;
|
||||
@@ -434,8 +446,8 @@ function getPercentLabel(val){
|
||||
}
|
||||
|
||||
/**
|
||||
* 調整遮罩大小
|
||||
* @param {object} chart 取得 chart.js 資料
|
||||
* Adjusts the overlay mask size.
|
||||
* @param {object} chart - The Chart.js instance data.
|
||||
*/
|
||||
function resizeMask(chart) {
|
||||
const from = (selectArea.value[0] * 0.01) / (selectRange.value * 0.01);
|
||||
@@ -445,8 +457,8 @@ function resizeMask(chart) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 調整左邊遮罩大小
|
||||
* @param {object} chart 取得 chart.js 資料
|
||||
* Adjusts the left overlay mask size.
|
||||
* @param {object} chart - The Chart.js instance data.
|
||||
*/
|
||||
function resizeLeftMask(chart, from) {
|
||||
const canvas = document.querySelector('#chartCanvasId canvas');
|
||||
@@ -458,8 +470,8 @@ function resizeLeftMask(chart, from) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 調整右邊遮罩大小
|
||||
* @param {object} chart 取得 chart.js 資料
|
||||
* Adjusts the right overlay mask size.
|
||||
* @param {object} chart - The Chart.js instance data.
|
||||
*/
|
||||
function resizeRightMask(chart, to) {
|
||||
const canvas = document.querySelector('#chartCanvasId canvas');
|
||||
@@ -471,7 +483,7 @@ function resizeRightMask(chart, to) {
|
||||
}
|
||||
|
||||
/**
|
||||
* create chart
|
||||
* Creates and renders the Chart.js line chart for attribute data.
|
||||
*/
|
||||
function createChart() {
|
||||
const vData = valueData.value;
|
||||
@@ -632,7 +644,7 @@ function createChart() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 滑塊改變的時候
|
||||
* Handles slider value changes.
|
||||
* @param {array} e [1, 100]
|
||||
*/
|
||||
function changeSelectArea(e) {
|
||||
@@ -665,8 +677,8 @@ function changeSelectArea(e) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 選取開始或結束時間時,要改變滑塊跟圖表
|
||||
* @param {object} e Tue Jan 25 2022 00:00:00 GMT+0800 (台北標準時間) | Blur Event
|
||||
* Updates the slider and chart when a start or end time is selected.
|
||||
* @param {object} e - The date object or blur event.
|
||||
* @param {string} direction start or end
|
||||
*/
|
||||
function sliderValueRange(e, direction) {
|
||||
|
||||
@@ -39,6 +39,16 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// The Lucia project.
|
||||
// Copyright 2023-2026 DSP, inc. All rights reserved.
|
||||
// Authors:
|
||||
// chiayin.kuo@dsp.im (chiayin), 2023/1/31
|
||||
/**
|
||||
* @module components/Discover/Map/Filter/Funnel Filter funnel
|
||||
* panel showing applied filter rules with toggle, delete, and
|
||||
* apply-all actions.
|
||||
*/
|
||||
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useToast } from 'vue-toast-notification';
|
||||
import { useLoadingStore } from '@/stores/loading';
|
||||
@@ -54,8 +64,9 @@ const { isLoading } = storeToRefs(loadingStore);
|
||||
const { hasResultRule, temporaryData, postRuleData, ruleData, isRuleData, tempFilterId } = storeToRefs(allMapDataStore);
|
||||
|
||||
/**
|
||||
* @param {boolean} e ture | false,可選 ture 或 false
|
||||
* @param {numble} index rule's index
|
||||
* Toggles a filter rule on or off.
|
||||
* @param {boolean} e - Whether the rule is enabled.
|
||||
* @param {number} index - The rule index.
|
||||
*/
|
||||
function isRule(e, index){
|
||||
const rule = isRuleData.value[index];
|
||||
@@ -66,8 +77,8 @@ function isRule(e, index){
|
||||
}
|
||||
|
||||
/**
|
||||
* header:Funnel 刪除全部的 Funnel
|
||||
* @param {numble|string} index rule's index 或 全部
|
||||
* Deletes a single filter rule or all rules.
|
||||
* @param {number|string} index - The rule index, or 'all' to delete all.
|
||||
*/
|
||||
async function deleteRule(index) {
|
||||
if(index === 'all') {
|
||||
@@ -91,9 +102,7 @@ async function deleteRule(index) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* header:Funnel 發送暫存的選取資料
|
||||
*/
|
||||
/** Submits all enabled filter rules and refreshes the map data. */
|
||||
async function submitAll() {
|
||||
postRuleData.value = temporaryData.value.filter(item => item !== 0); // 取得 submit 的資料,有 toggle button 的話,找出並刪除陣列中為 0 的項目
|
||||
if(!postRuleData.value?.length) return $toast.error('Not selected');
|
||||
|
||||
@@ -31,6 +31,16 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
// The Lucia project.
|
||||
// Copyright 2023-2026 DSP, inc. All rights reserved.
|
||||
// Authors:
|
||||
// chiayin.kuo@dsp.im (chiayin), 2023/1/31
|
||||
/**
|
||||
* @module components/Discover/Map/Filter/Timeframes
|
||||
* Timeframe filter with date range pickers and
|
||||
* duration range selectors.
|
||||
*/
|
||||
|
||||
import { ref, computed, watch, onMounted } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useAllMapDataStore } from '@/stores/allMapData';
|
||||
@@ -151,8 +161,8 @@ watch(selectTimeFrame, (newValue, oldValue) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* 調整遮罩大小
|
||||
* @param {object} chartInstance 取得 chart.js 資料
|
||||
* Adjusts the overlay mask size.
|
||||
* @param {object} chartInstance - The Chart.js instance.
|
||||
*/
|
||||
function resizeMask(chartInstance) {
|
||||
const from = (selectArea.value[0] * 0.01) / (selectRange.value * 0.01);
|
||||
@@ -164,8 +174,8 @@ function resizeMask(chartInstance) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 調整左邊遮罩大小
|
||||
* @param {object} chartInstance 取得 chart.js 資料
|
||||
* Adjusts the left overlay mask size.
|
||||
* @param {object} chartInstance - The Chart.js instance.
|
||||
*/
|
||||
function resizeLeftMask(chartInstance, from) {
|
||||
const canvas = document.getElementById("chartCanvasId");
|
||||
@@ -177,8 +187,8 @@ function resizeLeftMask(chartInstance, from) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 調整右邊遮罩大小
|
||||
* @param {object} chartInstance 取得 chart.js 資料
|
||||
* Adjusts the right overlay mask size.
|
||||
* @param {object} chartInstance - The Chart.js instance.
|
||||
*/
|
||||
function resizeRightMask(chartInstance, to) {
|
||||
const canvas = document.getElementById("chartCanvasId");
|
||||
@@ -190,7 +200,7 @@ function resizeRightMask(chartInstance, to) {
|
||||
}
|
||||
|
||||
/**
|
||||
* create chart
|
||||
* Creates and renders the Chart.js area chart for timeframe data.
|
||||
*/
|
||||
function createChart() {
|
||||
const max = filterTimeframe.value.y_axis.max * 1.1;
|
||||
@@ -289,7 +299,7 @@ function createChart() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 滑塊改變的時候
|
||||
* Handles slider value changes.
|
||||
* @param {array} e [1, 100]
|
||||
*/
|
||||
function changeSelectArea(e) {
|
||||
@@ -310,8 +320,8 @@ function changeSelectArea(e) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 選取開始或結束時間時,要改變滑塊跟圖表
|
||||
* @param {object} e Tue Jan 25 2022 00:00:00 GMT+0800 (台北標準時間)
|
||||
* Updates the slider and chart when a start or end time is selected.
|
||||
* @param {object} e - The selected date object.
|
||||
* @param {string} direction start or end
|
||||
*/
|
||||
function sliderTimeRange(e, direction) {
|
||||
|
||||
@@ -69,6 +69,16 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// The Lucia project.
|
||||
// Copyright 2023-2026 DSP, inc. All rights reserved.
|
||||
// Authors:
|
||||
// chiayin.kuo@dsp.im (chiayin), 2023/1/31
|
||||
/**
|
||||
* @module components/Discover/Map/Filter/Trace
|
||||
* Trace filter with trace selection table and
|
||||
* trace detail display.
|
||||
*/
|
||||
|
||||
import { ref, computed, watch, onMounted } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useAllMapDataStore } from '@/stores/allMapData';
|
||||
@@ -238,8 +248,8 @@ function barOptions(){
|
||||
|
||||
/**
|
||||
* Number to percentage
|
||||
* @param {number} val 原始數字
|
||||
* @returns {string} 轉換完成的百分比字串
|
||||
* @param {number} val - The raw ratio value.
|
||||
* @returns {string} The formatted percentage string.
|
||||
*/
|
||||
function getPercentLabel(val){
|
||||
if((val * 100).toFixed(1) >= 100) return 100;
|
||||
@@ -248,8 +258,8 @@ function getPercentLabel(val){
|
||||
|
||||
/**
|
||||
* set progress bar width
|
||||
* @param {number} value 百分比數字
|
||||
* @returns {string} 樣式的寬度設定
|
||||
* @param {number} value - The percentage value.
|
||||
* @returns {string} The CSS width style string.
|
||||
*/
|
||||
function progressWidth(value){
|
||||
return `width:${value}%;`
|
||||
@@ -258,7 +268,7 @@ function progressWidth(value){
|
||||
/**
|
||||
* switch case data
|
||||
* @param {number} id case id
|
||||
* @param {number} count 所有的 case 數量
|
||||
* @param {number} count - The total number of cases.
|
||||
*/
|
||||
async function switchCaseData(id, count) {
|
||||
// 點同一筆 id 不要有動作
|
||||
@@ -275,7 +285,7 @@ async function switchCaseData(id, count) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 將 trace element nodes 資料彙整
|
||||
* Assembles the trace element nodes data for Cytoscape rendering.
|
||||
*/
|
||||
function setNodesData(){
|
||||
// 避免每次渲染都重複累加
|
||||
@@ -297,7 +307,7 @@ function setNodesData(){
|
||||
}
|
||||
|
||||
/**
|
||||
* 將 trace edge line 資料彙整
|
||||
* Assembles the trace edge line data for Cytoscape rendering.
|
||||
*/
|
||||
function setEdgesData(){
|
||||
processMap.value.edges = [];
|
||||
@@ -327,8 +337,8 @@ function createCy(){
|
||||
}
|
||||
|
||||
/**
|
||||
* 無限滾動: 監聽 scroll 有沒有滾到底部
|
||||
* @param {element} event 滾動傳入的事件
|
||||
* Infinite scroll: listens for scroll reaching the bottom.
|
||||
* @param {Event} event - The scroll event.
|
||||
*/
|
||||
function handleScroll(event) {
|
||||
if(infinitMaxItems.value || baseCases.value.length < 20 || infiniteFinish.value === false) return;
|
||||
@@ -340,7 +350,7 @@ function handleScroll(event) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 無限滾動: 滾到底後,要載入數據
|
||||
* Infinite scroll: loads more data when the bottom is reached.
|
||||
*/
|
||||
async function fetchData() {
|
||||
try {
|
||||
|
||||
@@ -97,6 +97,17 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// The Lucia project.
|
||||
// Copyright 2023-2026 DSP, inc. All rights reserved.
|
||||
// Authors:
|
||||
// chiayin.kuo@dsp.im (chiayin), 2023/1/31
|
||||
/**
|
||||
* @module components/Discover/Map/SidebarFilter
|
||||
* Filter sidebar for the Map view with tabbed panels
|
||||
* for activity, timeframe, attribute, and trace
|
||||
* filters.
|
||||
*/
|
||||
|
||||
import { ref, reactive, computed } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useToast } from 'vue-toast-notification';
|
||||
@@ -227,6 +238,7 @@ const isDisabledButton = computed(() => {
|
||||
/**
|
||||
* Change Radio Filter Type
|
||||
*/
|
||||
/** Checks if the apply button should be disabled based on filter type. */
|
||||
function radioFilterType() {
|
||||
reset();
|
||||
}
|
||||
@@ -234,6 +246,7 @@ function radioFilterType() {
|
||||
/**
|
||||
* Change Radio Act Seq
|
||||
*/
|
||||
/** Checks if the apply button should be disabled for activity sequence. */
|
||||
function radioActSeq() {
|
||||
reset();
|
||||
}
|
||||
@@ -241,6 +254,7 @@ function radioActSeq() {
|
||||
/**
|
||||
* Change Radio Start And End
|
||||
*/
|
||||
/** Checks if the apply button should be disabled for start & end filter. */
|
||||
function radioStartAndEnd() {
|
||||
reset();
|
||||
}
|
||||
@@ -254,8 +268,8 @@ function switchTab(newTab) {
|
||||
|
||||
/**
|
||||
* Number to percentage
|
||||
* @param {number} val 原始數字
|
||||
* @returns {string} 轉換完成的百分比字串
|
||||
* @param {number} val - The raw ratio value.
|
||||
* @returns {string} The formatted percentage string.
|
||||
*/
|
||||
function getPercentLabel(val){
|
||||
if((val * 100).toFixed(1) >= 100) return `100%`;
|
||||
@@ -264,8 +278,8 @@ function getPercentLabel(val){
|
||||
|
||||
/**
|
||||
* set progress bar width
|
||||
* @param {number} value 百分比數字
|
||||
* @returns {string} 樣式的寬度設定
|
||||
* @param {number} value - The percentage value.
|
||||
* @returns {string} The CSS width style string.
|
||||
*/
|
||||
function progressWidth(value){
|
||||
return `width:${value}%;`
|
||||
@@ -293,7 +307,7 @@ function setHaveAct(data){
|
||||
|
||||
// 調整 filterStartData / filterEndData / filterStartToEndData / filterEndToStartData 的內容
|
||||
/**
|
||||
* @param {array} array filterStartToEnd / filterEndToStart,可傳入以上任一。
|
||||
* @param {Array} array - filterStartToEnd or filterEndToStart data array.
|
||||
*/
|
||||
function setActData(array) {
|
||||
const list = [];
|
||||
@@ -376,7 +390,7 @@ function endRow(e) {
|
||||
// 重新設定連動的 filterStartToEndData / filterEndToStartData 內容
|
||||
/**
|
||||
* @param {array} eventData Start or End List
|
||||
* @param {object} rowDataVal 所選擇的 row's data
|
||||
* @param {object} rowDataVal - The selected row's data.
|
||||
* @param {string} event sinks / sources
|
||||
*/
|
||||
function setStartAndEndData(eventData, rowDataVal, event){
|
||||
@@ -398,6 +412,11 @@ function setStartAndEndData(eventData, rowDataVal, event){
|
||||
/**
|
||||
* @param {object} e task's object
|
||||
*/
|
||||
/**
|
||||
* Creates a display rule object from filter event data.
|
||||
* @param {object} e - The filter rule data.
|
||||
* @returns {object} The display rule with type, label, and toggle.
|
||||
*/
|
||||
function setRule(e) {
|
||||
let label, type;
|
||||
const includeStr = e.is_exclude? "exclude" : "include";
|
||||
@@ -449,7 +468,7 @@ function setRule(e) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {boolean} message true | false 清空選項,可選以上任一。
|
||||
* @param {boolean} message - Whether to show the success toast message.
|
||||
*/
|
||||
function reset(message) {
|
||||
// Sequence
|
||||
@@ -480,7 +499,7 @@ function reset(message) {
|
||||
}
|
||||
|
||||
/**
|
||||
* header:Filter 發送選取的資料
|
||||
* Submits the selected filter data to the backend.
|
||||
*/
|
||||
async function submit() {
|
||||
isLoading.value = true;
|
||||
@@ -520,10 +539,16 @@ async function submit() {
|
||||
/**
|
||||
* create map
|
||||
*/
|
||||
/** Triggers the submit-all event to create the map. */
|
||||
function sumbitAll() {
|
||||
emit('submit-all');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the sequence filter selection is valid.
|
||||
* @param {Array} sele - The current selection values.
|
||||
* @returns {boolean} Whether the button should be disabled.
|
||||
*/
|
||||
function handleSequenceSelection(sele) {
|
||||
const secondSelection = sele[1];
|
||||
|
||||
@@ -539,6 +564,11 @@ function handleSequenceSelection(sele) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the start & end sub-selection is valid.
|
||||
* @param {string} option - 'Start', 'End', or 'Start & End'.
|
||||
* @returns {boolean} Whether the button should be disabled.
|
||||
*/
|
||||
function handleStartEndSelection(option) {
|
||||
switch (option) {
|
||||
case 'Start':
|
||||
@@ -552,6 +582,11 @@ function handleStartEndSelection(option) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the attribute filter selection is valid.
|
||||
* @param {string} type - The attribute type.
|
||||
* @returns {boolean} Whether the button should be disabled.
|
||||
*/
|
||||
function handleAttributesSelection(type) {
|
||||
switch (type) {
|
||||
case 'string':
|
||||
@@ -567,14 +602,25 @@ function handleAttributesSelection(type) {
|
||||
}
|
||||
}
|
||||
|
||||
/** Checks if the trace filter selection is valid.
|
||||
* @returns {boolean} Whether the button should be disabled.
|
||||
*/
|
||||
function handleTraceSelection() {
|
||||
return selectTraceArea.value[0] === selectTraceArea.value[1];
|
||||
}
|
||||
|
||||
/** Checks if the timeframes filter selection is valid.
|
||||
* @returns {boolean} Whether the button should be disabled.
|
||||
*/
|
||||
function handleTimeframesSelection() {
|
||||
return selectTimeFrame.value.length === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the display label for a task filter rule.
|
||||
* @param {object} e - The filter rule data.
|
||||
* @returns {string} The formatted label.
|
||||
*/
|
||||
function getTaskLabel(e) {
|
||||
switch (e.type) {
|
||||
case "contains-task":
|
||||
@@ -589,6 +635,11 @@ function getTaskLabel(e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the display label for an attribute filter rule.
|
||||
* @param {object} e - The filter rule data.
|
||||
* @returns {string} The formatted label.
|
||||
*/
|
||||
function getAttributeLabel(e) {
|
||||
switch (e.type) {
|
||||
case 'string-attr':
|
||||
@@ -603,6 +654,13 @@ function getAttributeLabel(e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds filter data from the current selections.
|
||||
* @param {Array} sele - The current selection values.
|
||||
* @param {boolean} isExclude - Whether this is an exclude filter.
|
||||
* @param {object} containmentMap - Containment type mapping.
|
||||
* @returns {object|Array} The filter data to submit.
|
||||
*/
|
||||
function getFilterData(sele, isExclude, containmentMap) {
|
||||
switch (sele[0]) {
|
||||
case 'Sequence':
|
||||
@@ -623,6 +681,12 @@ function getFilterData(sele, isExclude, containmentMap) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds sequence filter data.
|
||||
* @param {Array} sele - The current selection values.
|
||||
* @param {boolean} isExclude - Whether this is an exclude filter.
|
||||
* @returns {object} The sequence filter data.
|
||||
*/
|
||||
function getSequenceData(sele, isExclude) {
|
||||
switch (sele[1]) {
|
||||
case 'Have activity(s)':
|
||||
@@ -644,6 +708,12 @@ function getSequenceData(sele, isExclude) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds start & end filter data.
|
||||
* @param {Array} sele - The current selection values.
|
||||
* @param {boolean} isExclude - Whether this is an exclude filter.
|
||||
* @returns {object} The start & end filter data.
|
||||
*/
|
||||
function getStartEndData(sele, isExclude) {
|
||||
switch (sele[2]) {
|
||||
case 'Start':
|
||||
@@ -670,6 +740,11 @@ function getStartEndData(sele, isExclude) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds attributes filter data.
|
||||
* @param {boolean} isExclude - Whether this is an exclude filter.
|
||||
* @returns {object} The attributes filter data.
|
||||
*/
|
||||
function getAttributesData(isExclude) {
|
||||
const attrTypeMap = {
|
||||
'string': 'string-attr',
|
||||
@@ -704,6 +779,11 @@ function getAttributesData(isExclude) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds trace filter data.
|
||||
* @param {boolean} isExclude - Whether this is an exclude filter.
|
||||
* @returns {object} The trace filter data.
|
||||
*/
|
||||
function getTraceData(isExclude) {
|
||||
const lowerIndex = filterTraceViewRef.value.selectArea[0];
|
||||
const upperIndex = filterTraceViewRef.value.selectArea[1] - 1;
|
||||
@@ -715,6 +795,10 @@ function getTraceData(isExclude) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the rules list with newly submitted filter data.
|
||||
* @param {Array} postData - The submitted filter data.
|
||||
*/
|
||||
function updateRules(postData) {
|
||||
if (!temporaryData.value?.length) {
|
||||
temporaryData.value.push(...postData);
|
||||
@@ -727,6 +811,11 @@ function updateRules(postData) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a promise that resolves after the given delay.
|
||||
* @param {number} ms - The delay in milliseconds.
|
||||
* @returns {Promise} Resolves after the delay.
|
||||
*/
|
||||
function delay(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
@@ -242,6 +242,17 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// The Lucia project.
|
||||
// Copyright 2023-2026 DSP, inc. All rights reserved.
|
||||
// Authors:
|
||||
// chiayin.kuo@dsp.im (chiayin), 2023/1/31
|
||||
/**
|
||||
* @module components/Discover/Map/SidebarState
|
||||
* Summary statistics sidebar for the Map view
|
||||
* displaying cases, traces, activities, timeframe,
|
||||
* and case duration.
|
||||
*/
|
||||
|
||||
import { computed, ref } from 'vue';
|
||||
import { usePageAdminStore } from '@/stores/pageAdmin';
|
||||
import { useMapPathStore } from '@/stores/mapPathStore';
|
||||
@@ -282,17 +293,26 @@ const valueTraces = ref(0);
|
||||
const valueTaskInstances = ref(0);
|
||||
const valueTasks = ref(0);
|
||||
|
||||
/**
|
||||
* Handles click on an active trace to highlight it.
|
||||
* @param {number} clickedActiveTraceIndex - The clicked trace index.
|
||||
*/
|
||||
function onActiveTraceClick(clickedActiveTraceIndex) {
|
||||
mapPathStore.clearAllHighlight();
|
||||
activeTrace.value = clickedActiveTraceIndex;
|
||||
mapPathStore.highlightClickedPath(clickedActiveTraceIndex, clickedPathListIndex.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles click on a path option to highlight it.
|
||||
* @param {number} clickedPath - The clicked path index.
|
||||
*/
|
||||
function onPathOptionClick(clickedPath) {
|
||||
clickedPathListIndex.value = clickedPath;
|
||||
mapPathStore.highlightClickedPath(activeTrace.value, clickedPath);
|
||||
}
|
||||
|
||||
/** Resets the trace highlight to default. */
|
||||
function onResetTraceBtnClick() {
|
||||
if(isBPMNOn.value) {
|
||||
return;
|
||||
@@ -326,8 +346,8 @@ function moment(time){
|
||||
|
||||
/**
|
||||
* Number to percentage
|
||||
* @param {number} val 原始數字
|
||||
* @returns {string} 轉換完成的百分比字串
|
||||
* @param {number} val - The raw ratio value.
|
||||
* @returns {string} The formatted percentage string.
|
||||
*/
|
||||
function getPercentLabel(val){
|
||||
if((val * 100).toFixed(1) >= 100) return `100%`;
|
||||
|
||||
@@ -60,6 +60,16 @@
|
||||
</Sidebar>
|
||||
</template>
|
||||
<script setup>
|
||||
// The Lucia project.
|
||||
// Copyright 2023-2026 DSP, inc. All rights reserved.
|
||||
// Authors:
|
||||
// chiayin.kuo@dsp.im (chiayin), 2023/1/31
|
||||
/**
|
||||
* @module components/Discover/Map/SidebarTraces
|
||||
* Traces sidebar showing path insights with
|
||||
* clickable trace lists for highlighting on the map.
|
||||
*/
|
||||
|
||||
import { ref, computed, watch } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useLoadingStore } from '@/stores/loading';
|
||||
@@ -150,8 +160,8 @@ watch(infiniteFirstCases, (newValue) => {
|
||||
|
||||
/**
|
||||
* Number to percentage
|
||||
* @param {number} val 原始數字
|
||||
* @returns {string} 轉換完成的百分比字串
|
||||
* @param {number} val - The raw ratio value.
|
||||
* @returns {string} The formatted percentage string.
|
||||
*/
|
||||
function getPercentLabel(val){
|
||||
if((val * 100).toFixed(1) >= 100) return `100%`;
|
||||
@@ -160,8 +170,8 @@ function getPercentLabel(val){
|
||||
|
||||
/**
|
||||
* set progress bar width
|
||||
* @param {number} value 百分比數字
|
||||
* @returns {string} 樣式的寬度設定
|
||||
* @param {number} value - The percentage value.
|
||||
* @returns {string} The CSS width style string.
|
||||
*/
|
||||
function progressWidth(value){
|
||||
return `width:${value}%;`
|
||||
@@ -170,7 +180,7 @@ function progressWidth(value){
|
||||
/**
|
||||
* switch case data
|
||||
* @param {number} id case id
|
||||
* @param {number} count 總 case 數量
|
||||
* @param {number} count - The total number of cases.
|
||||
*/
|
||||
async function switchCaseData(id, count) {
|
||||
// 點同一筆 id 不要有動作
|
||||
@@ -184,7 +194,7 @@ async function switchCaseData(id, count) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 將 trace element nodes 資料彙整
|
||||
* Assembles the trace element nodes data for Cytoscape rendering.
|
||||
*/
|
||||
function setNodesData(){
|
||||
// 避免每次渲染都重複累加
|
||||
@@ -206,7 +216,7 @@ function setNodesData(){
|
||||
}
|
||||
|
||||
/**
|
||||
* 將 trace edge line 資料彙整
|
||||
* Assembles the trace edge line data for Cytoscape rendering.
|
||||
*/
|
||||
function setEdgesData(){
|
||||
processMap.value.edges = [];
|
||||
@@ -250,8 +260,8 @@ async function show() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 無限滾動: 監聽 scroll 有沒有滾到底部
|
||||
* @param {element} event 滾動傳入的事件
|
||||
* Infinite scroll: listens for scroll reaching the bottom.
|
||||
* @param {Event} event - The scroll event.
|
||||
*/
|
||||
function handleScroll(event) {
|
||||
if(infinitMaxItems.value || props.cases.length < 20 || infiniteFinish.value === false) return;
|
||||
@@ -263,7 +273,7 @@ function handleScroll(event) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 無限滾動: 滾到底後,要載入數據
|
||||
* Infinite scroll: loads more data when the bottom is reached.
|
||||
*/
|
||||
async function fetchData() {
|
||||
try {
|
||||
|
||||
@@ -70,6 +70,16 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// The Lucia project.
|
||||
// Copyright 2023-2026 DSP, inc. All rights reserved.
|
||||
// Authors:
|
||||
// chiayin.kuo@dsp.im (chiayin), 2023/1/31
|
||||
/**
|
||||
* @module components/Discover/Map/SidebarView Visualization
|
||||
* settings sidebar for map view type (process/BPMN), curve
|
||||
* style, direction, and data layer selection.
|
||||
*/
|
||||
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useMapPathStore } from '@/stores/mapPathStore';
|
||||
@@ -117,8 +127,8 @@ const selectedDuration = ref('');
|
||||
const rank = ref('LR'); // 直向 TB | 橫向 LR
|
||||
|
||||
/**
|
||||
* switch map type
|
||||
* @param {string} type 'processMap' | 'bpmn',可傳入以上任一。
|
||||
* Switches the map type and emits the change event.
|
||||
* @param {string} type - 'processMap' or 'bpmn'.
|
||||
*/
|
||||
function switchMapType(type) {
|
||||
mapType.value = type;
|
||||
@@ -126,8 +136,8 @@ function switchMapType(type) {
|
||||
}
|
||||
|
||||
/**
|
||||
* switch curve style
|
||||
* @param {string} style 直角 'unbundled-bezier' | 'taxi',可傳入以上任一。
|
||||
* Switches the curve style and emits the change event.
|
||||
* @param {string} style - 'unbundled-bezier' (curved) or 'taxi' (elbow).
|
||||
*/
|
||||
function switchCurveStyles(style) {
|
||||
curveStyle.value = style;
|
||||
@@ -135,8 +145,8 @@ function switchCurveStyles(style) {
|
||||
}
|
||||
|
||||
/**
|
||||
* switch rank
|
||||
* @param {string} rank 直向 'TB' | 橫向 'LR',可傳入以上任一。
|
||||
* Switches the graph layout direction and emits the change event.
|
||||
* @param {string} rankValue - 'TB' (vertical) or 'LR' (horizontal).
|
||||
*/
|
||||
function switchRank(rankValue) {
|
||||
rank.value = rankValue;
|
||||
@@ -144,9 +154,9 @@ function switchRank(rankValue) {
|
||||
}
|
||||
|
||||
/**
|
||||
* switch Data Layoer Type or Option.
|
||||
* @param {string} e 切換時傳入的選項
|
||||
* @param {string} type 'freq' | 'duration',可傳入以上任一。
|
||||
* Switches the data layer type (frequency or duration) and option.
|
||||
* @param {Event} e - The change event from the radio or select.
|
||||
* @param {string} type - 'freq' or 'duration'.
|
||||
*/
|
||||
function switchDataLayerType(e, type) {
|
||||
let value = '';
|
||||
@@ -169,11 +179,13 @@ function switchDataLayerType(e, type) {
|
||||
emit('switch-data-layer-type', dataLayerType.value, dataLayerOption.value);
|
||||
}
|
||||
|
||||
/** Switches to Process Map view. */
|
||||
function onProcessMapClick() {
|
||||
mapPathStore.setIsBPMNOn(false);
|
||||
switchMapType('processMap');
|
||||
}
|
||||
|
||||
/** Switches to BPMN Model view. */
|
||||
function onBPMNClick() {
|
||||
mapPathStore.setIsBPMNOn(true);
|
||||
switchMapType('bpmn');
|
||||
|
||||
@@ -79,6 +79,16 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// The Lucia project.
|
||||
// Copyright 2024-2026 DSP, inc. All rights reserved.
|
||||
// Authors:
|
||||
// chiayin.kuo@dsp.im (chiayin), 2023/1/31
|
||||
/**
|
||||
* @module components/Discover/StatusBar Collapsible status bar
|
||||
* showing dataset statistics (cases, traces, activities,
|
||||
* timeframe, case duration) for the Discover page.
|
||||
*/
|
||||
|
||||
import { ref, onMounted, } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { storeToRefs } from 'pinia';
|
||||
@@ -95,18 +105,16 @@ const isPanel = ref(false);
|
||||
const statData = ref(null);
|
||||
|
||||
/**
|
||||
* Number to percentage
|
||||
* @param {number} val 原始數字
|
||||
* @returns {string} 轉換完成的百分比字串
|
||||
* Converts a ratio (0–1) to a percentage number (0–100), capped at 100.
|
||||
* @param {number} val - The ratio value to convert.
|
||||
* @returns {number} The percentage value.
|
||||
*/
|
||||
function getPercentLabel(val){
|
||||
if((val * 100).toFixed(1) >= 100) return 100;
|
||||
else return parseFloat((val * 100).toFixed(1));
|
||||
}
|
||||
|
||||
/**
|
||||
* setting stats data
|
||||
*/
|
||||
/** Transforms raw stats into display-ready format with localized numbers and time labels. */
|
||||
function getStatData() {
|
||||
statData.value = {
|
||||
cases: {
|
||||
|
||||
Reference in New Issue
Block a user