<template> <main class="container is-fluid"> <template v-if="model"> <router-link class="button is-pulled-right" :to="{ name: 'models-list' }"> <i class="icon-arrow-left"></i> Models </router-link> <div class="title"> <span v-if="model.archived" class="tag">Archived</span> {{ model.name }} <EditForm class="ml-2 is-primary" :model-instance="model" mode="edit" /> </div> <div class="subtitle is-5"> <p>Model <ItemId :item-id="model.id" /></p> <button v-if="!model.archived" class="button is-danger mt-2" v-on:click="archiveModal = canAdmin" :disabled="!canAdmin || undefined" :title="archiveButtonTitle" > Archive model </button> </div> <div class="columns"> <div class="column"> <div class="field"> <label class="label">Created</label> <div class="control"> <p>{{ creationDate }}</p> </div> </div> </div> <div class="column"> <div class="field"> <label class="label">Last updated</label> <div class="control"> <p>{{ updateDate }}</p> </div> </div> </div> </div> <div class="field"> <label class="label">Description</label> <div class="control"> <!-- eslint-disable-next-line vue/no-v-html --> <p v-if="model.description" class="content" v-html="md.render(model.description)"></p> <p v-else>—</p> </div> </div> <hr /> <ModelDetails :model-id="modelId" /> </template> <div v-else-if="error" class="notification is-danger">{{ error }}</div> <div v-else class="loader is-size-2 mx-auto"></div> <ArchivalModal v-if="canAdmin" :instance="model" instance-type="model" v-model="archiveModal" :update-function="updateModel" /> </main> </template> <script lang="ts"> import MarkdownIt from 'markdown-it' import { defineComponent } from 'vue' import { mapState, mapActions } from 'pinia' import { UUID_REGEX } from '@/config' import { ago, errorParser } from '@/helpers' import { UUID } from '@/types' import { Model } from '@/types/model' import ModelDetails from '@/components/Model' import EditForm from '@/components/Model/EditForm.vue' import { useModelStore, useNotificationStore } from '@/stores' import ItemId from '@/components/ItemId.vue' import ArchivalModal from '@/components/ArchivalModal.vue' export default defineComponent({ props: { modelId: { type: String, required: true, validator: value => typeof value === 'string' && UUID_REGEX.test(value) } }, components: { ModelDetails, EditForm, ItemId, ArchivalModal }, data: () => ({ loading: false, error: null as string | null, archiveModal: false, md: new MarkdownIt({ breaks: true }) }), computed: { ...mapState(useModelStore, ['models']), model (): Model { return this.models[this.modelId] }, creationDate (): string | null { if (!this.model) return null return ago(new Date(this.model.created)) }, updateDate (): string | null { if (!this.model) return null return ago(new Date(this.model.updated)) }, canAdmin () { return this.model?.rights.includes('admin') }, archiveButtonTitle () { if (this.canAdmin) return 'Archive model' return 'You need administrator rights on a model to archive it' } }, methods: { ...mapActions(useNotificationStore, ['notify']), ...mapActions(useModelStore, ['retrieveModel', 'updateModel']), async loadModel (modelId: UUID) { this.loading = true try { await this.retrieveModel(modelId) } catch (err) { this.error = errorParser(err) } finally { this.loading = false } } }, watch: { modelId: { immediate: true, handler (newValue: UUID) { if (!this.models[newValue]) this.loadModel(newValue) } } } }) </script>