import Swal from 'sweetalert2'; import AllMapDataStore from '@/stores/allMapData.js'; import ConformanceStore from '@/stores/conformance.js'; import FilesStore from '@/stores/files.js'; import PageAdminStore from '@/stores/pageAdmin.js'; import { useModalStore } from '@/stores/modal.js'; const customClass = { container: '!z-[99999]', popup: '!w-[564px]', title: '!text-xl !font-semibold !mb-2', htmlContainer: '!text-sm !font-normal !h-full !mb-4 !leading-5', inputLabel: '!text-sm !font-normal', input: '!h-8 !text-sm !font-normal !shadow-inner !shadow-black !border-neutral-200', validationMessage: '!bg-neutral-10 !text-danger', confirmButton: '!inline-block !rounded-full !text-sm !font-medium !text-center !align-middle !transition-colors !duration-300 !px-5 !py-2 !w-[100px] !h-[40px]', cancelButton: '!inline-block !rounded-full !text-sm !font-medium !text-center !align-middle !transition-colors !duration-300 !px-5 !py-2 !w-[100px] !h-[40px] ', }; /** * Map Saved * @param { function } addFilterId 後端 API */ export async function saveFilter(addFilterId, next = null) { let fileName = ''; const pageAdminStore = PageAdminStore(); const { value, isConfirmed } = await Swal.fire({ title: 'SAVE NEW FILTER', input: 'text', inputPlaceholder: 'Enter Filter Name.', inputValue: fileName, inputAttributes: { 'maxlength': 200, }, inputValidator: (value) => { if (!value) return 'You need to write something!'; fileName = value; }, icon: 'info', iconHtml: 'cloud_upload', iconColor: '#0099FF', reverseButtons:true, confirmButtonColor: '#0099FF', showCancelButton: true, cancelButtonColor: '#94a3b8', customClass: customClass, }); // 透過回傳值判斷要不要轉址 if(isConfirmed) { // 存檔成功 await addFilterId(fileName); // 顯示儲存完成 if (value) { // Example of value: yes savedSuccessfully(value); } // 清空欄位 fileName = ''; return true; } else { // 點擊取消或空白處,為存檔失敗。 pageAdminStore.keepPreviousPage(); // Not every time we have nontrivial next value if (next !== null) { next(false); } return false; } } /** * Saved Success * @param { string } value File's name */ export async function savedSuccessfully(value) { value = value || ''; await Swal.fire({ title: 'SAVE COMPLETE', html: `${value} has been saved in Lucia.`, timer: 3000, // 停留 3 秒後自動關閉 showConfirmButton: false, icon: 'success', iconColor: '#0099FF', customClass: customClass }) }; /** * leave Map page * @param { function } next 執行完函式後的步驟 * @param { function } addFilterId 後端 API * @param { string } toPath route path * @param { function } logOut 登出函式 */ export async function leaveFilter(next, addFilterId, toPath, logOut) { const allMapDataStore = AllMapDataStore(); const pageAdminStore = PageAdminStore(); const result = await Swal.fire({ title: 'SAVE YOUR FILTER?', html: 'If you want to continue using this filter in any other page, please select [Yes].', icon: 'warning', iconColor: '#FF3366', reverseButtons:true, confirmButtonText: 'Yes', confirmButtonColor: '#FF3366', showCancelButton: true, cancelButtonText: 'No', cancelButtonColor: '#94a3b8', customClass: customClass, }); if(result.isConfirmed) { if(allMapDataStore.createFilterId) { await allMapDataStore.updataFilter(); if(allMapDataStore.isUpdataFilter) { await savedSuccessfully(allMapDataStore.filterName); } } else { // Dangerous, here shows a modal await saveFilter(addFilterId, next); } logOut ? logOut() : next(toPath); } else if(result.dismiss === 'cancel') { // console.log('popup cancel case', ); // Handle page admin issue // console.log("PageAdminStore.activePage", PageAdminStore.activePage); pageAdminStore.keepPreviousPage(); allMapDataStore.tempFilterId = null; logOut ? logOut() : next(toPath); } else if(result.dismiss === 'backdrop') { // console.log('popup backdrop case', ); // Handle page admin issue // console.log("PageAdminStore.activePage", PageAdminStore.activePage); pageAdminStore.keepPreviousPage(); if(!logOut){ next(false); }; } }; /** * Conformance Saved * @param { function } addConformanceCreateCheckId 後端 API */ export async function saveConformance(addConformanceCreateCheckId) { let fileName = ''; const { value, isConfirmed } = await Swal.fire({ title: 'SAVE NEW RULE', input: 'text', inputPlaceholder: 'Enter Rule Name.', inputValue: fileName, inputAttributes: { 'maxlength': 200, }, inputValidator: (value) => { if (!value) return 'You need to write something!'; fileName = value; }, icon: 'info', iconHtml: 'cloud_upload', iconColor: '#0099FF', reverseButtons:true, confirmButtonColor: '#0099FF', showCancelButton: true, cancelButtonColor: '#94a3b8', customClass: customClass, }); // 透過回傳值判斷要不要轉址 if(isConfirmed) { // 存檔成功 await addConformanceCreateCheckId(fileName); // 顯示儲存完成 if (value) savedSuccessfully(value); // 清空欄位 fileName = ''; return true; } else { // 點擊取消或空白處,為存檔失敗。 return false; } } /** * leave Conformance page * @param { function } next 執行完函式後的步驟 * @param { function } addConformanceCreateCheckId 後端 API * @param { string } toPath route path * @param { function } logOut 登出函式 */ export async function leaveConformance(next, addConformanceCreateCheckId, toPath, logOut) { const conformanceStore = ConformanceStore(); const result = await showConfirmationDialog(); if (result.isConfirmed) { await handleConfirmed(conformanceStore, addConformanceCreateCheckId); } else { await handleDismiss(result.dismiss, conformanceStore, next, toPath, logOut); } } async function showConfirmationDialog() { return Swal.fire({ title: 'SAVE YOUR RULE?', icon: 'warning', iconColor: '#FF3366', reverseButtons: true, confirmButtonText: 'Yes', confirmButtonColor: '#FF3366', showCancelButton: true, cancelButtonText: 'No', cancelButtonColor: '#94a3b8', customClass: customClass }); } async function handleConfirmed(conformanceStore, addConformanceCreateCheckId) { if (conformanceStore.conformanceFilterCreateCheckId || conformanceStore.conformanceLogCreateCheckId) { await conformanceStore.updataConformance(); if (conformanceStore.isUpdataConformance) { await savedSuccessfully(conformanceStore.conformanceFileName); } } else { await saveConformance(addConformanceCreateCheckId); } } async function handleDismiss(dismissType, conformanceStore, next, toPath, logOut) { switch (dismissType) { case 'cancel': resetTempCheckId(conformanceStore); logOut ? logOut() : next(toPath); break; case 'backdrop': if (!logOut) { next(false); } break; default: break; } } function resetTempCheckId(conformanceStore) { conformanceStore.conformanceFilterTempCheckId = null; conformanceStore.conformanceLogTempCheckId = null; } /** * Upload failde First * @param { string } failureType 後端檔案錯誤類型 * @param { string } failureMsg 後端檔案錯誤訊息 */ export async function uploadFailedFirst(failureType, failureMsg, failureLoc) { // msg: 'not in UTF-8' | 'insufficient columns' | 'the csv file is empty' | 'the filename does not ends with .csv' | 'not a CSV file' // type: 'encoding' | 'insufficient_columns' | 'empty' | 'name_suffix' | mime_type let value = ''; switch (failureType) { case 'size': value = 'File size exceeds 90MB.'; break; case 'encoding': value = `Please use UFT-8 for character encoding: (Row #${failureLoc})`; break; case 'insufficient_columns': value = 'Need at least five columns of data.'; break; case 'empty': value = 'Need at least one record of data.'; break; case 'name_suffix': case 'mime_type': value = 'File is not in csv format.'; break; default: value = failureMsg; break; } await Swal.fire({ title: 'IMPORT FAILED', html: value, timer: 3000, // 停留 3 秒後自動關閉 showConfirmButton: false, icon: 'error', iconColor: '#FF3366', customClass: customClass }) }; /** * Upload failde Second * @param { array } detail 後端回傳的失敗訊息 */ export async function uploadFailedSecond(detail) { let srt = ''; let manySrt = ''; detail.forEach(i => { let content = ''; let key = ''; switch (i.type) { case 'too_many': manySrt = 'There are more errors.'; break; case 'unrecognized': content = `
  • Data unregnizable in Status Column: (Row #${i.loc[1]}, "${i.input}")
  • `; break; case 'malformed': content = `
  • Data malformed in Timestamp Column: (Row #${i.loc[1]}, "${i.input}")
  • `; break; case 'missing': switch (i.loc[2]) { case 'case id': key = 'Case ID'; break; case 'timestamp': key = 'Timestamp'; break; case 'name': key = 'Activity'; break; case 'instance': key = 'Activity Instance ID'; break; case 'status': key = 'Status'; break; default: key = i.loc[2]; break; } content = `
  • Data missing in ${key} Column: (Row #${i.loc[1]})
  • `; break; } srt += content; }); await Swal.fire({ title: 'IMPORT FAILED', html: `

    Error(s) detected:

    ${manySrt} Please check.

    `, timer: 3000, // 停留 3 秒後自動關閉 showConfirmButton: false, icon: 'error', iconColor: '#FF3366', customClass: customClass }); srt = ''; }; /** * Upload Success * @param { string } value File's name */ export async function uploadSuccess() { await Swal.fire({ title: 'IMPORT COMPLETED', timer: 3000, // 停留 3 秒後自動關閉 showConfirmButton: false, icon: 'success', iconColor: '#0099FF', customClass: customClass }) }; /** * Confirm whether to upload the file * @param { object } fetchData 後端 API POST data */ export async function uploadConfirm(fetchData) { const filesStore = FilesStore(); const result = await Swal.fire({ title: 'ARE YOU SURE?', html: 'After importing, you won’t be able to modify labels.', icon: 'warning', iconColor: '#FF3366', reverseButtons:true, confirmButtonText: 'Yes', confirmButtonColor: '#FF3366', showCancelButton: true, cancelButtonText: 'No', cancelButtonColor: '#94a3b8', customClass: customClass, }); if(result.isConfirmed) { filesStore.uploadLog(fetchData); } }; /** * Upload loader */ export async function uploadloader() { await Swal.fire({ html: '', showConfirmButton: false, allowOutsideClick: false, customClass: customClass, }) }; /** * Rename Modal * @param { function } rename 後端 API * @param { string } type File 檔案類型 * @param { number } id File ID * @param { string } baseName 改名前的檔名 */ export async function renameModal(rename, type, id, baseName) { let fileName = baseName; const { value, isConfirmed } = await Swal.fire({ title: 'RENAME', input: 'text', inputPlaceholder: 'Enter File Name.', inputValue: fileName, inputAttributes: { 'maxlength': 200, }, icon: 'info', iconHtml: 'edit_square', iconColor: '#0099FF', reverseButtons: true, confirmButtonColor: '#0099FF', showCancelButton: '#94a3b8', customClass: customClass, didOpen: () => { const confirmButton = Swal.getConfirmButton(); const inputField = Swal.getInput(); inputField.addEventListener('input', function() { if (!inputField.value.trim()) { confirmButton.classList.add('disable-hover'); confirmButton.disabled = true; } else { confirmButton.classList.remove('disable-hover'); confirmButton.disabled = false; } }); } }); // 改名成功 if(isConfirmed) await rename(type, id, value); // 清空欄位 fileName = ''; } /** * Delete File * @param { string } files 有關連的檔案 * @param { string } type File 檔案類型 * @param { number } id File ID * @param { string } name 原本的檔案 */ export async function deleteFileModal(files, type, id, name) { const filesStore = FilesStore(); let htmlText = files.length === 0 ? `Do you really want to delete ${name}?` : `

    Do you really want to delete ${name}?

    The following dependent file(s) will also be deleted:

    `; const deleteCustomClass = { ...customClass }; deleteCustomClass.confirmButton = '!inline-block !rounded-full !text-sm !font-medium !text-center !align-middle !transition-colors !duration-300 !px-5 !py-2 !w-[100px] !h-[40px] !text-danger !bg-neutral-10 !border !border-danger'; const result = await Swal.fire({ title: 'CONFIRM DELETION', html: htmlText, icon: 'warning', iconColor: '#FF3366', reverseButtons:true, confirmButtonColor: '#ffffff', showCancelButton: true, cancelButtonColor: '#FF3366', customClass: deleteCustomClass, didOpen: () => { const confirmButton = Swal.getConfirmButton(); confirmButton.style.border = '1px solid #FF3366'; } }); if(result.isConfirmed) { filesStore.deleteFile(type, id); } }; /** * Delete Success */ export async function deleteSuccess() { await Swal.fire({ title: 'FILE(S) DELETED', timer: 3000, // 停留 3 秒後自動關閉 showConfirmButton: false, icon: 'success', iconColor: '#0099FF', customClass: customClass }) }; /** * Really deleted information * @param {string} files 被刪除的檔案 html * @param {array} reallyDeldetData 被刪除的檔案 data,未取得 recordId 而傳入 */ export async function reallyDeldetInformation(files, reallyDeldetData) { const filesStore = FilesStore(); const deleteCustomClass = { ...customClass }; const htmlText = `

    The following file(s) have been deleted by other user(s):

    `; deleteCustomClass.confirmButton = '!inline-block !rounded-full !text-sm !font-medium !text-center !align-middle !transition-colors !duration-300 !px-5 !py-2 !w-[100px] !h-[40px] !text-primary !bg-neutral-10 !border !border-primary'; deleteCustomClass.cancelButton = null; await Swal.fire({ title: 'FILE(S) DELETED BY OTHER USER(S)', html: htmlText, icon: 'info', iconColor: '#0099FF', customClass: deleteCustomClass, confirmButtonColor: '#ffffff', didOpen: () => { const confirmButton = Swal.getConfirmButton(); confirmButton.style.border = '1px solid #0099FF'; } }); await Promise.all(reallyDeldetData.map(file => filesStore.deletionRecord(file.id))); await filesStore.fetchAllFiles(); } /** * When user is leaving the acct mgmt page but hasn't finished editing, * we jump out this alert modal to remind her. */ export async function leaveAccountManagementToRemind(){ const modalStore = useModalStore(); const result = await Swal.fire({ title: 'SAVE YOUR EDIT?', icon: 'info', showCancelButton: true, didOpen: () => { const confirmButton = Swal.getConfirmButton(); confirmButton.style.border = '1px solid #0099FF'; } }); if(result.isConfirmed) { return; } else { modalStore.openModal(); } };