fix: acct_mgmt_button

This commit is contained in:
Cindy Chang
2024-07-15 15:39:59 +08:00
parent 4c9633a395
commit cab484ac00
4 changed files with 24 additions and 287 deletions

View File

@@ -1,5 +1,5 @@
<template>
<div class="mx-auto px-4 h-14">
<div class="mx-auto px-4 h-14 z-50">
<div class="flex justify-between items-center h-full">
<figure>
<DspLogo />
@@ -10,7 +10,7 @@
Logout
</button> -->
<img v-show="true" id="acct_mgmt_button" src="@/assets/icon-head-black.svg" width="32" height="32"
class="cursor-pointer" @click="onAcctHeadClick"
class="cursor-pointer z-50" @click="toggleIsAcctMenuOpen"
/>
</div>
</div>
@@ -18,10 +18,10 @@
</template>
<script>
import { storeToRefs, mapActions, } from 'pinia';
import { storeToRefs, } from 'pinia';
import i18next from '@/i18n/i18n';
import loginStore from '@/stores/login.ts';
import acctMenuStore from "@/stores/acctMgmt.ts";
import useAcctMgmtStore from '@/stores/acctMgmt.ts';
import DspLogo from '@/components/icons/DspLogo.vue';
import AllMapDataStore from '@/stores/allMapData.js';
import ConformanceStore from '@/stores/conformance.js';
@@ -39,10 +39,23 @@ export default {
const { logOut } = store;
const allMapDataStore = AllMapDataStore();
const conformanceStore = ConformanceStore();
const acctMgmtStore = useAcctMgmtStore();
const { tempFilterId, temporaryData, postRuleData, ruleData } = storeToRefs(allMapDataStore);
const { conformanceLogTempCheckId, conformanceFilterTempCheckId, conformanceFileName } = storeToRefs(conformanceStore);
return { logOut, temporaryData, tempFilterId, postRuleData, ruleData, conformanceLogTempCheckId, conformanceFilterTempCheckId, allMapDataStore, conformanceStore, conformanceFileName }
const toggleIsAcctMenuOpen = () => {
console.log('head clicked', );
acctMgmtStore.toggleIsAcctMenuOpen();
}
return { logOut, temporaryData, tempFilterId,
postRuleData, ruleData,
conformanceLogTempCheckId,
conformanceFilterTempCheckId,
allMapDataStore, conformanceStore,
conformanceFileName,
toggleIsAcctMenuOpen,
};
},
components: {
DspLogo,
@@ -63,10 +76,6 @@ export default {
this.logOut();
}
},
onAcctHeadClick(){
this.toggleIsAcctMenuOpen();
},
...mapActions(acctMenuStore, ['toggleIsAcctMenuOpen']),
},
mounted() {
this.$route.name === 'Login' || this.$route.name === 'NotFound404' ? this.showMember = false : this.showMember = true;

View File

@@ -1,276 +0,0 @@
import { defineStore } from "pinia";
import apiError from '@/module/apiError.js';
import { JUST_CREATE_ACCOUNT_HOT_DURATION_MINS } from '@/constants/constants.js';
export default defineStore('acctMgmtStore', {
state: () => ({
allUserAccoutList: [],
isAcctMenuOpen: false,
currentViewingUser: {
username: "",
detail: {},
},
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) {
const userFind = this.allUserAccoutList.find(user => user.username === username);
this.currentViewingUser = userFind ? userFind : {};
},
/**
* We have this method because we want to handle create new modal case.
*/
clearCurrentViewingUser() {
this.currentViewingUser = {
username: '',
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){
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) {
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) {
const apiDelete = `/api/users/${userToDelete}`;
try{
const response = await this.$axios.delete(apiDelete);
if(response.status === 200) {
return true;
}
}
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, editDetail) {
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,
});
if(response.status === 200) {
return true;
}
}
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, roleCode) {
const apiAddRole = `/api/users/${usernameToEdit}/roles/${roleCode}`;
try{
const response = await this.$axios.put(apiAddRole);
if(response.status === 200) {
return true;
}
}
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, roleCode) {
const apiDeleteRole = `/api/users/${usernameToEdit}/roles/${roleCode}`;
try{
const response = await this.$axios.delete(apiDeleteRole);
if(response.status === 200) {
return true;
}
}
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) {
const apiUserDetail = `/api/users/${uniqueUsername}`;
try{
const response = await this.$axios.get(apiUserDetail);
this.currentViewingUser = {
...this.currentViewingUser,
detail: response.data,
}
if(response.status === 200) {
return true;
}
}
catch(error) {
//不需要跳出錯誤,因為如果是錯誤反而是好事,表示帳號是獨一的
return false;
};
},
/**
* According to mouseover or mouseleave status, change the bool value.
* @param {string} username
* @param {boolean} isDeleteHovered
*/
changeIsDeleteHoveredByUser(username, isDeleteHovered) {
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, isRowHovered){
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, isEditHovered) {
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, isDetailHovered) {
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) {
this.shouldUpdateList = shouldUpdateBoolean;
},
/** Only update one single account in the pinia state.
* @param {object} userDataToReplace
*/
updateSingleAccountPiniaState(userDataToReplace){
const userIndex = this.allUserAccoutList.findIndex(user => user.username === userDataToReplace.username);
if (userIndex !== -1) {
this.allUserAccoutList[userIndex] = { ...this.allUserAccoutList[userIndex], ...userDataToReplace };
} else {
// Error handling here.
}
}
},
})

View File

@@ -334,6 +334,10 @@ export default defineComponent({
[inputPwd, inputConfirmPwd],
([newPwd, newConfirmPwd]) => {
isPwdMatched.value = newPwd === newConfirmPwd && newPwd.length;
// 只要[確認密碼]或[密碼]有更動confirm 按鈕就可點選
if (newPwd || newConfirmPwd) {
// isConfirmDisabled.value = false;
}
}
)
});

View File

@@ -28,10 +28,10 @@
</template>
<script>
import { defineComponent, ref, computed, onBeforeMount, watch, } from 'vue';
import { defineComponent, } from 'vue';
import { useModalStore } from '@/stores/modal.js';
import { useRouter } from 'vue-router';
import useAcctMgmtStore from '@/stores/acctMgmt.js';
import useAcctMgmtStore from '@/stores/acctMgmt';
import i18next from '@/i18n/i18n.js';
import { useToast } from 'vue-toast-notification';