web: improve struckture
This commit is contained in:
parent
b6afc7de07
commit
1c5c30be6e
5 changed files with 231 additions and 219 deletions
1
web/components.d.ts
vendored
1
web/components.d.ts
vendored
|
@ -13,6 +13,7 @@ declare module 'vue' {
|
|||
ListViewElement: typeof import('./src/components/ListViewElement.vue')['default']
|
||||
LoginPage: typeof import('./src/components/loginPage.vue')['default']
|
||||
MainPage: typeof import('./src/components/MainPage.vue')['default']
|
||||
UpdateDialog: typeof import('./src/components/UpdateDialog.vue')['default']
|
||||
UsersDialog: typeof import('./src/components/NavBarIcons/UsersDialog.vue')['default']
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,15 +2,7 @@
|
|||
<div class="mt-3">
|
||||
<h2>{{ props.licenseGroupName }}:</h2>
|
||||
<li v-for="license in licenses" :key="license.id">
|
||||
<ListViewElement
|
||||
:id="license.id"
|
||||
:licenseName="license.name"
|
||||
:licenseKey="license.key"
|
||||
:startDate="license.start ? new Date(license.start) : null"
|
||||
:endDate="license.end ? new Date(license.end) : null"
|
||||
:amount="license.amount"
|
||||
:notes="license.note"
|
||||
/>
|
||||
<ListViewElement :license="license" />
|
||||
</li>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<v-expansion-panel>
|
||||
<v-expansion-panel-title>
|
||||
<div class="mr-3">
|
||||
{{ props.licenseName }}
|
||||
{{ license.name }}
|
||||
</div>
|
||||
|
||||
<div
|
||||
|
@ -12,7 +12,7 @@
|
|||
style="align-items: center"
|
||||
>
|
||||
<KeyRound class="mr-1" />
|
||||
{{ props.licenseKey }}
|
||||
{{ license.key }}
|
||||
</div>
|
||||
|
||||
<div
|
||||
|
@ -22,8 +22,8 @@
|
|||
<CalendarCheck />
|
||||
<span>
|
||||
{{
|
||||
props.startDate
|
||||
? props.startDate.toLocaleDateString()
|
||||
license.start
|
||||
? new Date(license.start).toLocaleDateString()
|
||||
: "Indefinitely"
|
||||
}}
|
||||
</span>
|
||||
|
@ -36,8 +36,8 @@
|
|||
<CalendarX />
|
||||
<span>
|
||||
{{
|
||||
props.endDate
|
||||
? props.endDate.toLocaleDateString()
|
||||
license.end
|
||||
? new Date(license.end).toLocaleDateString()
|
||||
: "Indefinitely"
|
||||
}}
|
||||
</span>
|
||||
|
@ -53,11 +53,11 @@
|
|||
class="logo mr-1"
|
||||
width="24"
|
||||
/>
|
||||
<span v-if="props.amount == null || props.amount == undefined">
|
||||
<span v-if="license.amount == null || license.amount == undefined">
|
||||
<Infinity />
|
||||
</span>
|
||||
<span v-else>
|
||||
{{ props.amount }}
|
||||
{{ license.amount }}
|
||||
</span>
|
||||
</div>
|
||||
</v-expansion-panel-title>
|
||||
|
@ -68,126 +68,14 @@
|
|||
class="flex-grow-1 overflow-x-auto border-e-md align-self-end"
|
||||
cols="10"
|
||||
>
|
||||
{{ props.notes }}
|
||||
{{ license.note }}
|
||||
</div>
|
||||
|
||||
<div align="end">
|
||||
<!-- -->
|
||||
<!-- EDIT SECTION -->
|
||||
<!-- -->
|
||||
<v-btn class="mr-3" @click="edit" flat size="small">
|
||||
<Pencil />
|
||||
</v-btn>
|
||||
<v-dialog v-model="edit" width="600" persistent>
|
||||
<v-card max-width="600">
|
||||
<v-form @submit.prevent="submitEdit">
|
||||
<v-card-title>
|
||||
<span class="headline">Add License</span>
|
||||
</v-card-title>
|
||||
<v-card-subtitle>
|
||||
<span> Add an extra License to the database</span>
|
||||
</v-card-subtitle>
|
||||
<v-card-text>
|
||||
<div>
|
||||
<v-text-field
|
||||
label="License Name *"
|
||||
v-model="editLicenseName"
|
||||
variant="outlined"
|
||||
required
|
||||
clearable
|
||||
:rules="editNameRules"
|
||||
class="mb-3"
|
||||
></v-text-field>
|
||||
<v-text-field
|
||||
label="License Key *"
|
||||
v-model="editLicenseKey"
|
||||
variant="outlined"
|
||||
required
|
||||
clearable
|
||||
:rules="editNameRules"
|
||||
class="mb-3"
|
||||
></v-text-field>
|
||||
<v-autocomplete
|
||||
clearable
|
||||
label="Select Group *"
|
||||
:items="Data"
|
||||
variant="outlined"
|
||||
:rules="editNameRules"
|
||||
class="mb-1"
|
||||
v-model="editLicenseGroup"
|
||||
></v-autocomplete>
|
||||
<!-- Divider maybe remove -->
|
||||
<v-divider
|
||||
class="border-opacity-50"
|
||||
:thickness="2"
|
||||
></v-divider>
|
||||
<div>
|
||||
<div class="mb-3 mt-3">
|
||||
<v-date-input
|
||||
label="Start Date (optional)"
|
||||
variant="outlined"
|
||||
prepend-icon=""
|
||||
prepend-inner-icon="mdi-calendar-check"
|
||||
clearable
|
||||
v-model="editStartDate"
|
||||
hide-details
|
||||
></v-date-input>
|
||||
</div>
|
||||
<div class="mb-6">
|
||||
<v-date-input
|
||||
label="Stop Date (optional)"
|
||||
variant="outlined"
|
||||
prepend-icon=""
|
||||
prepend-inner-icon="mdi-calendar-remove"
|
||||
clearable
|
||||
v-model="editStopDate"
|
||||
hide-details
|
||||
></v-date-input>
|
||||
</div>
|
||||
</div>
|
||||
<v-number-input
|
||||
label="Amount (optional)"
|
||||
users
|
||||
variant="outlined"
|
||||
clearable
|
||||
:min="0"
|
||||
v-model="editAmount"
|
||||
>
|
||||
</v-number-input>
|
||||
<v-text-field
|
||||
label="Notes (optional)"
|
||||
v-model="editNotes"
|
||||
variant="outlined"
|
||||
clearable
|
||||
></v-text-field>
|
||||
<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="edit = 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>
|
||||
<UpdateDialog :license="license" />
|
||||
<!-- -->
|
||||
<!-- DELETE BTN -->
|
||||
<!-- -->
|
||||
|
@ -203,108 +91,26 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { License } from "@/types";
|
||||
import {
|
||||
Infinity,
|
||||
KeyRound,
|
||||
CalendarCheck,
|
||||
CalendarX,
|
||||
Pencil,
|
||||
Trash,
|
||||
} from "lucide-vue-next";
|
||||
import { ref } from "vue";
|
||||
import { useQuery, useMutation, useQueryClient } from "@tanstack/vue-query";
|
||||
import { axiosInstance } from "@/client";
|
||||
import { SubmitEventPromise } from "vuetify";
|
||||
import { LicenseGroup, UpdateLicenseDto } from "@/types";
|
||||
import UpdateDialog from "./UpdateDialog.vue";
|
||||
|
||||
const props = defineProps<{
|
||||
id: string;
|
||||
const { license } = defineProps<{
|
||||
license: License;
|
||||
/*id: string;
|
||||
licenseName: string;
|
||||
licenseKey: string;
|
||||
startDate: Date | null;
|
||||
endDate: Date | null;
|
||||
amount?: number;
|
||||
notes?: string;
|
||||
notes?: string;*/
|
||||
}>();
|
||||
|
||||
// EDIT SECTION
|
||||
|
||||
const edit = ref(false);
|
||||
const editLicenseName = ref("");
|
||||
const editLicenseGroup = ref();
|
||||
const editAmount = ref();
|
||||
const editLicenseKey = ref("");
|
||||
const editStartDate = ref<Date | null>();
|
||||
const editStopDate = ref<Date | null>();
|
||||
const editNotes = ref<string | undefined>("");
|
||||
|
||||
//Give initial values to the fields
|
||||
editLicenseName.value = props.licenseName;
|
||||
editLicenseKey.value = props.licenseKey;
|
||||
editAmount.value = props.amount;
|
||||
editStartDate.value = props.startDate;
|
||||
editStopDate.value = props.endDate;
|
||||
editNotes.value = props.notes;
|
||||
|
||||
const editNameRules = [
|
||||
(value: string) => {
|
||||
if (value) return true;
|
||||
|
||||
return "YOU MUST ENTER (A GROUP NAME)";
|
||||
},
|
||||
];
|
||||
|
||||
async function submitEdit(event: SubmitEventPromise) {
|
||||
const result = await event;
|
||||
if (result.valid) {
|
||||
const editData = {
|
||||
name: editLicenseName.value,
|
||||
group_id: editLicenseGroup.value,
|
||||
amount: editAmount.value,
|
||||
key: editLicenseKey.value,
|
||||
start: editStartDate.value ?? null,
|
||||
end: editStopDate.value ?? null,
|
||||
notes: editNotes.value,
|
||||
};
|
||||
console.log(editData);
|
||||
editMutate(editData);
|
||||
} else {
|
||||
console.log("Invalid");
|
||||
}
|
||||
}
|
||||
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const gyros = props.id;
|
||||
|
||||
const { mutate: editMutate } = useMutation({
|
||||
mutationFn: async (newEdit: UpdateLicenseDto) => {
|
||||
await axiosInstance.put(`/licenses/${gyros}`, newEdit);
|
||||
},
|
||||
onError: (error) => {
|
||||
console.log(error);
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ["licenses"] });
|
||||
edit.value = false;
|
||||
},
|
||||
});
|
||||
|
||||
const { data } = useQuery({
|
||||
queryKey: ["licenses"],
|
||||
queryFn: async () => {
|
||||
const res = await axiosInstance.get<LicenseGroup[]>("/licenses");
|
||||
return res.data;
|
||||
},
|
||||
select: (data) => {
|
||||
return data.map((group) => {
|
||||
return {
|
||||
title: group.name,
|
||||
value: group.id,
|
||||
};
|
||||
});
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
|
212
web/src/components/UpdateDialog.vue
Normal file
212
web/src/components/UpdateDialog.vue
Normal file
|
@ -0,0 +1,212 @@
|
|||
<template>
|
||||
<v-btn class="mr-3" @click="edit = true" flat size="small">
|
||||
<Pencil />
|
||||
</v-btn>
|
||||
<v-dialog v-model="edit" width="600" persistent>
|
||||
<v-card max-width="600">
|
||||
<v-form @submit.prevent="submitEdit">
|
||||
<v-card-title>
|
||||
<span class="headline">Add License</span>
|
||||
</v-card-title>
|
||||
<v-card-subtitle>
|
||||
<span> Add an extra License to the database</span>
|
||||
</v-card-subtitle>
|
||||
<v-card-text>
|
||||
<div>
|
||||
<v-text-field
|
||||
label="License Name *"
|
||||
v-model="editLicenseName"
|
||||
variant="outlined"
|
||||
required
|
||||
clearable
|
||||
:rules="editNameRules"
|
||||
class="mb-3"
|
||||
></v-text-field>
|
||||
<v-text-field
|
||||
label="License Key *"
|
||||
v-model="editLicenseKey"
|
||||
variant="outlined"
|
||||
required
|
||||
clearable
|
||||
:rules="editNameRules"
|
||||
class="mb-3"
|
||||
></v-text-field>
|
||||
<v-autocomplete
|
||||
clearable
|
||||
label="Select Group *"
|
||||
:items="data"
|
||||
variant="outlined"
|
||||
:rules="editNameRules"
|
||||
class="mb-1"
|
||||
v-model="editLicenseGroup"
|
||||
></v-autocomplete>
|
||||
<!-- Divider maybe remove -->
|
||||
<v-divider class="border-opacity-50" :thickness="2"></v-divider>
|
||||
<div>
|
||||
<div class="mb-3 mt-3">
|
||||
<v-date-input
|
||||
label="Start Date (optional)"
|
||||
variant="outlined"
|
||||
prepend-icon=""
|
||||
prepend-inner-icon="mdi-calendar-check"
|
||||
clearable
|
||||
v-model="editStartDate"
|
||||
hide-details
|
||||
></v-date-input>
|
||||
</div>
|
||||
<div class="mb-6">
|
||||
<v-date-input
|
||||
label="Stop Date (optional)"
|
||||
variant="outlined"
|
||||
prepend-icon=""
|
||||
prepend-inner-icon="mdi-calendar-remove"
|
||||
clearable
|
||||
v-model="editStopDate"
|
||||
hide-details
|
||||
></v-date-input>
|
||||
</div>
|
||||
</div>
|
||||
<v-number-input
|
||||
label="Amount (optional)"
|
||||
users
|
||||
variant="outlined"
|
||||
clearable
|
||||
:min="0"
|
||||
v-model="editAmount"
|
||||
>
|
||||
</v-number-input>
|
||||
<v-text-field
|
||||
label="Notes (optional)"
|
||||
v-model="editNotes"
|
||||
variant="outlined"
|
||||
clearable
|
||||
></v-text-field>
|
||||
<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="edit = 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>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Pencil } from "lucide-vue-next";
|
||||
import { useQuery, useMutation, useQueryClient } from "@tanstack/vue-query";
|
||||
import { axiosInstance } from "@/client";
|
||||
import { SubmitEventPromise } from "vuetify";
|
||||
import { LicenseGroup, UpdateLicenseDto, License } from "@/types";
|
||||
import { ref } from "vue";
|
||||
|
||||
const { license } = defineProps<{
|
||||
license: License;
|
||||
}>();
|
||||
|
||||
// EDIT SECTION
|
||||
|
||||
const edit = ref(false);
|
||||
const editLicenseName = ref(license.name);
|
||||
const editLicenseGroup = ref(license.group_id);
|
||||
const editAmount = ref(license.amount);
|
||||
const editLicenseKey = ref(license.key);
|
||||
const editStartDate = ref<Date | null>(
|
||||
license.start ? new Date(license.start) : null
|
||||
);
|
||||
const editStopDate = ref<Date | null>(
|
||||
license.end ? new Date(license.end) : null
|
||||
);
|
||||
const editNotes = ref<string | undefined>(license.note);
|
||||
|
||||
//Give initial values to the fields
|
||||
/*editLicenseName.value = props.licenseName;
|
||||
editLicenseKey.value = props.licenseKey;
|
||||
editAmount.value = props.amount;
|
||||
editStartDate.value = props.startDate;
|
||||
editStopDate.value = props.endDate;
|
||||
editNotes.value = props.notes;*/
|
||||
|
||||
const editNameRules = [
|
||||
(value: string) => {
|
||||
if (value) return true;
|
||||
|
||||
return "YOU MUST ENTER (A GROUP NAME)";
|
||||
},
|
||||
];
|
||||
|
||||
async function submitEdit(event: SubmitEventPromise) {
|
||||
const result = await event;
|
||||
if (result.valid) {
|
||||
const editData = {
|
||||
name: editLicenseName.value,
|
||||
group_id: editLicenseGroup.value,
|
||||
amount: editAmount.value,
|
||||
key: editLicenseKey.value,
|
||||
start: editStartDate.value
|
||||
? editStartDate.value.toISOString()
|
||||
: undefined,
|
||||
end: editStopDate.value ? editStopDate.value.toISOString() : undefined,
|
||||
notes: editNotes.value,
|
||||
};
|
||||
console.log(editData);
|
||||
editMutate(editData);
|
||||
} else {
|
||||
console.log("Invalid");
|
||||
}
|
||||
}
|
||||
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const gyros = license.id;
|
||||
|
||||
const { mutate: editMutate } = useMutation({
|
||||
mutationFn: async (newEdit: UpdateLicenseDto) => {
|
||||
await axiosInstance.put(`/licenses/${gyros}`, newEdit);
|
||||
},
|
||||
onError: (error) => {
|
||||
console.log(error);
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ["licenses"] });
|
||||
edit.value = false;
|
||||
},
|
||||
});
|
||||
|
||||
const { data } = useQuery({
|
||||
queryKey: ["licenses"],
|
||||
queryFn: async () => {
|
||||
const res = await axiosInstance.get<LicenseGroup[]>("/licenses");
|
||||
return res.data;
|
||||
},
|
||||
select: (data) => {
|
||||
return data.map((group) => {
|
||||
return {
|
||||
title: group.name,
|
||||
value: group.id,
|
||||
};
|
||||
});
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
|
@ -12,6 +12,7 @@ export interface License {
|
|||
key: string;
|
||||
amount?: number;
|
||||
note?: string;
|
||||
group_id: string;
|
||||
}
|
||||
|
||||
export interface CreateLicenseDto {
|
||||
|
|
Loading…
Add table
Reference in a new issue