fix: acct_mgmt_button
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
@@ -334,6 +334,10 @@ export default defineComponent({
|
||||
[inputPwd, inputConfirmPwd],
|
||||
([newPwd, newConfirmPwd]) => {
|
||||
isPwdMatched.value = newPwd === newConfirmPwd && newPwd.length;
|
||||
// 只要[確認密碼]或[密碼]有更動,confirm 按鈕就可點選
|
||||
if (newPwd || newConfirmPwd) {
|
||||
// isConfirmDisabled.value = false;
|
||||
}
|
||||
}
|
||||
)
|
||||
});
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user