web: added functionality for add/delete user
This commit is contained in:
parent
d2c50fc2e5
commit
c6074c26e0
6 changed files with 200 additions and 14 deletions
1
web/components.d.ts
vendored
1
web/components.d.ts
vendored
|
@ -16,6 +16,7 @@ declare module 'vue' {
|
|||
LoginPage: typeof import('./src/components/loginPage.vue')['default']
|
||||
MainPage: typeof import('./src/components/MainPage.vue')['default']
|
||||
UpdateDialog: typeof import('./src/components/UpdateDialog.vue')['default']
|
||||
UsersAddDialog: typeof import('./src/components/NavBarIcons/UsersAddDialog.vue')['default']
|
||||
UsersDeleteActions: typeof import('./src/components/NavBarIcons/UsersDeleteActions.vue')['default']
|
||||
UsersDialog: typeof import('./src/components/NavBarIcons/UsersDialog.vue')['default']
|
||||
UsersEditActions: typeof import('./src/components/NavBarIcons/UsersEditActions.vue')['default']
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
<!-- Users, Groups, Licenses -->
|
||||
<div>
|
||||
<!-- USER MANAGEMENT -->
|
||||
<UsersDialog />
|
||||
<template v-if="!user" />
|
||||
<UsersDialog v-else-if="user.admin" />
|
||||
<UsersEditActions v-else :admin-menu="false" :user="user!" />
|
||||
<!-- -->
|
||||
<!-- GROUP SECTION -->
|
||||
<!-- -->
|
||||
|
@ -206,8 +208,10 @@ import { SubmitEventPromise } from "vuetify";
|
|||
import { ref } from "vue";
|
||||
import { Plus, LogOut, FolderPlus } from "lucide-vue-next";
|
||||
import { useQuery, useMutation, useQueryClient } from "@tanstack/vue-query";
|
||||
import UsersDialog from "./NavBarIcons/UsersDialog.vue";
|
||||
import UsersEditActions from "./NavBarIcons/UsersEditActions.vue";
|
||||
import { axiosInstance } from "@/client";
|
||||
import { LicenseGroup, CreateLicenseDto, CreateGroupDto } from "@/types";
|
||||
import { LicenseGroup, CreateLicenseDto, CreateGroupDto, User } from "@/types";
|
||||
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
|
@ -227,6 +231,14 @@ const { data } = useQuery({
|
|||
},
|
||||
});
|
||||
|
||||
const { data: user } = useQuery({
|
||||
queryKey: ["user"],
|
||||
queryFn: async () => {
|
||||
const res = await axiosInstance.get<User>("/users/me");
|
||||
return res.data;
|
||||
},
|
||||
});
|
||||
|
||||
const { mutate: licenseMutate } = useMutation({
|
||||
mutationFn: async (newLicense: CreateLicenseDto) => {
|
||||
await axiosInstance.post("/licenses", newLicense);
|
||||
|
|
149
web/src/components/NavBarIcons/UsersAddDialog.vue
Normal file
149
web/src/components/NavBarIcons/UsersAddDialog.vue
Normal file
|
@ -0,0 +1,149 @@
|
|||
<template>
|
||||
<div>
|
||||
<v-btn prepend-icon="mdi-plus" variant="outlined" block @click="add = true">
|
||||
Add User
|
||||
</v-btn>
|
||||
<v-dialog v-model="add" width="600" persistent>
|
||||
<v-card max-width="600">
|
||||
<v-form @submit.prevent="submit">
|
||||
<v-card-title>
|
||||
<span class="headline">Add User</span>
|
||||
</v-card-title>
|
||||
<v-card-subtitle>
|
||||
<span> Add an User to the database</span>
|
||||
</v-card-subtitle>
|
||||
<v-card-text>
|
||||
<div>
|
||||
<v-text-field
|
||||
label="User Name *"
|
||||
v-model="addUserName"
|
||||
variant="outlined"
|
||||
required
|
||||
clearable
|
||||
:rules="userNameRules"
|
||||
class="mb-3"
|
||||
></v-text-field>
|
||||
<v-text-field
|
||||
label="User Email *"
|
||||
v-model="addUserEmail"
|
||||
variant="outlined"
|
||||
required
|
||||
clearable
|
||||
:rules="userNameEmail"
|
||||
class="mb-3"
|
||||
></v-text-field>
|
||||
<v-text-field
|
||||
label="User Password *"
|
||||
v-model="addUserPassword"
|
||||
variant="outlined"
|
||||
required
|
||||
clearable
|
||||
:rules="userNamePassword"
|
||||
class="mb-3"
|
||||
></v-text-field>
|
||||
<v-switch
|
||||
label="Admin (Optional)"
|
||||
inset
|
||||
v-model="addUserAdmin"
|
||||
color="primary"
|
||||
></v-switch>
|
||||
<span class="dialogNote">
|
||||
all fields marked with * are required
|
||||
</span>
|
||||
</div>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-row>
|
||||
<v-col cols="10" align="right" no-gutters>
|
||||
<v-btn
|
||||
class="ms-auto"
|
||||
text="Cancel"
|
||||
color="blue darken-1"
|
||||
@click="add = false"
|
||||
></v-btn>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-btn
|
||||
class="ms-auto"
|
||||
text="Add"
|
||||
type="submit"
|
||||
color="blue darken-1"
|
||||
></v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-actions>
|
||||
</v-form>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { axiosInstance } from "@/client";
|
||||
import { CreateUserDto } from "@/types";
|
||||
import { useMutation, useQueryClient } from "@tanstack/vue-query";
|
||||
import { ref } from "vue";
|
||||
import { SubmitEventPromise } from "vuetify";
|
||||
|
||||
const add = ref(false);
|
||||
const addUserName = ref("");
|
||||
const addUserEmail = ref("");
|
||||
const addUserPassword = ref("");
|
||||
const addUserAdmin = ref(false);
|
||||
|
||||
const userNameRules = [
|
||||
(value: string) => {
|
||||
if (value) return true;
|
||||
|
||||
return "YOU MUST ENTER (A USER NAME";
|
||||
},
|
||||
];
|
||||
const userNameEmail = [
|
||||
(value: string) => {
|
||||
if (value) return true;
|
||||
|
||||
return "YOU MUST ENTER (A USER EMAIL)";
|
||||
},
|
||||
];
|
||||
|
||||
const userNamePassword = [
|
||||
(value: string) => {
|
||||
if (value) return true;
|
||||
|
||||
return "YOU MUST ENTER (A USER PASSWORD)";
|
||||
},
|
||||
];
|
||||
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const { mutate: userMutate } = useMutation({
|
||||
mutationFn: async (newUser: CreateUserDto) => {
|
||||
await axiosInstance.post("/users", newUser);
|
||||
},
|
||||
onError: (error) => {
|
||||
console.log(error);
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ["users"] });
|
||||
add.value = false;
|
||||
},
|
||||
});
|
||||
|
||||
async function submit(event: SubmitEventPromise) {
|
||||
const result = await event;
|
||||
if (result.valid) {
|
||||
const data = {
|
||||
name: addUserName.value,
|
||||
email: addUserEmail.value,
|
||||
password: addUserPassword.value,
|
||||
admin: addUserAdmin.value,
|
||||
};
|
||||
console.log(data);
|
||||
userMutate(data);
|
||||
} else {
|
||||
console.log("Invalid");
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
|
@ -16,16 +16,16 @@
|
|||
:items="data ?? []"
|
||||
:items-per-page="10"
|
||||
item-key="name"
|
||||
class="elevation-5"
|
||||
class="elevation-5 mb-5"
|
||||
>
|
||||
<template v-slot:item.actions="{ item }">
|
||||
<UsersEditAction :user="item" />
|
||||
<UsersEditAction :user="item" :admin-menu="true" />
|
||||
<UsersDeleteAction :user="item" />
|
||||
</template>
|
||||
</v-data-table>
|
||||
<UsersAddDialog />
|
||||
<v-divider class="border-opacity-50 mt-5" :thickness="2"></v-divider>
|
||||
</v-card-text>
|
||||
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn color="blue darken-1" @click="users = false">Close</v-btn>
|
||||
|
@ -37,9 +37,10 @@
|
|||
<script setup lang="ts">
|
||||
import UsersDeleteAction from "./UsersDeleteActions.vue";
|
||||
import UsersEditAction from "./UsersEditActions.vue";
|
||||
import UsersAddDialog from "./UsersAddDialog.vue";
|
||||
import { Users } from "lucide-vue-next";
|
||||
import { defineComponent, ref, computed, watch } from "vue";
|
||||
import { useQuery, useMutation, useQueryClient } from "@tanstack/vue-query";
|
||||
import { ref } from "vue";
|
||||
import { useQuery, useQueryClient } from "@tanstack/vue-query";
|
||||
import { axiosInstance } from "@/client";
|
||||
import { User } from "@/types";
|
||||
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
<template>
|
||||
<v-icon class="me-2" size="small" @click="edit = true">mdi-pencil</v-icon>
|
||||
<v-icon v-if="adminMenu" class="me-2" size="small" @click="edit = true"
|
||||
>mdi-pencil</v-icon
|
||||
>
|
||||
<v-btn v-else icon class="mr-3" @click="edit = true">
|
||||
<Users />
|
||||
</v-btn>
|
||||
<v-dialog v-model="edit" width="600" persistent>
|
||||
<v-card max-width="600">
|
||||
<v-form @submit.prevent="submitGroup">
|
||||
|
@ -15,7 +20,6 @@
|
|||
label="User Name *"
|
||||
v-model="editUserName"
|
||||
variant="outlined"
|
||||
required
|
||||
clearable
|
||||
:rules="editUserNameRules"
|
||||
class="mb-3"
|
||||
|
@ -24,17 +28,27 @@
|
|||
label="User Email *"
|
||||
v-model="editUserEmail"
|
||||
variant="outlined"
|
||||
required
|
||||
clearable
|
||||
:rules="editUserEmailRules"
|
||||
class="mb-3"
|
||||
></v-text-field>
|
||||
<v-text-field
|
||||
label="User Password (Optional)"
|
||||
v-model="editUserPassword"
|
||||
variant="outlined"
|
||||
clearable
|
||||
class="mb-3"
|
||||
></v-text-field>
|
||||
<v-switch
|
||||
label="Admin"
|
||||
label="Admin (Optional)"
|
||||
inset
|
||||
v-model="editUserAdmin"
|
||||
color="primary"
|
||||
v-if="adminMenu"
|
||||
></v-switch>
|
||||
<span class="dialogNote">
|
||||
all fields marked with * are required
|
||||
</span>
|
||||
</div>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
|
@ -68,8 +82,9 @@ import { SubmitEventPromise } from "vuetify";
|
|||
import { axiosInstance } from "@/client";
|
||||
import { useMutation, useQueryClient } from "@tanstack/vue-query";
|
||||
import { CreateLicenseDto, User } from "@/types";
|
||||
import { Users } from "lucide-vue-next";
|
||||
|
||||
const { user } = defineProps<{ user: User }>();
|
||||
const { user, adminMenu } = defineProps<{ user: User; adminMenu: boolean }>();
|
||||
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
|
@ -107,15 +122,16 @@ const { mutate: userMutate } = useMutation({
|
|||
await axiosInstance.post("/licenses", newLicense);
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ["licenses"] });
|
||||
queryClient.invalidateQueries({ queryKey: ["users"] });
|
||||
edit.value = false;
|
||||
},
|
||||
});
|
||||
|
||||
const edit = ref(false);
|
||||
const editUserName = ref(user.name);
|
||||
const editUserEmail = ref(user.email);
|
||||
const editUserAdmin = ref(user.admin);
|
||||
const edit = ref(false);
|
||||
const editUserPassword = ref(undefined);
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
|
@ -32,6 +32,13 @@ export interface User {
|
|||
admin: boolean;
|
||||
}
|
||||
|
||||
export interface CreateUserDto {
|
||||
name: string;
|
||||
email: string;
|
||||
password: string;
|
||||
admin: boolean;
|
||||
}
|
||||
|
||||
export type CreateGroupDto = Omit<LicenseGroup, "id" | "licenses">;
|
||||
|
||||
export type UpdateLicenseDto = Omit<License, "id">;
|
||||
|
|
Loading…
Reference in a new issue