feature: just create badge. Important thing is the await keyword
This commit is contained in:
4
src/assets/icon-new.svg
Normal file
4
src/assets/icon-new.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="35" height="16" viewBox="0 0 35 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M34.11 14.49L30.19 7.87L34.07 1.52C34.1621 1.36868 34.2124 1.1956 34.2157 1.01848C34.2189 0.841351 34.1751 0.666534 34.0886 0.511912C34.0022 0.35729 33.8762 0.228414 33.7236 0.138469C33.5709 0.0485231 33.3972 0.000737145 33.22 0H2C1.46957 0 0.960859 0.210714 0.585786 0.585787C0.210714 0.96086 0 1.46957 0 2L0 14C0 14.5304 0.210714 15.0391 0.585786 15.4142C0.960859 15.7893 1.46957 16 2 16H33.25C33.4265 16 33.5999 15.9532 33.7524 15.8645C33.905 15.7758 34.0314 15.6483 34.1188 15.4949C34.2061 15.3415 34.2513 15.1678 34.2498 14.9913C34.2482 14.8148 34.2 14.6418 34.11 14.49ZM10.51 11.18H9.39L6.13 6.84V11.19H5V5H6.13L9.4 9.35V5H10.52L10.51 11.18ZM16.84 6H13.31V7.49H16.51V8.49H13.31V10.1H16.84V11.1H12.18V5H16.83L16.84 6ZM25.13 11.16H24L22.45 6.57L20.9 11.18H19.78L17.78 5H19L20.32 9.43L21.84 5H23.06L24.52 9.43L25.85 5H27.08L25.13 11.16Z" fill="#FFCC44"/>
|
||||
<path d="M34.11 14.49L30.19 7.87L34.07 1.52C34.1621 1.36868 34.2124 1.1956 34.2157 1.01848C34.2189 0.841351 34.1751 0.666534 34.0886 0.511912C34.0022 0.35729 33.8762 0.228414 33.7236 0.138469C33.5709 0.0485231 33.3972 0.000737145 33.22 0H2C1.46957 0 0.960859 0.210714 0.585786 0.585787C0.210714 0.96086 0 1.46957 0 2L0 14C0 14.5304 0.210714 15.0391 0.585786 15.4142C0.960859 15.7893 1.46957 16 2 16H33.25C33.4265 16 33.5999 15.9532 33.7524 15.8645C33.905 15.7758 34.0314 15.6483 34.1188 15.4949C34.2061 15.3415 34.2513 15.1678 34.2498 14.9913C34.2482 14.8148 34.2 14.6418 34.11 14.49ZM10.51 11.18H9.39L6.13 6.84V11.19H5V5H6.13L9.4 9.35V5H10.52L10.51 11.18ZM16.84 6H13.31V7.49H16.51V8.49H13.31V10.1H16.84V11.1H12.18V5H16.83L16.84 6ZM25.13 11.16H24L22.45 6.57L20.9 11.18H19.78L17.78 5H19L20.32 9.43L21.84 5H23.06L24.52 9.43L25.85 5H27.08L25.13 11.16Z" fill="#FFAA44"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
@@ -8,6 +8,8 @@ export const MODAL_ACCT_EDIT = 'MODAL_ACCT_EDIT';
|
||||
export const MODAL_ACCT_INFO = 'MODAL_ACCT_INFO';
|
||||
export const MODAL_DELETE = 'MODAL_DELETE';
|
||||
|
||||
export const JUST_CREATE_ACCOUNT_HOT_DURATION_MINS = 2;
|
||||
|
||||
export const knownLayoutChartOption = {
|
||||
padding: {
|
||||
top: 16,
|
||||
|
||||
@@ -8,7 +8,7 @@ import Map from '@/views/Discover/Map/index.vue';
|
||||
import Conformance from '@/views/Discover/Conformance/index.vue';
|
||||
import Performance from '@/views/Discover/Performance/index.vue';
|
||||
import CompareDashboard from '@/views/Compare/Dashboard/index.vue';
|
||||
import AccountAdmin from '@/views/AccountManagement/AccountAdmin/index.vue';
|
||||
import AccountAdmin from '@/views/AccountManagement/AccountAdmin/AccountAdmin.vue';
|
||||
import MemberArea from '@/views/MemberArea/index.vue';
|
||||
import NotFound404 from '@/views/NotFound404.vue';
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
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: () => ({
|
||||
@@ -12,6 +13,9 @@ export default defineStore('acctMgmtStore', {
|
||||
response: {
|
||||
deleteAccount: null,
|
||||
},
|
||||
isOneAccountJustCreate: false, //如果有一個帳號剛剛建立,則會在列表上的第一列顯示這個帳號,並且右置一個徽章
|
||||
justCreateUsername: "", // unique username
|
||||
shouldUpdateList: false, // 控制是否該刷新列表
|
||||
}),
|
||||
getters: {
|
||||
},
|
||||
@@ -90,6 +94,11 @@ export default defineStore('acctMgmtStore', {
|
||||
|
||||
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.');
|
||||
@@ -132,7 +141,7 @@ export default defineStore('acctMgmtStore', {
|
||||
}
|
||||
}
|
||||
catch(error) {
|
||||
apiError(error, 'Failed to get user detail.');
|
||||
//不需要跳出錯誤,因為如果是錯誤反而是好事,表示帳號是獨一的
|
||||
return false;
|
||||
};
|
||||
},
|
||||
@@ -180,5 +189,17 @@ export default defineStore('acctMgmtStore', {
|
||||
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;
|
||||
},
|
||||
},
|
||||
})
|
||||
@@ -14,11 +14,15 @@
|
||||
>
|
||||
<Column field="username" :header="i18next.t('AcctMgmt.Account')" bodyClass="font-medium" sortable>
|
||||
<template #body="slotProps">
|
||||
<div class="row-container flex-w-full-hoverable w-full" @mouseenter="handleRowMouseOver(slotProps.data.username)"
|
||||
<div class="row-container flex-w-full-hoverable w-full flex" @mouseenter="handleRowMouseOver(slotProps.data.username)"
|
||||
@mouseout="handleRowMouseOut(slotProps.data.username)">
|
||||
<div @dblclick="onAcctDoubleClick(slotProps.data.username)" class="cursor-pointer">
|
||||
<div @dblclick="onAcctDoubleClick(slotProps.data.username)" class="cursor-pointer flex">
|
||||
{{ slotProps.data.username }}
|
||||
</div>
|
||||
<span id="just_create_badge" class="flex ml-4"
|
||||
v-if="isOneAccountJustCreate && slotProps.data.username === justCreateUsername">
|
||||
<img src="@/assets/icon-new.svg" alt="New">
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</Column>
|
||||
@@ -100,7 +104,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, computed, onBeforeMount, watch, } from 'vue';
|
||||
import { ref, computed, onMounted, watch, } from 'vue';
|
||||
import { storeToRefs, mapState, mapActions, } from 'pinia';
|
||||
import LoadingStore from '@/stores/loading.js';
|
||||
import { useModalStore } from '@/stores/modal.js';
|
||||
@@ -128,9 +132,7 @@ function repeatAccountList(accountList, N) {
|
||||
const repeatedList = [];
|
||||
|
||||
for (let i = 0; i < N; i++) {
|
||||
// 复制每次的对象并将其添加到新数组中
|
||||
accountList.forEach(account => {
|
||||
// 创建一个新的对象,避免直接引用
|
||||
const newAccount = { ...account, id: account.id + i };
|
||||
repeatedList.push(newAccount);
|
||||
});
|
||||
@@ -150,10 +152,16 @@ export default {
|
||||
const { isLoading } = storeToRefs(loadingStore);
|
||||
const loginStore = piniaLoginStore();
|
||||
const infiniteStart = ref(0);
|
||||
const infiniteAcctData = computed(() => acctMgmtStore.allUserAccoutList.slice(0, infiniteStart.value + ONCE_RENDER_NUM_OF_DATA));
|
||||
|
||||
const shouldUpdateList = computed(() => acctMgmtStore.shouldUpdateList);
|
||||
|
||||
const allAccountResponsive = computed(() => acctMgmtStore.allUserAccoutList);
|
||||
const infiniteAcctData = computed(() => allAccountResponsive.value.slice(0, infiniteStart.value + ONCE_RENDER_NUM_OF_DATA));
|
||||
const loginUserData = ref(null);
|
||||
|
||||
const isOneAccountJustCreate = computed(() => acctMgmtStore.isOneAccountJustCreate);
|
||||
const justCreateUsername = computed(() => acctMgmtStore.justCreateUsername);
|
||||
|
||||
const fetchLoginUserData = async () => {
|
||||
await loginStore.getUserData();
|
||||
loginUserData.value = loginStore.userData;
|
||||
@@ -162,12 +170,23 @@ export default {
|
||||
const moveCurrentLoginUserToFirstRow = () => {
|
||||
const currentLoginUsername = loginUserData.value.username;
|
||||
if(infiniteAcctData.value && infiniteAcctData.value.length){
|
||||
const index = infiniteAcctData.value.findIndex(user => user.username === currentLoginUsername);
|
||||
const index = allAccountResponsive.value.findIndex(user => user.username === currentLoginUsername);
|
||||
|
||||
if (index !== -1) {
|
||||
// 移除匹配的對象(現正登入的使用者)並將其插入到陣列的第一位"
|
||||
const [user] = infiniteAcctData.value.splice(index, 1);
|
||||
infiniteAcctData.value.unshift(user);
|
||||
// 移除匹配的對象(現正登入的使用者)並將其插入到陣列的第一位
|
||||
const [loginUser] = allAccountResponsive.value.splice(index, 1);
|
||||
infiniteAcctData.value.unshift(loginUser);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const moveJustCreateUserToFirstRow = () => {
|
||||
if(infiniteAcctData.value && infiniteAcctData.value.length){
|
||||
const index = acctMgmtStore.allUserAccoutList.findIndex(user => user.username === acctMgmtStore.justCreateUsername);
|
||||
if (index !== -1) {
|
||||
// 移除匹配的對象(剛剛新增的使用者)並將其插入到陣列的第一位
|
||||
const [justCreateUser] = acctMgmtStore.allUserAccoutList.splice(index, 1);
|
||||
infiniteAcctData.value.unshift(justCreateUser);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -225,7 +244,19 @@ export default {
|
||||
return curData?.isRowHovered ? 'bg-[#F1F5F9]' : '';
|
||||
};
|
||||
|
||||
onBeforeMount(async () => {
|
||||
watch(shouldUpdateList, async(newShouldUpdateList) => {
|
||||
if (newShouldUpdateList) {
|
||||
await acctMgmtStore.getAllUserAccounts();
|
||||
acctMgmtStore.setShouldUpdateList(false);
|
||||
|
||||
// 當夾帶有infiniteStart.value,就表示依然考慮到無限捲動的需求
|
||||
infiniteAcctData.value = allAccountResponsive.value.slice(0, infiniteStart.value + ONCE_RENDER_NUM_OF_DATA);
|
||||
moveCurrentLoginUserToFirstRow();
|
||||
moveJustCreateUserToFirstRow();
|
||||
}
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
await fetchLoginUserData();
|
||||
await acctMgmtStore.getAllUserAccounts();
|
||||
moveCurrentLoginUserToFirstRow();
|
||||
@@ -271,6 +302,8 @@ export default {
|
||||
modalStore,
|
||||
loginUserData,
|
||||
infiniteAcctData,
|
||||
isOneAccountJustCreate,
|
||||
justCreateUsername,
|
||||
onCreateNewClick,
|
||||
onAcctDoubleClick,
|
||||
handleScroll,
|
||||
@@ -163,10 +163,6 @@ export default defineComponent({
|
||||
|
||||
const whichCurrentModal = computed(() => modalStore.whichModal);
|
||||
|
||||
const {
|
||||
id,
|
||||
} = currentViewingUser;
|
||||
|
||||
const isSSO = computed(() => acctMgmtStore.currentViewingUser.is_sso);
|
||||
const username = computed(() => acctMgmtStore.currentViewingUser.username);
|
||||
const name = computed(() => acctMgmtStore.currentViewingUser.name);
|
||||
@@ -246,7 +242,7 @@ export default defineComponent({
|
||||
});
|
||||
await toast.success(i18next.t("AcctMgmt.MsgAccountAdded"));
|
||||
await modalStore.closeModal();
|
||||
await acctMgmtStore.getAllUserAccounts();
|
||||
acctMgmtStore.setShouldUpdateList(true);
|
||||
await router.push('/account/account-admin');
|
||||
break;
|
||||
default:
|
||||
@@ -277,7 +273,6 @@ export default defineComponent({
|
||||
return {
|
||||
isConfirmDisabled,
|
||||
username,
|
||||
id,
|
||||
name,
|
||||
isSSO,
|
||||
isPwdEyeOn,
|
||||
@@ -3,7 +3,7 @@
|
||||
flex justify-center items-center">
|
||||
|
||||
<div class="flex">
|
||||
<ModalAccountEdit v-if="whichModal === MODAL_ACCT_EDIT || whichModal === MODAL_CREATE_NEW "/>
|
||||
<ModalAccountEditCreate v-if="whichModal === MODAL_ACCT_EDIT || whichModal === MODAL_CREATE_NEW "/>
|
||||
<ModalAccountInfo v-if="whichModal === MODAL_ACCT_INFO"/>
|
||||
<ModalDeleteAlert v-if="whichModal === MODAL_DELETE" />
|
||||
</div>
|
||||
@@ -11,9 +11,9 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { watch, computed, } from 'vue';
|
||||
import { computed, } from 'vue';
|
||||
import { useModalStore } from '@/stores/modal.js';
|
||||
import ModalAccountEdit from './ModalAccountEdit.vue';
|
||||
import ModalAccountEditCreate from './ModalAccountEditCreate.vue';
|
||||
import ModalAccountInfo from './ModalAccountInfo.vue';
|
||||
import ModalDeleteAlert from './ModalDeleteAlert.vue';
|
||||
import {
|
||||
@@ -29,10 +29,6 @@
|
||||
const modalStore = useModalStore();
|
||||
const whichModal = computed(() => modalStore.whichModal);
|
||||
|
||||
watch(() => whichModal, (newVal, oldVal) => {
|
||||
// (`whichModal changed from ${oldVal} to ${newVal}`);
|
||||
});
|
||||
|
||||
return {
|
||||
modalStore,
|
||||
whichModal,
|
||||
@@ -43,7 +39,7 @@
|
||||
};
|
||||
},
|
||||
components: {
|
||||
ModalAccountEdit,
|
||||
ModalAccountEditCreate,
|
||||
ModalAccountInfo,
|
||||
ModalDeleteAlert,
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ export default defineComponent({
|
||||
if(acctMgmtStore.deleteAccount(acctMgmtStore.currentViewingUser.username)){
|
||||
toast.success(i18next.t("AcctMgmt.MsgAccountDeleteSuccess"));
|
||||
modalStore.closeModal();
|
||||
await acctMgmtStore.getAllUserAccounts();
|
||||
acctMgmtStore.setShouldUpdateList(true);
|
||||
router.push("/account/account-admin");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user