Skip to content
Snippets Groups Projects

Resolve "Add UI for viewing and managing Resources"

Merged Daniel Göbel requested to merge feature/88-add-ui-for-viewing-and-managing-resources into main
Files
7
<script setup lang="ts">
import { reactive, onMounted, ref } from "vue";
import BootstrapModal from "@/components/modals/BootstrapModal.vue";
import { Modal } from "bootstrap";
import { useResourceStore } from "@/stores/resources";
import type { ResourceIn } from "@/client/resource";
import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
import { Tooltip } from "bootstrap";
const resourceRepository = useResourceStore();
const resourceCreateForm = ref<HTMLFormElement | undefined>(undefined);
const resourceNameElement = ref<HTMLInputElement | undefined>(undefined);
const resource = reactive<ResourceIn>({
name: "",
description: "",
release: "",
source: "",
});
const formState = reactive<{
validated: boolean;
resourceNameTaken: boolean;
loading: boolean;
}>({
validated: false,
resourceNameTaken: false,
loading: false,
});
const props = defineProps<{
modalID: string;
}>();
let createResourceModal: Modal | null = null;
function createResource() {
formState.validated = true;
formState.resourceNameTaken = false;
resource.description = resource.description.trim();
resource.name = resource.name.trim();
resourceNameElement.value?.setCustomValidity("");
if (resourceCreateForm.value?.checkValidity()) {
formState.loading = true;
resourceRepository
.createResource(resource)
.then(() => {
createResourceModal?.hide();
resource.name = "";
resource.description = "";
resource.source = "";
resource.release = "";
formState.resourceNameTaken = false;
formState.validated = false;
})
.catch((error) => {
if (
error.status === 400 &&
error.body["detail"] ===
`Resource with name '${resource.name}' already exists`
) {
formState.resourceNameTaken = true;
resourceNameElement.value?.setCustomValidity(
"Resource name is already taken",
);
}
})
.finally(() => {
formState.loading = false;
});
}
}
function modalClosed() {
formState.validated = false;
formState.resourceNameTaken = false;
resourceNameElement.value?.setCustomValidity("");
}
onMounted(() => {
createResourceModal = new Modal("#" + props.modalID);
new Tooltip("#tooltip-new-resource-source");
new Tooltip("#tooltip-new-resource-release");
});
</script>
<template>
<bootstrap-modal
:modalId="modalID"
static-backdrop
modal-label="Create Resource Modal"
v-on="{ 'hidden.bs.modal': modalClosed }"
>
<template #header> Create new Resource</template>
<template #body>
<form
id="resourceCreateForm"
:class="{ 'was-validated': formState.validated }"
ref="resourceCreateForm"
>
<div class="mb-3">
<label for="resourceNameInput" class="form-label"
>Resource Name</label
>
<div class="input-group">
<input
type="text"
class="form-control"
id="resourceNameInput"
required
minlength="3"
maxlength="32"
v-model="resource.name"
ref="resourceNameElement"
/>
<div class="invalid-feedback">
<div v-if="formState.resourceNameTaken">
Resource name already taken.
</div>
<div>
Requirements
<ul>
<li>At least 3 Characters long</li>
<li>Unique in CloWM</li>
</ul>
</div>
</div>
</div>
</div>
<div class="mb-3">
<label for="resourceDescriptionInput" class="form-label">
Description
</label>
<div class="input-group">
<textarea
class="form-control"
id="resourceDescriptionInput"
required
rows="3"
minlength="16"
maxlength="256"
v-model="resource.description"
placeholder="Describe the purpose of the resource"
></textarea>
<div class="invalid-feedback">
Requirements
<ul>
<li>At least 16 Characters long</li>
</ul>
</div>
</div>
</div>
<div class="mb-3">
<label for="resourceSourceInput" class="form-label"> Source </label>
<div class="input-group">
<div class="input-group-text">
<font-awesome-icon icon="fa-solid fa-link" />
</div>
<input
class="form-control"
id="resourceSourceInput"
required
minlength="8"
maxlength="264"
v-model="resource.source"
placeholder="The source of the resource (e.g. a link)"
/>
<div
class="input-group-text hover-info"
id="tooltip-new-resource-source"
data-bs-toggle="tooltip"
data-bs-title="The source from where the resource comes"
>
<font-awesome-icon icon="fa-solid fa-circle-question" />
</div>
</div>
</div>
<div class="mb-3">
<label for="resourceReleaseInput" class="form-label"> Release </label>
<div class="input-group">
<div class="input-group-text">
<font-awesome-icon icon="fa-solid fa-tag" />
</div>
<input
class="form-control"
id="resourceReleaseInput"
required
minlength="3"
maxlength="32"
v-model="resource.release"
placeholder="Initial release name"
/>
<div
class="input-group-text hover-info"
id="tooltip-new-resource-release"
data-bs-toggle="tooltip"
data-bs-title="The name of the first resource version"
>
<font-awesome-icon icon="fa-solid fa-circle-question" />
</div>
</div>
</div>
</form>
</template>
<template v-slot:footer>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
Close
</button>
<button
type="submit"
form="resourceCreateForm"
class="btn btn-primary"
:disabled="formState.loading"
@click.prevent="createResource"
>
<span
v-if="formState.loading"
class="spinner-border spinner-border-sm"
role="status"
aria-hidden="true"
></span>
Save
</button>
</template>
</bootstrap-modal>
</template>
<style scoped></style>
Loading