acctMgmt.ts by ChatGPT
This commit is contained in:
278
src/stores/acctMgmt.ts
Normal file
278
src/stores/acctMgmt.ts
Normal file
@@ -0,0 +1,278 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import apiError from '@/module/apiError';
|
||||
import { JUST_CREATE_ACCOUNT_HOT_DURATION_MINS } from '@/constants/constants';
|
||||
|
||||
interface User {
|
||||
username: string;
|
||||
detail: Record<string, any>;
|
||||
name?: string;
|
||||
is_admin?: boolean;
|
||||
is_sso?: boolean;
|
||||
isDeleteHovered?: boolean;
|
||||
isRowHovered?: boolean;
|
||||
isEditHovered?: boolean;
|
||||
isDetailHovered?: boolean;
|
||||
}
|
||||
|
||||
interface EditDetail {
|
||||
newUsername?: string;
|
||||
username?: string;
|
||||
password: string;
|
||||
name: string;
|
||||
is_active: boolean;
|
||||
}
|
||||
|
||||
export default defineStore('acctMgmtStore', {
|
||||
state: () => ({
|
||||
allUserAccoutList: [] as User[],
|
||||
isAcctMenuOpen: false,
|
||||
currentViewingUser: {
|
||||
username: '',
|
||||
detail: {},
|
||||
} as User,
|
||||
response: {
|
||||
deleteAccount: null,
|
||||
},
|
||||
isOneAccountJustCreate: false, //如果有一個帳號剛剛建立,則會在列表上的第一列顯示這個帳號,並且右置一個徽章
|
||||
justCreateUsername: '', // unique username
|
||||
shouldUpdateList: false, // 控制是否該刷新列表
|
||||
}),
|
||||
getters: {},
|
||||
actions: {
|
||||
/**
|
||||
* Set related boolean to true
|
||||
*/
|
||||
openAcctMenu(){
|
||||
this.isAcctMenuOpen = true;
|
||||
},
|
||||
/**
|
||||
* Set related boolean to false
|
||||
*/
|
||||
closeAcctMenu(){
|
||||
this.isAcctMenuOpen = false;
|
||||
},
|
||||
toggleIsAcctMenuOpen() {
|
||||
this.isAcctMenuOpen = !this.isAcctMenuOpen;
|
||||
},
|
||||
/**
|
||||
* For convenience, set current viewing data according to unique user ID.
|
||||
* @param {string} username
|
||||
*/
|
||||
setCurrentViewingUser(username: string) {
|
||||
const userFind = this.allUserAccoutList.find(user => user.username === username);
|
||||
this.currentViewingUser = userFind ? userFind : { username: '', detail: {} };
|
||||
},
|
||||
/**
|
||||
* We have this method because we want to handle create new modal case.
|
||||
*/
|
||||
clearCurrentViewingUser() {
|
||||
this.currentViewingUser = {
|
||||
username: '',
|
||||
detail: {},
|
||||
name: '',
|
||||
is_admin: false,
|
||||
is_sso: false,
|
||||
};
|
||||
},
|
||||
/**
|
||||
* Get all user accounts
|
||||
*/
|
||||
async getAllUserAccounts() {
|
||||
const apiGetUserList = `/api/users`;
|
||||
try {
|
||||
const response = await this.$axios.get(apiGetUserList);
|
||||
const customizedResponseData = await this.customizeAllUserList(response.data);
|
||||
this.allUserAccoutList = customizedResponseData;
|
||||
} catch(error) {
|
||||
apiError(error, 'Failed to get all users.');
|
||||
}
|
||||
},
|
||||
/**
|
||||
* For example, add isHovered field
|
||||
*/
|
||||
async customizeAllUserList(rawResponseData: User[]): Promise<User[]> {
|
||||
return rawResponseData.map(user => ({
|
||||
...user, // 保留後端傳來的欄位
|
||||
isDeleteHovered: false, // 針對前端顯示而額外增加的欄位
|
||||
isRowHovered: false,
|
||||
isEditHovered: false,
|
||||
}));
|
||||
},
|
||||
/**
|
||||
* Create new user in database.
|
||||
* @param {object} userToCreate
|
||||
* userToCreate {
|
||||
* "username": "string",
|
||||
* "password": "string",
|
||||
* "name": "string",
|
||||
* "is_admin": boolean,
|
||||
* "is_active": boolean,
|
||||
* }
|
||||
*/
|
||||
async createNewAccount(userToCreate: User) {
|
||||
const apiCreateAccount = `/api/users`;
|
||||
|
||||
try {
|
||||
const response = await this.$axios.post(apiCreateAccount, userToCreate);
|
||||
if (response.status === 200) {
|
||||
this.isOneAccountJustCreate = true;
|
||||
this.justCreateUsername = userToCreate.username;
|
||||
setTimeout(this.resetJustCreateFlag, JUST_CREATE_ACCOUNT_HOT_DURATION_MINS * 1000 * 60);
|
||||
}
|
||||
} catch(error) {
|
||||
apiError(error, 'Failed to add a new account.');
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Delete an account from database.
|
||||
* @param {string} userToDelete this value is unique in database.
|
||||
* @returns the result of whether the deletion is success or not.
|
||||
*/
|
||||
async deleteAccount(userToDelete: string): Promise<boolean> {
|
||||
const apiDelete = `/api/users/${userToDelete}`;
|
||||
|
||||
try {
|
||||
const response = await this.$axios.delete(apiDelete);
|
||||
return response.status === 200;
|
||||
} catch(error) {
|
||||
apiError(error, 'Failed to delete the account.');
|
||||
return false;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Edit an account.
|
||||
* @param {string} userToEdit this value is unique in database.
|
||||
* @param {object} editDetail
|
||||
*/
|
||||
async editAccount(userToEdit: string, editDetail: EditDetail): Promise<boolean> {
|
||||
const apiEdit = `/api/users/${userToEdit}`;
|
||||
|
||||
try {
|
||||
const response = await this.$axios.put(apiEdit, {
|
||||
username: editDetail.newUsername ? editDetail.newUsername : editDetail.username,
|
||||
password: editDetail.password,
|
||||
name: editDetail.name,
|
||||
is_active: editDetail.is_active,
|
||||
});
|
||||
return response.status === 200;
|
||||
} catch(error) {
|
||||
apiError(error, 'Failed to edit the account.');
|
||||
return false;
|
||||
}
|
||||
},
|
||||
/** Add a role to the user in database.
|
||||
* @param {string} usernameToEdit
|
||||
* @param {string} roleCode
|
||||
*/
|
||||
async addRoleToUser(usernameToEdit: string, roleCode: string): Promise<boolean> {
|
||||
const apiAddRole = `/api/users/${usernameToEdit}/roles/${roleCode}`;
|
||||
|
||||
try {
|
||||
const response = await this.$axios.put(apiAddRole);
|
||||
return response.status === 200;
|
||||
} catch(error) {
|
||||
apiError(error, 'Failed to add role to the account.');
|
||||
return false;
|
||||
}
|
||||
},
|
||||
/** Delete a role from the user in database.
|
||||
* @param {string} usernameToEdit
|
||||
* @param {string} roleCode
|
||||
*/
|
||||
async deleteRoleToUser(usernameToEdit: string, roleCode: string): Promise<boolean> {
|
||||
const apiDeleteRole = `/api/users/${usernameToEdit}/roles/${roleCode}`;
|
||||
|
||||
try {
|
||||
const response = await this.$axios.delete(apiDeleteRole);
|
||||
return response.status === 200;
|
||||
} catch(error) {
|
||||
apiError(error, 'Failed to delete a role frome the account.');
|
||||
return false;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Get user detail by unique username.
|
||||
* @param {string} uniqueUsername
|
||||
*/
|
||||
async getUserDetail(uniqueUsername: string): Promise<boolean> {
|
||||
const apiUserDetail = `/api/users/${uniqueUsername}`;
|
||||
|
||||
try {
|
||||
const response = await this.$axios.get(apiUserDetail);
|
||||
this.currentViewingUser = {
|
||||
...this.currentViewingUser,
|
||||
detail: response.data,
|
||||
};
|
||||
return response.status === 200;
|
||||
} catch(error) {
|
||||
//不需要跳出錯誤,因為如果是錯誤反而是好事,表示帳號是獨一的
|
||||
return false;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* According to mouseover or mouseleave status, change the bool value.
|
||||
* @param {string} username
|
||||
* @param {boolean} isDeleteHovered
|
||||
*/
|
||||
changeIsDeleteHoveredByUser(username: string, isDeleteHovered: boolean) {
|
||||
const userToChange = this.allUserAccoutList.find(user => user.username === username);
|
||||
if (userToChange) {
|
||||
userToChange.isDeleteHovered = isDeleteHovered;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* According to mouseover or mouseleave status, change the bool value.
|
||||
* @param {string} username
|
||||
* @param {boolean} isRowHovered
|
||||
*/
|
||||
changeIsRowHoveredByUser(username: string, isRowHovered: boolean) {
|
||||
const userToChange = this.allUserAccoutList.find(user => user.username === username);
|
||||
if (userToChange) {
|
||||
userToChange.isRowHovered = isRowHovered;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* According to mouseover or mouseleave status, change the bool value.
|
||||
* @param {string} username
|
||||
* @param {boolean} isEditHovered
|
||||
*/
|
||||
changeIsEditHoveredByUser(username: string, isEditHovered: boolean) {
|
||||
const userToChange = this.allUserAccoutList.find(user => user.username === username);
|
||||
if (userToChange) {
|
||||
userToChange.isEditHovered = isEditHovered;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* According to mouseover or mouseleave status, change the bool value.
|
||||
* @param {string} username
|
||||
* @param {boolean} isEditHovered
|
||||
*/
|
||||
changeIsDetailHoveredByUser(username: string, isDetailHovered: boolean) {
|
||||
const userToChange = this.allUserAccoutList.find(user => user.username === username);
|
||||
if (userToChange) {
|
||||
userToChange.isDetailHovered = isDetailHovered;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Reset isOneAccountJustCreate to false, causing the badge to disappear.
|
||||
*/
|
||||
resetJustCreateFlag(){
|
||||
this.isOneAccountJustCreate = false;
|
||||
},
|
||||
/** Set the value of shouldUpdateList variable.
|
||||
* @param {boolean} shouldUpdateBoolean
|
||||
*/
|
||||
setShouldUpdateList(shouldUpdateBoolean: boolean) {
|
||||
this.shouldUpdateList = shouldUpdateBoolean;
|
||||
},
|
||||
/** Only update one single account in the pinia state.
|
||||
* @param {object} userDataToReplace
|
||||
*/
|
||||
updateSingleAccountPiniaState(userDataToReplace: User) {
|
||||
const userIndex = this.allUserAccoutList.findIndex(user => user.username === userDataToReplace.username);
|
||||
if (userIndex !== -1) {
|
||||
this.allUserAccoutList[userIndex] = { ...this.allUserAccoutList[userIndex], ...userDataToReplace };
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user