feature: create POST api done.

This commit is contained in:
Cindy Chang
2024-06-21 15:21:24 +08:00
parent 0fb0d8b529
commit 9b0d54bf5e
4 changed files with 109 additions and 13 deletions

View File

@@ -1,5 +1,5 @@
export const PRIME_VUE_TICKS_LIMIT = 6;
export const ONCE_RENDER_NUM_OF_DATA = 6;
export const ONCE_RENDER_NUM_OF_DATA = 9;
export const GRID_COLOR = '#64748b';

View File

@@ -69,6 +69,28 @@ export default defineStore('acctMgmtStore', {
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);
console.log('TODO: response:', response, response.status);
}
catch(error) {
apiError(error, 'Failed to add a new account');
};
},
/**
* According to mouseover or mouseleave status, change the bool value.
* @param {string} username

View File

@@ -123,7 +123,7 @@ import {
import iconDetailOn from '@/assets/icon-detail-on.svg';
import iconDetailOff from '@/assets/icon-detail-card.svg';
// 這是製作假資料,在正式環境不會用到
function repeatAccountList(accountList, N) {
const repeatedList = [];
@@ -143,7 +143,7 @@ function repeatAccountList(accountList, N) {
const repeatedAccountList = repeatAccountList(accountList, 20);
export default {
setup(props) {
setup() {
const acctMgmtStore = useAcctMgmtStore();
const loadingStore = LoadingStore();
const modalStore = useModalStore();
@@ -182,6 +182,8 @@ export default {
internalInfiniteAcctData.value = allUserAccoutList.value.slice(0, ONCE_RENDER_NUM_OF_DATA)
};
const isInfiniteFinish = ref(true);
const handleDeleteMouseOver = (username) => {
acctMgmtStore.changeIsDeleteHoveredByUser(username, true);
};
@@ -229,12 +231,39 @@ export default {
moveCurrentLoginUserToFirstRow();
});
/**
* 無限滾動: 監聽 scroll 有沒有滾到底部
* @param {element} event 滾動傳入的事件
*/
const handleScroll = (event) => {
if(internalInfiniteAcctData.value.length < ONCE_RENDER_NUM_OF_DATA || isInfiniteFinish.value === false) {
return;
}
const container = event.target;
const smallValue = 4;
const overScrollHeight = container.scrollTop + container.clientHeight >= container.scrollHeight - smallValue;
if(overScrollHeight){
fetchMoreDataVue3();
}
};
const fetchMoreDataVue3 = () => {
infiniteStart.value += ONCE_RENDER_NUM_OF_DATA;
internalInfiniteAcctData.value = [internalInfiniteAcctData.value, acctMgmtStore.allUserAccoutList.slice(
infiniteStart.value, this.infiniteStart + ONCE_RENDER_NUM_OF_DATA)];
isInfiniteFinish.value = true;
};
return {
isLoading,
modalStore,
loginUserData,
internalInfiniteAcctData,
onCreateNewClick,
handleScroll,
getRowClass,
onDeleteBtnClick,
handleDeleteMouseOver,
@@ -276,11 +305,12 @@ export default {
onAdminRightsBtnClick(isOn){
},
/**
* 無限滾動: 監聽 scroll 有沒有滾到底部
* @param {element} event 滾動傳入的事件
*/
handleScroll(event) {
handleScrollVue2(event) {
if(this.infinitMaxItems || this.infiniteAcctData.length < ONCE_RENDER_NUM_OF_DATA || this.isInfiniteFinish === false) {
return;
}
@@ -291,13 +321,13 @@ export default {
const overScrollHeight = container.scrollTop + container.clientHeight >= container.scrollHeight - smallValue;
if(overScrollHeight){
this.fetchMoreData();
this.fetchMoreDataVue2();
}
},
/**
* 無限滾動: 滾到底後,要載入數據
*/
async fetchMoreData() {
async fetchMoreDataVue2() {
this.isLoading = true;
this.infiniteFinish = false;
this.infiniteStart += ONCE_RENDER_NUM_OF_DATA;

View File

@@ -13,7 +13,7 @@
</div>
<input id="input_account_field"
class="w-[454px] rounded p-1 border border-[1px] border-[#64748B] flex items-center h-[40px] outline-none"
:value="username"/>
v-model="inputUserAccount"/>
</div>
<div class="input-row w-full flex py-2 h-[40px] mb-4 items-center
justify-between">
@@ -23,7 +23,7 @@
</span>
</div>
<input class="w-[454px] rounded p-1 border border-[1px] border-[#64748B] flex items-center h-[40px] outline-none"
:value="name"/>
v-model="inputName"/>
</div>
<div v-show="!isSSO" class="input-row w-full flex py-2 h-[40px] mb-4 items-center
justify-between">
@@ -115,7 +115,7 @@
</template>
<script>
import { defineComponent, computed, ref, } from 'vue';
import { defineComponent, computed, ref, watch, } from 'vue';
import i18next from "@/i18n/i18n.js";
import { mapActions, } from 'pinia';
import { useModalStore } from '@/stores/modal.js';
@@ -133,8 +133,7 @@ export default defineComponent({
const isPwdEyeOn = ref(false);
const isPwdConfirmEyeOn = ref(false);
const isPwdMatched = ref(true);
const inputPwd = ref("");
const inputConfirmPwd = ref("");
const isSetAsAdminChecked = ref(false);
const isSetActivedChecked = ref(true);
@@ -148,6 +147,22 @@ export default defineComponent({
const username = computed(() => acctMgmtStore.currentViewingUser.username);
const name = computed(() => acctMgmtStore.currentViewingUser.name);
const inputUserAccount = ref(whichCurrentModal.value === MODAL_CREATE_NEW ? '' : currentViewingUser.value.username);
const inputName = ref(whichCurrentModal.value === MODAL_CREATE_NEW ? '' : currentViewingUser.value.name);
const inputPwd = ref("");
const inputConfirmPwd = ref("");
// 自從加入這段 watch 之後,填寫密碼欄位之時,就不會胡亂清空掉 account 或是 full name 蘭為了。
watch(whichCurrentModal, (newVal) => {
if (newVal === MODAL_CREATE_NEW) {
inputUserAccount.value = '';
inputName.value = '';
} else {
inputUserAccount.value = currentViewingUser.value.username;
inputName.value = currentViewingUser.value.name;
}
});
const modalTitle = computed(() => {
return modalStore.whichModal === MODAL_CREATE_NEW ? i18next.t('AcctMgmt.CreateNew') : i18next.t('AcctMgmt.AccountEdit');
});
@@ -164,14 +179,41 @@ export default defineComponent({
};
const validateConfirmPwd = () => {
let validateResult = true;
isPwdMatched.value = inputPwd.value === inputConfirmPwd.value;
console.log('isPwdMatched.value',isPwdMatched.value );
return validateResult && isPwdMatched.value;
}
const onConfirmBtnClick = () => {
validateConfirmPwd();
const validateResult = validateConfirmPwd();
if(!validateResult){
return;
}
//TODO: 這邊要記得回來加一個判斷帳號是否已經存在的邏輯
checkAccountIsUnique();
console.log('input content to feed in',
inputUserAccount.value,
inputPwd.value,
inputName.value,
isSetAsAdminChecked.value,
isSetActivedChecked.value,
);
acctMgmtStore.createNewAccount({
username: inputUserAccount.value,
password: inputPwd.value,
name: inputName.value,
is_admin: isSetAsAdminChecked.value,
is_active: isSetActivedChecked.value,
});
}
const checkAccountIsUnique = async() => {
let isAccountUnique = false;
//TODO: call pinia store to call backend API
return isAccountUnique;
};
const toggleIsAdmin = () => {
isSetAsAdminChecked.value = !isSetAsAdminChecked.value;
}
@@ -190,6 +232,8 @@ export default defineComponent({
togglePwdEyeBtn,
togglePwdConfirmEyeBtn,
isPwdMatched,
inputUserAccount,
inputName,
inputPwd,
inputConfirmPwd,
onConfirmBtnClick,