Files
lucia-frontend/src/stores/files.js
Cindy Chang 47da80b424 sonar low
2024-07-26 11:16:05 +08:00

346 lines
9.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { defineStore } from "pinia";
import axios from "axios";
import moment from 'moment';
import apiError from '@/module/apiError.js';
import Swal from 'sweetalert2';
import { uploadFailedFirst, uploadFailedSecond, uploadloader, uploadSuccess, deleteSuccess } from '@/module/alertModal.js';
import pinia from '@/stores/main.ts';
import loadingStore from '@/stores/loading.js';
const loading = loadingStore(pinia);
export default defineStore('filesStore', {
state: () => ({
allEventFiles: [
{
parentLog: '',
fileType: '',
ownerName: '',
}
],
switchFilesTagData: {
ALL: ['Log', 'Filter', 'Rule', 'Design'],
DISCOVER: ['Log', 'Filter', 'Rule'],
COMPARE: ['Log','Filter'],
DESIGN: ['Log', 'Design'],
},
filesTag: 'ALL',
httpStatus: 200,
uploadId: null,
allUploadDetail: null,
uploadLogId: null,
uploadFileName: null,
allDependentsData: null,
}),
getters: {
/**
* Get allFiles and switch files tag
*/
allFiles: state => {
let result = state.allEventFiles;
let data = state.switchFilesTagData;
let filesTag = state.filesTag;
result = result.filter(file => data[filesTag].includes(file.fileType));
return result;
},
/**
* Get upload preview
*/
uploadDetail: state => {
return state.allUploadDetail;
},
/**
* Get dependents of files data
*/
dependentsData: state => {
return state.allDependentsData;
}
},
actions: {
/**
* Fetch All Files api
*/
async fetchAllFiles() {
const api = '/api/files';
let icon = '';
let fileType = '';
let parentLog = '';
try {
const response = await axios.get(api);
this.allEventFiles = response.data;
this.allEventFiles.map(o => {
switch (o.type) {
case 'log':
icon = 'work_history';
fileType = 'Log';
parentLog = o.name;
break;
case 'filter':
icon = 'tornado';
fileType = 'Filter';
parentLog = o.parent.name;
break;
case 'log-check':
case 'filter-check':
icon = 'local_police';
fileType = 'Rule';
parentLog = o.parent.name;
break;
case 'design':
icon = 'shape_line';
break;
}
o.icon = icon;
o.parentLog = parentLog;
o.fileType = fileType;
o.ownerName = o.owner.name;
o.updated_base = o.updated_at;
o.accessed_base = o.accessed_at;
o.updated_at = moment(o.updated_at).utcOffset('+08:00').format('YYYY-MM-DD HH:mm');
o.accessed_at = o.accessed_at ? moment(o.accessed_at).utcOffset('+08:00').format('YYYY-MM-DD HH:mm') : null;
});
} catch(error) {
apiError(error, 'Failed to load the files.');
};
},
/**
* Uploads a CSV log file. 第一階段上傳
* @param {Object} fromData 傳給後端的 Data
*/
async upload(fromData) {
const api = '/api/logs/csv-uploads';
const config = {
data: true,
headers: {
'Content-Type': 'multipart/form-data',
},
};
uploadloader(); // 進度條
try {
const response = await axios.post(api, fromData, config);
this.uploadId = response.data.id;
this.$router.push({name: 'Upload'});
Swal.close(); // 關閉進度條
} catch(error) {
if(error.response.status === 422) {
// msg: 'not in UTF-8' | 'insufficient columns' | 'the csv file is empty' | 'the filename does not ends with .csv'
// type: 'encoding' | 'insufficient_columns' | 'empty' | 'name_suffix'
let detail = error.response.data.detail;
uploadFailedFirst(detail[0].type, detail[0].msg, detail[0].loc[2]);
} else {
Swal.close(); // 關閉進度條
apiError(error, 'Failed to upload the files.');
}
}
},
/**
* Fetch upload detail
*/
async getUploadDetail() {
const uploadId = this.uploadId;
const api = `/api/logs/csv-uploads/${uploadId}`;
try {
const response = await axios.get(api);
this.allUploadDetail = response.data.preview;
} catch(error) {
apiError(error, 'Failed to get upload detail.');
}
},
/**
* Add a Log from an Uploaded CSV Log File. 第二階段上傳
* @param {Object} data 傳給後端的 Data
*/
async uploadLog(data) {
const uploadId = this.uploadId;
const api = `/api/logs/csv-uploads/${uploadId}`;
uploadloader(); // 進度條
try {
const response = await axios.post(api, data);
this.uploadLogId = await response.data.id;
await Swal.close(); // 關閉進度條
await this.rename(); // 改檔名
await uploadSuccess();
this.$router.push({name: 'Files'});
} catch(error) {
if(error.response.status === 422) {
let detail = [...error.response.data.detail];
uploadFailedSecond(detail);
} else {
Swal.close(); // 關閉進度條
apiError(error, 'Failed to upload the log files.');
}
}
},
/**
* Rename a Log
* @param { string } type log | filter | log-check | filter-check傳入以上任一個。
* @param { number } id 檔案 ID
* @param { string } name file's name
*/
async rename(type, id, fileName) {
// 先判斷有沒有 uploadLogId有就設定 id 和 type再判斷檔案型別。
if(this.uploadId && this.uploadFileName) {
type = 'log';
id = this.uploadLogId;
fileName = this.uploadFileName;
}
let api;
let data = {"name": fileName};
switch (type) {
case 'log':
api = `/api/logs/${id}/name`;
break;
case 'filter':
api = `/api/filters/${id}/name`;
break;
case 'log-check':
api = `/api/log-checks/${id}/name`;
break;
case 'filter-check':
api = `/api/filter-checks/${id}/name`;
break;
}
try {
await axios.put(api, data);
this.uploadFileName = null;
await this.fetchAllFiles();
} catch(error) {
apiError(error, 'Failed to rename.');
}
},
/**
* Get the Dependents of the files
* @param { string } type log | filter | log-check | filter-check
* @param { number } id 檔案 ID
*/
async getDependents(type, id) {
let api;
switch (type) {
case 'log':
api = `/api/logs/${id}/dependents`;
break;
case 'filter':
api = `/api/filters/${id}/dependents`;
break;
case 'log-check':
api = `/api/log-checks/${id}/dependents`;
break;
case 'filter-check':
api = `/api/filter-checks/${id}/dependents`;
break;
}
try {
const response = await axios.get(api);
this.allDependentsData = response.data;
} catch(error) {
apiError(error, 'Failed to get Dependents of the files.');
}
},
/**
* Delete file
* @param { string } type log | filter | log-check | filter-check
* @param { number } id 檔案 ID
*/
async deleteFile(type, id) {
let api;
if(id == null || isNaN(id)) {
return $toast.default('Delete File API Error.', {position: 'bottom'});
};
loading.isLoading = true;
switch (type) {
case 'log':
api = `/api/logs/${id}`;
break;
case 'filter':
api = `/api/filters/${id}`;
break;
case 'log-check':
api = `/api/log-checks/${id}`;
break;
case 'filter-check':
api = `/api/filter-checks/${id}`;
break;
}
try {
await this.fetchAllFiles();
await deleteSuccess();
} catch(error) {
apiError(error, 'Failed to delete.');
} finally {
loading.isLoading = false;
}
},
/**
* Remove a Deletion Record真刪除被 Admin 或被其他帳號刪除的檔案
* @param {number} id 檔案 ID
*/
async deletionRecord(id) {
let api = '';
loading.isLoading = true;
api = `/api/deletion/${id}`;
try {
} catch(error) {
apiError(error, 'Failed to Remove a Deletion Record.')
} finally {
loading.isLoading = false;
}
},
/**
* Download file as CSV
* @param { string } type log | filter | log-check | filter-check
* @param { number } id 檔案 ID
* @param { string } fileName file's name
*/
async downloadFileCSV(type, id, fileName) {
let api;
switch (type) {
case 'log':
api = `/api/logs/${id}/csv`;
break;
case 'filter':
api = `/api/filters/${id}/csv`;
break;
// case 'log-check':
// api = `/api/log-checks/${id}/csv`;
// break;
// case 'filter-check':
// api = `/api/filter-checks/${id}/csv`;
// break;
default:
return;
}
try {
const response = await axios.get(api);
const csvData = response.data;
const blob = new Blob([csvData], { type: 'text/csv' });
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = `${fileName}.csv`;
link.click();
window.URL.revokeObjectURL(url);
} catch(error) {
apiError(error, 'Failed to delete.');
}
},
},
})