Compare commits
No commits in common. "master" and "develop" have entirely different histories.
17 changed files with 775 additions and 3639 deletions
|
@ -64,7 +64,7 @@ export default class MimetypeController {
|
||||||
'maxLength': '{{ field }} must be less then {{ max }} characters long',
|
'maxLength': '{{ field }} must be less then {{ max }} characters long',
|
||||||
'isUnique': '{{ field }} must be unique, and this value is already taken',
|
'isUnique': '{{ field }} must be unique, and this value is already taken',
|
||||||
'required': '{{ field }} is required',
|
'required': '{{ field }} is required',
|
||||||
'file_extension.array.minLength': 'at least {{ min }} mimetypes must be defined',
|
'file_extension.minLength': 'at least {{ min }} mimetypes must be defined',
|
||||||
'file_extension.*.string': 'Each file extension must be a valid string', // Adjusted to match the type
|
'file_extension.*.string': 'Each file extension must be a valid string', // Adjusted to match the type
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -936,7 +936,6 @@ export default class DatasetsController {
|
||||||
}
|
}
|
||||||
|
|
||||||
const collectionRoles = await CollectionRole.query()
|
const collectionRoles = await CollectionRole.query()
|
||||||
.whereIn('name', ['ddc', 'ccs'])
|
|
||||||
.preload('collections', (coll: Collection) => {
|
.preload('collections', (coll: Collection) => {
|
||||||
// preloa only top level collection with noparent_id
|
// preloa only top level collection with noparent_id
|
||||||
coll.whereNull('parent_id').orderBy('number', 'asc');
|
coll.whereNull('parent_id').orderBy('number', 'asc');
|
||||||
|
|
|
@ -1500,7 +1500,6 @@ export default class DatasetController {
|
||||||
}
|
}
|
||||||
|
|
||||||
const collectionRoles = await CollectionRole.query()
|
const collectionRoles = await CollectionRole.query()
|
||||||
.whereIn('name', ['ddc', 'ccs'])
|
|
||||||
.preload('collections', (coll: Collection) => {
|
.preload('collections', (coll: Collection) => {
|
||||||
// preloa only top level collection with noparent_id
|
// preloa only top level collection with noparent_id
|
||||||
coll.whereNull('parent_id').orderBy('number', 'asc');
|
coll.whereNull('parent_id').orderBy('number', 'asc');
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -32,21 +32,3 @@ export default class CollectionsRoles extends BaseSchema {
|
||||||
// visible_oai boolean NOT NULL DEFAULT true,
|
// visible_oai boolean NOT NULL DEFAULT true,
|
||||||
// CONSTRAINT collections_roles_pkey PRIMARY KEY (id)
|
// CONSTRAINT collections_roles_pkey PRIMARY KEY (id)
|
||||||
// )
|
// )
|
||||||
|
|
||||||
// change to normal intzeger:
|
|
||||||
// ALTER TABLE collections_roles ALTER COLUMN id DROP DEFAULT;
|
|
||||||
// DROP SEQUENCE IF EXISTS collections_roles_id_seq;
|
|
||||||
|
|
||||||
// -- Step 1: Temporarily change one ID to a value not currently used
|
|
||||||
// UPDATE collections_roles SET id = 99 WHERE name = 'ccs';
|
|
||||||
|
|
||||||
// -- Step 2: Change 'ddc' ID to 2 (the old 'ccs' ID)
|
|
||||||
// UPDATE collections_roles SET id = 2 WHERE name = 'ddc';
|
|
||||||
|
|
||||||
// -- Step 3: Change the temporary ID (99) to 3 (the old 'ddc' ID)
|
|
||||||
// UPDATE collections_roles SET id = 3 WHERE name = 'ccs';
|
|
||||||
|
|
||||||
// UPDATE collections_roles SET id = 99 WHERE name = 'bk';
|
|
||||||
// UPDATE collections_roles SET id = 1 WHERE name = 'institutes';
|
|
||||||
// UPDATE collections_roles SET id = 4 WHERE name = 'pacs';
|
|
||||||
// UPDATE collections_roles SET id = 7 WHERE name = 'bk';
|
|
|
@ -25,8 +25,6 @@ export default class Collections extends BaseSchema {
|
||||||
.onUpdate('CASCADE');
|
.onUpdate('CASCADE');
|
||||||
table.boolean('visible').notNullable().defaultTo(true);
|
table.boolean('visible').notNullable().defaultTo(true);
|
||||||
table.boolean('visible_publish').notNullable().defaultTo(true);
|
table.boolean('visible_publish').notNullable().defaultTo(true);
|
||||||
table.integer('left_id').unsigned();
|
|
||||||
table.integer('right_id').unsigned();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,26 +59,3 @@ export default class Collections extends BaseSchema {
|
||||||
// change to normal intzeger:
|
// change to normal intzeger:
|
||||||
// ALTER TABLE collections ALTER COLUMN id DROP DEFAULT;
|
// ALTER TABLE collections ALTER COLUMN id DROP DEFAULT;
|
||||||
// DROP SEQUENCE IF EXISTS collections_id_seq;
|
// DROP SEQUENCE IF EXISTS collections_id_seq;
|
||||||
|
|
||||||
|
|
||||||
// ALTER TABLE collections
|
|
||||||
// ADD COLUMN left_id INTEGER;
|
|
||||||
// COMMENT ON COLUMN collections.left_id IS 'comment';
|
|
||||||
// ALTER TABLE collections
|
|
||||||
// ADD COLUMN right_id INTEGER;
|
|
||||||
// COMMENT ON COLUMN collections.right_id IS 'comment';
|
|
||||||
|
|
||||||
// -- Step 1: Drop the existing default
|
|
||||||
// ALTER TABLE collections
|
|
||||||
// ALTER COLUMN visible DROP DEFAULT,
|
|
||||||
// ALTER COLUMN visible_publish DROP DEFAULT;
|
|
||||||
|
|
||||||
// -- Step 2: Change column types with proper casting
|
|
||||||
// ALTER TABLE collections
|
|
||||||
// ALTER COLUMN visible TYPE smallint USING CASE WHEN visible THEN 1 ELSE 0 END,
|
|
||||||
// ALTER COLUMN visible_publish TYPE smallint USING CASE WHEN visible_publish THEN 1 ELSE 0 END;
|
|
||||||
|
|
||||||
// -- Step 3: Set new defaults as smallint
|
|
||||||
// ALTER TABLE collections
|
|
||||||
// ALTER COLUMN visible SET DEFAULT 1,
|
|
||||||
// ALTER COLUMN visible_publish SET DEFAULT 1;
|
|
1732
package-lock.json
generated
1732
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -97,7 +97,6 @@
|
||||||
"@phc/format": "^1.0.0",
|
"@phc/format": "^1.0.0",
|
||||||
"@poppinss/manager": "^5.0.2",
|
"@poppinss/manager": "^5.0.2",
|
||||||
"@vinejs/vine": "^3.0.0",
|
"@vinejs/vine": "^3.0.0",
|
||||||
"argon2": "^0.43.0",
|
|
||||||
"axios": "^1.7.9",
|
"axios": "^1.7.9",
|
||||||
"bcrypt": "^5.1.1",
|
"bcrypt": "^5.1.1",
|
||||||
"bcryptjs": "^2.4.3",
|
"bcryptjs": "^2.4.3",
|
||||||
|
|
|
@ -108,9 +108,7 @@ const inputElClass = computed(() => {
|
||||||
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 17h-2v-6H5v-2h6V5h2v6h6v2h-6v6z" />
|
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 17h-2v-6H5v-2h6V5h2v6h6v2h-6v6z" />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<!-- <FormCheckRadio v-for="(value, key) in options" :key="key" v-model="computedValue" :type="type"
|
<FormCheckRadio v-for="(value, key) in options" :key="key" v-model="computedValue" :type="type"
|
||||||
:name="name" :input-value="key" :label="value" :class="componentClass" /> -->
|
:name="name" :input-value="Number(key)" :label="value" :class="componentClass" />
|
||||||
<FormCheckRadio v-for="(value, key) in options" :key="key" v-model="computedValue" :type="type"
|
|
||||||
:name="name" :input-value="isNaN(Number(key)) ? key : Number(key)" :label="value" :class="componentClass" />
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, reactive } from 'vue';
|
import { ref, reactive } from 'vue';
|
||||||
import { computed, ComputedRef } from 'vue';
|
import { Head, useForm } from '@inertiajs/vue3';
|
||||||
import { Head, useForm, usePage } from '@inertiajs/vue3';
|
import { mdiAccountKey, mdiArrowLeftBoldOutline, mdiTrashCan, mdiImageText, mdiPlus } from '@mdi/js';
|
||||||
import { mdiAccountKey, mdiArrowLeftBoldOutline, mdiTrashCan, mdiImageText, mdiPlus, mdiAlertBoxOutline } from '@mdi/js';
|
|
||||||
import LayoutAuthenticated from '@/Layouts/LayoutAuthenticated.vue';
|
import LayoutAuthenticated from '@/Layouts/LayoutAuthenticated.vue';
|
||||||
import SectionMain from '@/Components/SectionMain.vue';
|
import SectionMain from '@/Components/SectionMain.vue';
|
||||||
import SectionTitleLineWithButton from '@/Components/SectionTitleLineWithButton.vue';
|
import SectionTitleLineWithButton from '@/Components/SectionTitleLineWithButton.vue';
|
||||||
|
@ -17,7 +16,6 @@ import standardTypes from 'mime/types/standard.js';
|
||||||
import otherTypes from 'mime/types/other.js';
|
import otherTypes from 'mime/types/other.js';
|
||||||
import FormCheckRadioGroup from '@/Components/FormCheckRadioGroup.vue';
|
import FormCheckRadioGroup from '@/Components/FormCheckRadioGroup.vue';
|
||||||
import MimetypeInput from '@/Components/MimetypeInput.vue';
|
import MimetypeInput from '@/Components/MimetypeInput.vue';
|
||||||
import NotificationBar from '@/Components/NotificationBar.vue';
|
|
||||||
|
|
||||||
defineProps({
|
defineProps({
|
||||||
borderless: Boolean,
|
borderless: Boolean,
|
||||||
|
@ -25,10 +23,6 @@ defineProps({
|
||||||
ctrlKFocus: Boolean,
|
ctrlKFocus: Boolean,
|
||||||
});
|
});
|
||||||
|
|
||||||
const flash: ComputedRef<any> = computed(() => {
|
|
||||||
return usePage().props.flash;
|
|
||||||
});
|
|
||||||
|
|
||||||
const customTypes: { [key: string]: string[] } = {
|
const customTypes: { [key: string]: string[] } = {
|
||||||
'application/vnd.opengeospatial.geopackage+sqlite3': ['gpkg'],
|
'application/vnd.opengeospatial.geopackage+sqlite3': ['gpkg'],
|
||||||
'text/plain': ['txt', 'asc', 'c', 'cc', 'h', 'srt'],
|
'text/plain': ['txt', 'asc', 'c', 'cc', 'h', 'srt'],
|
||||||
|
@ -147,13 +141,6 @@ const isValidForm = (): boolean => {
|
||||||
<BaseButton :route-name="stardust.route('settings.mimetype.index')" :icon="mdiArrowLeftBoldOutline"
|
<BaseButton :route-name="stardust.route('settings.mimetype.index')" :icon="mdiArrowLeftBoldOutline"
|
||||||
label="Back" color="white" rounded-full small />
|
label="Back" color="white" rounded-full small />
|
||||||
</SectionTitleLineWithButton>
|
</SectionTitleLineWithButton>
|
||||||
|
|
||||||
<NotificationBar v-if="flash.message" color="success" :icon="mdiAlertBoxOutline">
|
|
||||||
{{ flash.message }}
|
|
||||||
</NotificationBar>
|
|
||||||
<!-- <FormValidationErrors v-bind:errors="errors" /> -->
|
|
||||||
|
|
||||||
|
|
||||||
<CardBox form>
|
<CardBox form>
|
||||||
<MimetypeInput @on-select-result="selectResult" @on-clear-input="clearInput" :transparent="transparent"
|
<MimetypeInput @on-select-result="selectResult" @on-clear-input="clearInput" :transparent="transparent"
|
||||||
:borderless="borderless" :mimeTypes="mimeTypes" :isValidMimeType="isValidMimeType" />
|
:borderless="borderless" :mimeTypes="mimeTypes" :isValidMimeType="isValidMimeType" />
|
||||||
|
|
|
@ -16,6 +16,8 @@ import SectionMain from '@/Components/SectionMain.vue';
|
||||||
import CardBoxWidget from '@/Components/CardBoxWidget.vue';
|
import CardBoxWidget from '@/Components/CardBoxWidget.vue';
|
||||||
import CardBox from '@/Components/CardBox.vue';
|
import CardBox from '@/Components/CardBox.vue';
|
||||||
import TableSampleClients from '@/Components/TableSampleClients.vue';
|
import TableSampleClients from '@/Components/TableSampleClients.vue';
|
||||||
|
// import NotificationBar from '@/Components/NotificationBar.vue';
|
||||||
|
import CardBoxClient from '@/Components/CardBoxClient.vue';
|
||||||
import LayoutAuthenticated from '@/Layouts/LayoutAuthenticated.vue';
|
import LayoutAuthenticated from '@/Layouts/LayoutAuthenticated.vue';
|
||||||
import SectionTitleLineWithButton from '@/Components/SectionTitleLineWithButton.vue';
|
import SectionTitleLineWithButton from '@/Components/SectionTitleLineWithButton.vue';
|
||||||
// import SectionBannerStarOnGitHub from '@/Components/SectionBannerStarOnGitea.vue';
|
// import SectionBannerStarOnGitHub from '@/Components/SectionBannerStarOnGitea.vue';
|
||||||
|
@ -43,12 +45,7 @@ const chartData = computed(() => mainService.graphData);
|
||||||
// const clientBarItems = computed(() => mainService.clients.slice(0, 4));
|
// const clientBarItems = computed(() => mainService.clients.slice(0, 4));
|
||||||
// const transactionBarItems = computed(() => mainService.history);
|
// const transactionBarItems = computed(() => mainService.history);
|
||||||
|
|
||||||
mainService.fetchApi('clients');
|
const authorBarItems = computed(() => mainService.authors.slice(0, 5));
|
||||||
mainService.fetchApi('authors');
|
|
||||||
mainService.fetchApi('datasets');
|
|
||||||
mainService.fetchChartData();
|
|
||||||
|
|
||||||
// const authorBarItems = computed(() => mainService.authors.slice(0, 5));
|
|
||||||
const authors = computed(() => mainService.authors);
|
const authors = computed(() => mainService.authors);
|
||||||
const datasets = computed(() => mainService.datasets);
|
const datasets = computed(() => mainService.datasets);
|
||||||
const datasetBarItems = computed(() => mainService.datasets.slice(0, 5));
|
const datasetBarItems = computed(() => mainService.datasets.slice(0, 5));
|
||||||
|
|
|
@ -36,8 +36,7 @@
|
||||||
'cursor-pointer p-2 border border-gray-200 rounded hover:bg-sky-50 text-sky-700 text-sm': true,
|
'cursor-pointer p-2 border border-gray-200 rounded hover:bg-sky-50 text-sky-700 text-sm': true,
|
||||||
'bg-sky-100 border-sky-500': selectedToplevelCollection && selectedToplevelCollection.id === col.id
|
'bg-sky-100 border-sky-500': selectedToplevelCollection && selectedToplevelCollection.id === col.id
|
||||||
}" @click="onToplevelCollectionSelected(col)">
|
}" @click="onToplevelCollectionSelected(col)">
|
||||||
<span class="text-sky-700">{{ col.name }}</span>
|
{{ `${col.name} (${col.number})` }}
|
||||||
<span class="ml-2 px-2 py-0.5 bg-gray-200 text-gray-700 text-xs rounded-full">{{ col.number }}</span>
|
|
||||||
</li>
|
</li>
|
||||||
<li v-if="collections.length === 0" class="text-gray-800 dark:text-slate-400">
|
<li v-if="collections.length === 0" class="text-gray-800 dark:text-slate-400">
|
||||||
No collections available.
|
No collections available.
|
||||||
|
@ -56,8 +55,7 @@
|
||||||
<template #item="{ element: parent }">
|
<template #item="{ element: parent }">
|
||||||
<li :key="parent.id" :draggable="!parent.inUse" :class="getChildClasses(parent)"
|
<li :key="parent.id" :draggable="!parent.inUse" :class="getChildClasses(parent)"
|
||||||
@click="onCollectionSelected(parent)">
|
@click="onCollectionSelected(parent)">
|
||||||
<span class="text-sky-700">{{ parent.name }}</span>
|
{{ `${parent.name} (${parent.number})` }}
|
||||||
<span class="ml-2 px-2 py-0.5 bg-gray-200 text-gray-700 text-xs rounded-full">{{ parent.number }}</span>
|
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
</draggable>
|
</draggable>
|
||||||
|
@ -81,13 +79,11 @@
|
||||||
'p-2 border border-gray-200 rounded text-sm',
|
'p-2 border border-gray-200 rounded text-sm',
|
||||||
element.inUse ? 'bg-gray-200 text-gray-500 drag-none' : 'bg-green-50 text-green-700 hover:bg-green-100 hover:underline cursor-move'
|
element.inUse ? 'bg-gray-200 text-gray-500 drag-none' : 'bg-green-50 text-green-700 hover:bg-green-100 hover:underline cursor-move'
|
||||||
]">
|
]">
|
||||||
<span class="text-sky-700">{{ element.name }}</span>
|
{{ `${element.name} (${element.number})` }}
|
||||||
<span class="ml-2 px-2 py-0.5 bg-gray-200 text-gray-700 text-xs rounded-full">{{ element.number }}</span>
|
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
</draggable>
|
</draggable>
|
||||||
</CardBox>
|
</CardBox>
|
||||||
|
|
||||||
<!-- Narrower Collections (Children) -->
|
<!-- Narrower Collections (Children) -->
|
||||||
<CardBox v-if="selectedCollection" class="rounded-lg p-4" has-form-data>
|
<CardBox v-if="selectedCollection" class="rounded-lg p-4" has-form-data>
|
||||||
<h2 class="text-lg font-bold text-gray-800 dark:text-slate-400 mb-2">Narrower Collections</h2>
|
<h2 class="text-lg font-bold text-gray-800 dark:text-slate-400 mb-2">Narrower Collections</h2>
|
||||||
|
@ -96,8 +92,7 @@
|
||||||
<template #item="{ element: child }">
|
<template #item="{ element: child }">
|
||||||
<li :key="child.id" :draggable="!child.inUse" :class="getChildClasses(child)"
|
<li :key="child.id" :draggable="!child.inUse" :class="getChildClasses(child)"
|
||||||
@click="onCollectionSelected(child)">
|
@click="onCollectionSelected(child)">
|
||||||
<span class="text-sky-700">{{ child.name }}</span>
|
{{ `${child.name} (${child.number})` }}
|
||||||
<span class="ml-2 px-2 py-0.5 bg-gray-200 text-gray-700 text-xs rounded-full">{{ child.number }}</span>
|
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
</draggable>
|
</draggable>
|
||||||
|
@ -123,8 +118,7 @@
|
||||||
<template #item="{ element }">
|
<template #item="{ element }">
|
||||||
<div :key="element.id"
|
<div :key="element.id"
|
||||||
class="p-2 m-1 bg-sky-200 text-sky-800 rounded flex items-center gap-2 h-7">
|
class="p-2 m-1 bg-sky-200 text-sky-800 rounded flex items-center gap-2 h-7">
|
||||||
<span class="text-sky-700">{{ element.name }}</span>
|
<span>{{ element.name }} ({{ element.number }})</span>
|
||||||
<span class="ml-2 px-2 py-0.5 bg-gray-200 text-gray-700 text-xs rounded-full">{{ element.number }}</span>
|
|
||||||
<button
|
<button
|
||||||
@click="selectedCollectionList = selectedCollectionList.filter(item => item.id !== element.id)"
|
@click="selectedCollectionList = selectedCollectionList.filter(item => item.id !== element.id)"
|
||||||
class="hover:text-sky-600 flex items-center">
|
class="hover:text-sky-600 flex items-center">
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<LayoutAuthenticated>
|
<LayoutAuthenticated>
|
||||||
|
|
||||||
<Head title="Classify"></Head>
|
<Head title="Classify"></Head>
|
||||||
<SectionMain>
|
<SectionMain>
|
||||||
<SectionTitleLineWithButton :icon="mdiLibraryShelves" title="Library Classification" main>
|
<SectionTitleLineWithButton :icon="mdiLibraryShelves" title="Library Classification" main>
|
||||||
|
@ -34,30 +33,29 @@
|
||||||
</h2>
|
</h2>
|
||||||
<ul class="flex flex-wrap gap-2">
|
<ul class="flex flex-wrap gap-2">
|
||||||
<li v-for="col in collections" :key="col.id" :class="{
|
<li v-for="col in collections" :key="col.id" :class="{
|
||||||
'cursor-pointer p-2 border border-gray-200 rounded hover:bg-sky-50 flex items-center': true,
|
'cursor-pointer p-2 border border-gray-200 rounded hover:bg-sky-50 text-sky-700 text-sm': true,
|
||||||
'bg-sky-100 border-sky-500': selectedToplevelCollection && selectedToplevelCollection.id === col.id
|
'bg-sky-100 border-sky-500': selectedToplevelCollection && selectedToplevelCollection.id === col.id
|
||||||
}" @click="onToplevelCollectionSelected(col)">
|
}" @click="onToplevelCollectionSelected(col)">
|
||||||
<span class="text-sky-700">{{ col.name }}</span>
|
{{ `${col.name} (${col.number})` }}
|
||||||
<span class="ml-2 px-2 py-0.5 bg-gray-200 text-gray-700 text-xs rounded-full">{{ col.number }}</span>
|
|
||||||
</li>
|
</li>
|
||||||
<li v-if="collections.length === 0" class="text-gray-800 dark:text-slate-400">
|
<li v-if="collections.length === 0" class="text-gray-800 dark:text-slate-400">
|
||||||
No collections available.
|
No collections available.
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</CardBox>
|
</CardBox>
|
||||||
|
|
||||||
<!-- Collections Listing -->
|
<!-- Collections Listing -->
|
||||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-4">
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-4">
|
||||||
|
|
||||||
<!-- Broader Collection (Parent) -->
|
<!-- Broader Collection (Parent) -->
|
||||||
<CardBox v-if="selectedCollection" class="rounded-lg p-4" has-form-data>
|
<CardBox v-if="selectedCollection" class="rounded-lg p-4" has-form-data>
|
||||||
<h2 class="text-lg font-bold text-gray-800 dark:text-slate-400 mb-2">Broader Collection</h2>
|
<h2 class="text-lg font-bold text-gray-800 dark:text-slate-400 mb-2">Broader Collection</h2>
|
||||||
<draggable v-if="broaderCollections.length > 0" v-model="broaderCollections"
|
<draggable v-if="broaderCollections.length > 0" v-model="broaderCollections"
|
||||||
:group="{ name: 'collections' }" tag="ul" class="flex flex-wrap gap-2 max-h-60 overflow-y-auto">
|
:group="{ name: 'collections' }" tag="ul" class="flex flex-wrap gap-2 max-h-60 overflow-y-auto">
|
||||||
<template #item="{ element: parent }">
|
<template #item="{ element: parent }">
|
||||||
<li :key="parent.id" :draggable="!parent.inUse" :class="getChildClasses(parent)"
|
<li :key="parent.id" :draggable="!parent.inUse" :class="getChildClasses(parent)"
|
||||||
@click="onCollectionSelected(parent)">
|
@click="onCollectionSelected(parent)">
|
||||||
<span class="text-sky-700">{{ parent.name }}</span>
|
{{ `${parent.name} (${parent.number})` }}
|
||||||
<span class="ml-2 px-2 py-0.5 bg-gray-200 text-gray-700 text-xs rounded-full">{{ parent.number }}</span>
|
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
</draggable>
|
</draggable>
|
||||||
|
@ -71,35 +69,30 @@
|
||||||
<!-- Selected Collection Details -->
|
<!-- Selected Collection Details -->
|
||||||
<CardBox v-if="selectedCollection" class="rounded-lg p-4" has-form-data>
|
<CardBox v-if="selectedCollection" class="rounded-lg p-4" has-form-data>
|
||||||
<h3 class="text-xl font-bold text-gray-800 dark:text-slate-400 mb-2">Selected Collection</h3>
|
<h3 class="text-xl font-bold text-gray-800 dark:text-slate-400 mb-2">Selected Collection</h3>
|
||||||
<!-- <p :class="[
|
<!-- <p :class="[
|
||||||
'cursor-pointer p-2 border border-gray-200 rounded text-sm',
|
'cursor-pointer p-2 border border-gray-200 rounded text-sm',
|
||||||
selectedCollection.inUse ? 'bg-gray-200 text-gray-500 drag-none' : 'bg-green-50 text-green-700 hover:bg-green-100 hover:underline cursor-move'
|
selectedCollection.inUse ? 'bg-gray-200 text-gray-500 drag-none' : 'bg-green-50 text-green-700 hover:bg-green-100 hover:underline cursor-move'
|
||||||
]"></p> -->
|
]"></p> -->
|
||||||
<draggable v-model="selectedCollectionArray"
|
<draggable v-model="selectedCollectionArray" :group="{ name: 'collections', pull: 'clone', put: false }" tag="ul" class="flex flex-wrap gap-2 max-h-60 overflow-y-auto">
|
||||||
:group="{ name: 'collections', pull: 'clone', put: false }" tag="ul"
|
|
||||||
class="flex flex-wrap gap-2 max-h-60 overflow-y-auto">
|
|
||||||
<template #item="{ element }">
|
<template #item="{ element }">
|
||||||
<li :key="element.id" :class="[
|
<li :key="element.id" :class="[
|
||||||
'p-2 border border-gray-200 rounded text-sm',
|
'p-2 border border-gray-200 rounded text-sm',
|
||||||
element.inUse ? 'bg-gray-200 text-gray-500 drag-none' : 'bg-green-50 text-green-700 hover:bg-green-100 hover:underline cursor-move'
|
element.inUse ? 'bg-gray-200 text-gray-500 drag-none' : 'bg-green-50 text-green-700 hover:bg-green-100 hover:underline cursor-move'
|
||||||
]">
|
]">
|
||||||
<span class="text-sky-700">{{ element.name }}</span>
|
{{ `${element.name} (${element.number})` }}
|
||||||
<span class="ml-2 px-2 py-0.5 bg-gray-200 text-gray-700 text-xs rounded-full">{{ element.number }}</span>
|
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
</draggable>
|
</draggable>
|
||||||
</CardBox>
|
</CardBox>
|
||||||
|
|
||||||
<!-- Narrower Collections (Children) -->
|
<!-- Narrower Collections (Children) -->
|
||||||
<CardBox v-if="selectedCollection" class="rounded-lg p-4" has-form-data>
|
<CardBox v-if="selectedCollection" class="rounded-lg p-4" has-form-data>
|
||||||
<h2 class="text-lg font-bold text-gray-800 dark:text-slate-400 mb-2">Narrower Collections</h2>
|
<h2 class="text-lg font-bold text-gray-800 dark:text-slate-400 mb-2">Narrower Collections</h2>
|
||||||
<draggable v-if="narrowerCollections.length > 0" v-model="narrowerCollections"
|
<draggable v-if="narrowerCollections.length > 0" v-model="narrowerCollections"
|
||||||
:group="{ name: 'collections' }" tag="ul" class="flex flex-wrap gap-2 max-h-60 overflow-y-auto">
|
:group="{ name: 'collections' }" tag="ul" class="flex flex-wrap gap-2 max-h-60 overflow-y-auto">
|
||||||
<template #item="{ element: child }">
|
<template #item="{ element: child }">
|
||||||
<li :key="child.id" :draggable="!child.inUse" :class="getChildClasses(child)"
|
<li :key="child.id" :draggable="!child.inUse" :class="getChildClasses(child)"
|
||||||
@click="onCollectionSelected(child)">
|
@click="onCollectionSelected(child)">
|
||||||
<span class="text-sky-700">{{ child.name }}</span>
|
{{ `${child.name} (${child.number})` }}
|
||||||
<span class="ml-2 px-2 py-0.5 bg-gray-200 text-gray-700 text-xs rounded-full">{{ child.number }}</span>
|
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
</draggable>
|
</draggable>
|
||||||
|
@ -113,21 +106,19 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-4 rounded-lg">
|
<div class="mb-4 rounded-lg">
|
||||||
<div v-if="selectedCollection || selectedCollectionList.length > 0"
|
<div v-if="selectedCollection || selectedCollectionList.length > 0" class="bg-gray-100 shadow rounded-lg p-6 mb-6" :class="{ 'opacity-50': selectedCollection && selectedCollectionList.length === 0 }">
|
||||||
class="bg-gray-100 shadow rounded-lg p-6 mb-6"
|
|
||||||
:class="{ 'opacity-50': selectedCollection && selectedCollectionList.length === 0 }">
|
|
||||||
<p class="mb-4 text-gray-700">Please drag your collections here to classify your previously created
|
<p class="mb-4 text-gray-700">Please drag your collections here to classify your previously created
|
||||||
dataset
|
dataset
|
||||||
according to library classification standards.</p>
|
according to library classification standards.</p>
|
||||||
<draggable v-model="selectedCollectionList" :group="{ name: 'collections' }"
|
<draggable v-model="selectedCollectionList" :group="{ name: 'collections' }"
|
||||||
class="min-h-36 border-dashed border-2 border-gray-400 p-4 text-sm flex flex-wrap gap-2 max-h-60 overflow-y-auto"
|
class="min-h-36 border-dashed border-2 border-gray-400 p-4 text-sm flex flex-wrap gap-2 max-h-60 overflow-y-auto"
|
||||||
tag="ul" :disabled="selectedCollection === null && selectedCollectionList.length > 0"
|
tag="ul"
|
||||||
|
:disabled="selectedCollection === null && selectedCollectionList.length > 0"
|
||||||
:style="{ opacity: (selectedCollection === null && selectedCollectionList.length > 0) ? 0.5 : 1, pointerEvents: (selectedCollection === null && selectedCollectionList.length > 0) ? 'none' : 'auto' }">
|
:style="{ opacity: (selectedCollection === null && selectedCollectionList.length > 0) ? 0.5 : 1, pointerEvents: (selectedCollection === null && selectedCollectionList.length > 0) ? 'none' : 'auto' }">
|
||||||
<template #item="{ element }">
|
<template #item="{ element }">
|
||||||
<div :key="element.id"
|
<div :key="element.id"
|
||||||
class="p-2 m-1 bg-sky-200 text-sky-800 rounded flex items-center gap-2 h-7">
|
class="p-2 m-1 bg-sky-200 text-sky-800 rounded flex items-center gap-2 h-7">
|
||||||
<span class="text-sky-700">{{ element.name }}</span>
|
<span>{{ element.name }} ({{ element.number }})</span>
|
||||||
<span class="ml-2 px-2 py-0.5 bg-gray-200 text-gray-700 text-xs rounded-full">{{ element.number }}</span>
|
|
||||||
<button
|
<button
|
||||||
@click="selectedCollectionList = selectedCollectionList.filter(item => item.id !== element.id)"
|
@click="selectedCollectionList = selectedCollectionList.filter(item => item.id !== element.id)"
|
||||||
class="hover:text-sky-600 flex items-center">
|
class="hover:text-sky-600 flex items-center">
|
||||||
|
@ -140,7 +131,7 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</draggable>
|
</draggable>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="p-6 border-t border-gray-100 dark:border-slate-800">
|
<div class="p-6 border-t border-gray-100 dark:border-slate-800">
|
||||||
|
@ -208,10 +199,10 @@ const selectedCollectionList: Ref<Collection[]> = ref<Collection[]>([]);
|
||||||
|
|
||||||
// Wrap selectedCollection in an array for draggable (always expects an array)
|
// Wrap selectedCollection in an array for draggable (always expects an array)
|
||||||
const selectedCollectionArray = computed({
|
const selectedCollectionArray = computed({
|
||||||
get: () => (selectedCollection.value ? [selectedCollection.value] : []),
|
get: () => (selectedCollection.value ? [selectedCollection.value] : []),
|
||||||
set: (value: Collection[]) => {
|
set: (value: Collection[]) => {
|
||||||
selectedCollection.value = value.length ? value[0] : null
|
selectedCollection.value = value.length ? value[0] : null
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ -308,7 +299,7 @@ const fetchCollections = async (collectionId: number) => {
|
||||||
selectedCollection.value = { ...selectedCollection.value, inUse: true };
|
selectedCollection.value = { ...selectedCollection.value, inUse: true };
|
||||||
} else if (selectedCollection.value) {
|
} else if (selectedCollection.value) {
|
||||||
selectedCollection.value = { ...selectedCollection.value, inUse: false };
|
selectedCollection.value = { ...selectedCollection.value, inUse: false };
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in fetchCollections:', error);
|
console.error('Error in fetchCollections:', error);
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,7 @@ const layoutService = LayoutService(pinia);
|
||||||
const localeService = LocaleStore(pinia);
|
const localeService = LocaleStore(pinia);
|
||||||
|
|
||||||
localeService.initializeLocale();
|
localeService.initializeLocale();
|
||||||
// const mainService = MainService(pinia);
|
const mainService = MainService(pinia);
|
||||||
// mainService.setUser(user);
|
// mainService.setUser(user);
|
||||||
|
|
||||||
/* App style */
|
/* App style */
|
||||||
|
@ -91,11 +91,12 @@ styleService.setStyle(localStorage[styleKey] ?? 'basic');
|
||||||
if ((!localStorage[darkModeKey] && window.matchMedia('(prefers-color-scheme: dark)').matches) || localStorage[darkModeKey] === '1') {
|
if ((!localStorage[darkModeKey] && window.matchMedia('(prefers-color-scheme: dark)').matches) || localStorage[darkModeKey] === '1') {
|
||||||
styleService.setDarkMode(true);
|
styleService.setDarkMode(true);
|
||||||
}
|
}
|
||||||
|
// mainService.fetch('clients');
|
||||||
// mainService.fetchApi('clients');
|
// mainService.fetch('history');
|
||||||
// mainService.fetchApi('authors');
|
mainService.fetchApi('clients');
|
||||||
// mainService.fetchApi('datasets');
|
mainService.fetchApi('authors');
|
||||||
// mainService.fetchChartData();
|
mainService.fetchApi('datasets');
|
||||||
|
mainService.fetchChartData();
|
||||||
|
|
||||||
/* Collapse mobile aside menu on route change */
|
/* Collapse mobile aside menu on route change */
|
||||||
Inertia.on('navigate', () => {
|
Inertia.on('navigate', () => {
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<meta name="msapplication-TileColor" content="#da532c">
|
<meta name="msapplication-TileColor" content="#da532c">
|
||||||
<meta name="theme-color" content="#ffffff">
|
<meta name="theme-color" content="#ffffff">
|
||||||
|
|
||||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
<link rel="icon" type="image/svg+xml" href="favicon.svg">
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
||||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
||||||
|
|
|
@ -11,8 +11,8 @@ import { middleware } from '../kernel.js';
|
||||||
// API
|
// API
|
||||||
router
|
router
|
||||||
.group(() => {
|
.group(() => {
|
||||||
router.get('clients', [UserController, 'getSubmitters']).as('client.index').use(middleware.auth());;
|
router.get('clients', [UserController, 'getSubmitters']).as('client.index');
|
||||||
router.get('authors', [AuthorsController, 'index']).as('author.index').use(middleware.auth());;
|
router.get('authors', [AuthorsController, 'index']).as('author.index');
|
||||||
router.get('datasets', [DatasetController, 'index']).as('dataset.index');
|
router.get('datasets', [DatasetController, 'index']).as('dataset.index');
|
||||||
router.get('persons', [AuthorsController, 'persons']).as('author.persons');
|
router.get('persons', [AuthorsController, 'persons']).as('author.persons');
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ router
|
||||||
router.get('/years', [HomeController, 'findYears']);
|
router.get('/years', [HomeController, 'findYears']);
|
||||||
router.get('/statistic', [HomeController, 'findPublicationsPerMonth']);
|
router.get('/statistic', [HomeController, 'findPublicationsPerMonth']);
|
||||||
|
|
||||||
router.get('/file/download/:id', [FileController, 'findOne']).as('file.findOne');
|
router.get('/download/:id', [FileController, 'findOne']).as('file.findOne');
|
||||||
|
|
||||||
router.get('/avatar/:name/:background?/:textColor?/:size?', [AvatarController, 'generateAvatar']);
|
router.get('/avatar/:name/:background?/:textColor?/:size?', [AvatarController, 'generateAvatar']);
|
||||||
|
|
||||||
|
|
Loading…
Add table
editor.link_modal.header
Reference in a new issue