Compare commits
No commits in common. "0d259b6464e7d2f439b2d9345c248ce4344b128c" and "b540547e4cd98ce8296f58689dbf40141a75d954" have entirely different histories.
0d259b6464
...
b540547e4c
9 changed files with 455 additions and 533 deletions
|
@ -1047,10 +1047,10 @@ export default class DatasetController {
|
||||||
// name: fileName,
|
// name: fileName,
|
||||||
// overwrite: true, // overwrite in case of conflict
|
// overwrite: true, // overwrite in case of conflict
|
||||||
// });
|
// });
|
||||||
await fileData.moveToDisk(datasetFullPath, 'local', {
|
await fileData.moveToDisk(datasetFullPath, {
|
||||||
name: fileName,
|
name: fileName,
|
||||||
overwrite: true, // overwrite in case of conflict
|
overwrite: true, // overwrite in case of conflict
|
||||||
disk: 'local',
|
driver: 'local',
|
||||||
});
|
});
|
||||||
|
|
||||||
//save to db:
|
//save to db:
|
||||||
|
@ -1248,51 +1248,4 @@ export default class DatasetController {
|
||||||
relatedCollections: dataset.collections,
|
relatedCollections: dataset.collections,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async categorizeUpdate({ request, response, session }: HttpContext) {
|
|
||||||
// Get the dataset id from the route parameter
|
|
||||||
const id = request.param('id');
|
|
||||||
const dataset = await Dataset.query().preload('files').where('id', id).firstOrFail();
|
|
||||||
|
|
||||||
const validStates = ['inprogress', 'rejected_editor'];
|
|
||||||
if (!validStates.includes(dataset.server_state)) {
|
|
||||||
return response
|
|
||||||
.flash(
|
|
||||||
'warning',
|
|
||||||
`Invalid server state. Dataset with id ${id} cannot be categorized. Dataset has server state ${dataset.server_state}.`,
|
|
||||||
)
|
|
||||||
.redirect()
|
|
||||||
.toRoute('dataset.list');
|
|
||||||
}
|
|
||||||
|
|
||||||
let trx: TransactionClientContract | null = null;
|
|
||||||
try {
|
|
||||||
trx = await db.transaction();
|
|
||||||
// const user = (await User.find(auth.user?.id)) as User;
|
|
||||||
// await this.createDatasetAndAssociations(user, request, trx);
|
|
||||||
|
|
||||||
// Retrieve the selected collections from the request.
|
|
||||||
// This should be an array of collection ids.
|
|
||||||
const collections: number[] = request.input('collections', []);
|
|
||||||
|
|
||||||
// Synchronize the dataset collections using the transaction.
|
|
||||||
await dataset.useTransaction(trx).related('collections').sync(collections);
|
|
||||||
|
|
||||||
// Commit the transaction.await trx.commit()
|
|
||||||
await trx.commit();
|
|
||||||
|
|
||||||
// Redirect with a success flash message.
|
|
||||||
// return response.flash('success', 'Dataset collections updated successfully!').redirect().toRoute('dataset.list');
|
|
||||||
|
|
||||||
session.flash('message', 'Dataset collections updated successfully!');
|
|
||||||
return response.redirect().toRoute('dataset.list');
|
|
||||||
} catch (error) {
|
|
||||||
if (trx !== null) {
|
|
||||||
await trx.rollback();
|
|
||||||
}
|
|
||||||
console.error('Failed tocatgorize dataset collections:', error);
|
|
||||||
// throw new ValidationException(true, { 'upload error': `failed to create dataset and related models. ${error}` });
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
678
package-lock.json
generated
678
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -39,7 +39,7 @@
|
||||||
"@types/clamscan": "^2.0.4",
|
"@types/clamscan": "^2.0.4",
|
||||||
"@types/escape-html": "^1.0.4",
|
"@types/escape-html": "^1.0.4",
|
||||||
"@types/fs-extra": "^11.0.4",
|
"@types/fs-extra": "^11.0.4",
|
||||||
"@types/leaflet": "^1.9.16",
|
"@types/leaflet": "^1.9.3",
|
||||||
"@types/luxon": "^3.4.2",
|
"@types/luxon": "^3.4.2",
|
||||||
"@types/node": "^22.10.2",
|
"@types/node": "^22.10.2",
|
||||||
"@types/proxy-addr": "^2.0.0",
|
"@types/proxy-addr": "^2.0.0",
|
||||||
|
|
|
@ -109,9 +109,6 @@
|
||||||
--radius: 15;
|
--radius: 15;
|
||||||
--pi: 3.14159265358979;
|
--pi: 3.14159265358979;
|
||||||
}
|
}
|
||||||
.leaflet-container .leaflet-pane {
|
|
||||||
z-index: 30!important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* @layer base {
|
/* @layer base {
|
||||||
html,
|
html,
|
||||||
|
|
|
@ -282,7 +282,7 @@ const handleDrawEventCreated = async (event) => {
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<style scoped lang="css">
|
<style lang="css">
|
||||||
/* .leaflet-container {
|
/* .leaflet-container {
|
||||||
height: 600px;
|
height: 600px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<LayoutAuthenticated>
|
<LayoutAuthenticated>
|
||||||
<Head title="Collections"></Head>
|
|
||||||
|
<Head title="Profile"></Head>
|
||||||
<SectionMain>
|
<SectionMain>
|
||||||
<SectionTitleLineWithButton :icon="mdiLibraryShelves" title="Library Classification" main>
|
<SectionTitleLineWithButton :icon="mdiLibraryShelves" title="Library Classification" main>
|
||||||
<div class="bg-lime-100 shadow rounded-lg p-6 mb-6 flex items-center justify-between">
|
<div class="bg-lime-100 shadow rounded-lg p-6 mb-6 flex items-center justify-between">
|
||||||
|
@ -50,17 +51,13 @@
|
||||||
<!-- 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"
|
<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">
|
<li v-for="parent in broaderCollections" :key="parent.id"
|
||||||
<template #item="{ element: parent }">
|
class="cursor-pointer p-2 border border-gray-200 rounded bg-green-50 text-green-700 text-sm hover:bg-green-100 hover:underline"
|
||||||
<li :key="parent.id" :draggable="!parent.inUse" :class="getChildClasses(parent)"
|
@click="onCollectionSelected(parent)" title="Click to select this collection">
|
||||||
@click="onCollectionSelected(parent)">
|
{{ `${parent.name} (${parent.number})` }}
|
||||||
{{ `${parent.name} (${parent.number})` }}
|
</li>
|
||||||
</li>
|
<li v-if="broaderCollections.length === 0" class="text-gray-500 text-sm">
|
||||||
</template>
|
|
||||||
</draggable>
|
|
||||||
<ul v-else class="flex flex-wrap gap-2 max-h-60 overflow-y-auto">
|
|
||||||
<li class="text-gray-500 text-sm">
|
|
||||||
No broader collections available.
|
No broader collections available.
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -69,10 +66,8 @@
|
||||||
<!-- 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
|
||||||
'cursor-pointer p-2 border border-gray-200 rounded text-sm',
|
class="cursor-pointer p-2 border border-gray-200 rounded bg-green-50 text-green-700 text-sm hover:bg-green-100">
|
||||||
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.name} (${selectedCollection.number})` }}
|
{{ `${selectedCollection.name} (${selectedCollection.number})` }}
|
||||||
</p>
|
</p>
|
||||||
</CardBox>
|
</CardBox>
|
||||||
|
@ -80,10 +75,21 @@
|
||||||
<!-- 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>
|
||||||
|
<!-- <ul class="flex flex-wrap gap-2 max-h-60 overflow-y-auto">
|
||||||
|
<li v-for="child in narrowerCollections" :key="child.id"
|
||||||
|
class="cursor-pointer p-2 border border-gray-200 rounded bg-green-50 text-green-700 text-sm hover:bg-green-100 hover:underline"
|
||||||
|
@click="onCollectionSelected(child)">
|
||||||
|
{{ `${child.name} (${child.number})` }}
|
||||||
|
</li>
|
||||||
|
<li v-if="narrowerCollections.length === 0" class="text-gray-500 text-sm">
|
||||||
|
No sub-collections available.
|
||||||
|
</li>
|
||||||
|
</ul> -->
|
||||||
<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"
|
||||||
|
class="cursor-pointer p-2 border border-gray-200 rounded bg-green-50 text-green-700 text-sm hover:bg-green-100 hover:underline"
|
||||||
@click="onCollectionSelected(child)">
|
@click="onCollectionSelected(child)">
|
||||||
{{ `${child.name} (${child.number})` }}
|
{{ `${child.name} (${child.number})` }}
|
||||||
</li>
|
</li>
|
||||||
|
@ -99,21 +105,19 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-4 rounded-lg">
|
<div class="mb-4 rounded-lg">
|
||||||
<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 }">
|
<div v-if="selectedCollection" class="bg-gray-100 shadow rounded-lg p-6 mb-6">
|
||||||
<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="dropCollections" :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"
|
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' }">
|
|
||||||
<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>{{ element.name }} ({{ element.number }})</span>
|
<span>{{ element.name }} ({{ element.number }})</span>
|
||||||
<button
|
<button
|
||||||
@click="selectedCollectionList = selectedCollectionList.filter(item => item.id !== element.id)"
|
@click="dropCollections = dropCollections.filter(item => item.id !== element.id)"
|
||||||
class="hover:text-sky-600 flex items-center">
|
class="hover:text-sky-600 flex items-center">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 20 20"
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 20 20"
|
||||||
fill="currentColor">
|
fill="currentColor">
|
||||||
|
@ -127,6 +131,7 @@
|
||||||
</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">
|
||||||
<BaseButtons>
|
<BaseButtons>
|
||||||
<BaseButton @click.stop="syncDatasetCollections" label="Save" color="info" small
|
<BaseButton @click.stop="syncDatasetCollections" label="Save" color="info" small
|
||||||
|
@ -134,13 +139,17 @@
|
||||||
</BaseButton>
|
</BaseButton>
|
||||||
</BaseButtons>
|
</BaseButtons>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</SectionMain>
|
</SectionMain>
|
||||||
</LayoutAuthenticated>
|
</LayoutAuthenticated>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script lang="ts" setup>
|
||||||
import { ref, Ref, watch, computed } from 'vue';
|
import { ref, Ref, watch, computed } from 'vue';
|
||||||
import { useForm } from '@inertiajs/vue3';
|
|
||||||
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';
|
||||||
|
@ -150,19 +159,20 @@ import draggable from 'vuedraggable';
|
||||||
import BaseButton from '@/Components/BaseButton.vue';
|
import BaseButton from '@/Components/BaseButton.vue';
|
||||||
import BaseButtons from '@/Components/BaseButtons.vue';
|
import BaseButtons from '@/Components/BaseButtons.vue';
|
||||||
import CardBox from '@/Components/CardBox.vue';
|
import CardBox from '@/Components/CardBox.vue';
|
||||||
import { stardust } from '@eidellev/adonis-stardust/client';
|
|
||||||
import { CollectionRole, Collection } from '@/types/models';
|
|
||||||
|
|
||||||
// import CollectionRoleSelector from '@/Components/Collection/CollectionRoleSelector.vue';
|
interface CollectionRole {
|
||||||
// import ToplevelCollections from '@/Components/Collection/ToplevelCollections.vue';
|
id: number;
|
||||||
// import CollectionHierarchy from '@/Components/Collection/CollectionHierarchy.vue';
|
name: string;
|
||||||
// import CollectionDropZone from '@/Components/Collection/CollectionDropZone.vue';
|
collections?: any[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Collection {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
number: string;
|
||||||
|
parent_id?: number | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------
|
|
||||||
Props & Reactive State
|
|
||||||
-------------------------------------------------------------------------- */
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
collectionRoles: {
|
collectionRoles: {
|
||||||
type: Array,
|
type: Array,
|
||||||
|
@ -173,10 +183,7 @@ const props = defineProps({
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({}),
|
default: () => ({}),
|
||||||
},
|
},
|
||||||
relatedCollections: {
|
relatedCollections: Array<Collection>
|
||||||
type: Array as () => Collection[],
|
|
||||||
default: () => [] as const
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const collectionRoles: Ref<CollectionRole[]> = ref(props.collectionRoles as CollectionRole[]);
|
const collectionRoles: Ref<CollectionRole[]> = ref(props.collectionRoles as CollectionRole[]);
|
||||||
|
@ -186,28 +193,34 @@ const selectedToplevelCollection = ref<Collection | null>(null);
|
||||||
const selectedCollection = ref<Collection | null>(null);
|
const selectedCollection = ref<Collection | null>(null);
|
||||||
const narrowerCollections = ref<Collection[]>([]);
|
const narrowerCollections = ref<Collection[]>([]);
|
||||||
const broaderCollections = ref<Collection[]>([]);
|
const broaderCollections = ref<Collection[]>([]);
|
||||||
// Reactive list that holds collections dropped by the user
|
|
||||||
const selectedCollectionList: Ref<Collection[]> = ref<Collection[]>([]);
|
|
||||||
|
|
||||||
const form = useForm({
|
|
||||||
collections: [] as number[],
|
|
||||||
});
|
|
||||||
|
|
||||||
// Watch for changes in dropCollections
|
|
||||||
watch(
|
|
||||||
() => selectedCollectionList.value,
|
|
||||||
() => {
|
|
||||||
if (selectedCollection.value) {
|
|
||||||
fetchCollections(selectedCollection.value.id);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ deep: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------
|
// const onCollectionRoleSelected = (event: Event) => {
|
||||||
Watchers and Initial Setup
|
// const target = event.target as HTMLSelectElement;
|
||||||
-------------------------------------------------------------------------- */
|
// const roleId = Number(target.value);
|
||||||
|
// selectedCollectionRole.value =
|
||||||
|
// collectionRoles.value.find((role: CollectionRole) => role.id === roleId) || null;
|
||||||
|
|
||||||
|
// // Clear any previously selected collection or related data
|
||||||
|
// selectedCollection.value = null;
|
||||||
|
// narrowerCollections.value = [];
|
||||||
|
// broaderCollections.value = [];
|
||||||
|
|
||||||
|
// // fetchTopLevelCollections(roleId);
|
||||||
|
// collections.value = selectedCollectionRole.value?.collections || []
|
||||||
|
// };
|
||||||
|
|
||||||
|
// New reactive array to hold dropped collections for the dataset
|
||||||
|
const dropCollections: Ref<Collection[]> = ref([]);
|
||||||
|
|
||||||
|
// If there are related collections passed in, fill dropCollections with these.
|
||||||
|
if (props.relatedCollections && props.relatedCollections.length > 0) {
|
||||||
|
dropCollections.value = props.relatedCollections;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a computed property for the disabled state based on dropCollections length
|
||||||
|
const isSaveDisabled = computed(() => dropCollections.value.length === 0);
|
||||||
|
|
||||||
// If the collectionRoles prop might load asynchronously (or change), you can watch for it:
|
// If the collectionRoles prop might load asynchronously (or change), you can watch for it:
|
||||||
watch(
|
watch(
|
||||||
() => props.collectionRoles as CollectionRole[],
|
() => props.collectionRoles as CollectionRole[],
|
||||||
|
@ -223,8 +236,7 @@ watch(
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
|
// Watch for changes in selectedCollectionRole and update related collections state
|
||||||
// When collection role changes, update available collections and clear dependent state.
|
|
||||||
watch(
|
watch(
|
||||||
() => selectedCollectionRole.value as CollectionRole,
|
() => selectedCollectionRole.value as CollectionRole,
|
||||||
(newSelectedCollectionRole: CollectionRole | null) => {
|
(newSelectedCollectionRole: CollectionRole | null) => {
|
||||||
|
@ -241,77 +253,60 @@ watch(
|
||||||
broaderCollections.value = []
|
broaderCollections.value = []
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
// Watch for changes in dropCollections
|
||||||
|
watch(
|
||||||
|
() => dropCollections.value,
|
||||||
|
() => {
|
||||||
|
if (selectedCollection.value) {
|
||||||
|
fetchCollections(selectedCollection.value.id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------
|
|
||||||
Methods
|
|
||||||
-------------------------------------------------------------------------- */
|
|
||||||
const onToplevelCollectionSelected = (collection: Collection) => {
|
const onToplevelCollectionSelected = (collection: Collection) => {
|
||||||
selectedToplevelCollection.value = collection;
|
selectedToplevelCollection.value = collection;
|
||||||
selectedCollection.value = collection;
|
selectedCollection.value = collection;
|
||||||
// call the API endpoint to get both.
|
// call the API endpoint to get both.
|
||||||
fetchCollections(collection.id);
|
fetchCollections(collection.id)
|
||||||
};
|
};
|
||||||
|
|
||||||
const onCollectionSelected = (collection: Collection) => {
|
const onCollectionSelected = (collection: Collection) => {
|
||||||
selectedCollection.value = collection;
|
selectedCollection.value = collection;
|
||||||
// call the API endpoint to get both.
|
// call the API endpoint to get both.
|
||||||
fetchCollections(collection.id);
|
fetchCollections(collection.id)
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// New function to load both narrower and broader concepts using the real API route.
|
||||||
* fetchCollections: Retrieves broader and narrower collections.
|
|
||||||
* Marks any narrower collection as inUse if it appears in selectedCollectionList.
|
|
||||||
*/
|
|
||||||
const fetchCollections = async (collectionId: number) => {
|
const fetchCollections = async (collectionId: number) => {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get(`/api/collections/${collectionId}`);
|
const response = await axios.get(`/api/collections/${collectionId}`);
|
||||||
const data = response.data;
|
const data = response.data;
|
||||||
// Map each returned narrower collection
|
|
||||||
narrowerCollections.value = data.narrowerCollections.map((collection: Collection) => {
|
// Set narrower concepts with filtered collections
|
||||||
// If found, mark it as inUse.
|
narrowerCollections.value = data.narrowerCollections.filter(
|
||||||
const alreadyDropped = selectedCollectionList.value.find(dc => dc.id === collection.id);
|
collection => !dropCollections.value.some(dc => dc.id === collection.id)
|
||||||
return alreadyDropped ? { ...collection, inUse: true } : { ...collection, inUse: false };
|
);
|
||||||
});
|
// For broader concepts, if present, wrap it in an array (or change your template accordingly)
|
||||||
broaderCollections.value = data.broaderCollection.map((collection: Collection) => {
|
broaderCollections.value = data.broaderCollection;
|
||||||
const alreadyDropped = selectedCollectionList.value.find(dc => dc.id === collection.id);
|
|
||||||
return alreadyDropped ? { ...collection, inUse: true } : { ...collection, inUse: false };
|
|
||||||
});
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in fetchCollections:', error);
|
console.error('Error in fetchConcepts:', error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const syncDatasetCollections = async () => {
|
const syncDatasetCollections = async () => {
|
||||||
// Extract the ids from the dropCollections list
|
try {
|
||||||
form.collections = selectedCollectionList.value.map((item: Collection) => item.id);
|
// Extract the ids from the dropCollections list
|
||||||
form.put(stardust.route('dataset.categorizeUpdate', [props.dataset.id]), {
|
const collectionIds = dropCollections.value.map(item => item.id);
|
||||||
preserveState: true,
|
await axios.post('/api/dataset/collections/sync', { collections: collectionIds });
|
||||||
onSuccess: () => {
|
// Optionally show a success message or refresh dataset info
|
||||||
console.log('Dataset collections synced successfully');
|
} catch (error) {
|
||||||
},
|
console.error('Error syncing dataset collections:', error);
|
||||||
onError: (errors) => {
|
}
|
||||||
console.error('Error syncing dataset collections:', errors);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* getChildClasses returns the Tailwind CSS classes to apply to each collection list item.
|
|
||||||
*/
|
|
||||||
const getChildClasses = (child: Collection) => {
|
|
||||||
return child.inUse
|
|
||||||
? 'p-2 border border-gray-200 rounded bg-gray-200 text-gray-500 cursor-pointer drag-none'
|
|
||||||
: 'p-2 border border-gray-200 rounded bg-green-50 text-green-700 cursor-move hover:bg-green-100 hover:underline'
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there are related collections passed in, fill dropCollections with these.
|
|
||||||
if (props.relatedCollections && props.relatedCollections.length > 0) {
|
|
||||||
selectedCollectionList.value = props.relatedCollections;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add a computed property for the disabled state based on dropCollections length
|
|
||||||
const isSaveDisabled = computed(() => selectedCollectionList.value.length === 0);
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
/* --------------------------------------------------------------------------
|
|
||||||
Types and Interfaces
|
|
||||||
-------------------------------------------------------------------------- */
|
|
||||||
export interface Collection {
|
|
||||||
id: number;
|
|
||||||
name: string;
|
|
||||||
number: string;
|
|
||||||
parent_id?: number | null;
|
|
||||||
inUse?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CollectionRole {
|
|
||||||
id: number;
|
|
||||||
name: string;
|
|
||||||
collections?: Collection[];
|
|
||||||
}
|
|
|
@ -319,11 +319,6 @@ router
|
||||||
.as('dataset.categorize')
|
.as('dataset.categorize')
|
||||||
.where('id', router.matchers.number())
|
.where('id', router.matchers.number())
|
||||||
.use([middleware.auth(), middleware.can(['dataset-edit'])]);
|
.use([middleware.auth(), middleware.can(['dataset-edit'])]);
|
||||||
router
|
|
||||||
.put('/dataset/:id/categorizeUpdate', [DatasetController, 'categorizeUpdate'])
|
|
||||||
.as('dataset.categorizeUpdate')
|
|
||||||
.where('id', router.matchers.number())
|
|
||||||
.use([middleware.auth(), middleware.can(['dataset-edit'])]);
|
|
||||||
})
|
})
|
||||||
.prefix('submitter');
|
.prefix('submitter');
|
||||||
|
|
||||||
|
|
|
@ -102,18 +102,6 @@ module.exports = {
|
||||||
{ values: theme('asideScrollbars') },
|
{ values: theme('asideScrollbars') },
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
plugin(function({ addUtilities }) {
|
|
||||||
const newUtilities = {
|
|
||||||
'.drag-none': {
|
|
||||||
'-webkit-user-drag': 'none',
|
|
||||||
'-khtml-user-drag': 'none',
|
|
||||||
'-moz-user-drag': 'none',
|
|
||||||
'-o-user-drag': 'none',
|
|
||||||
'user-drag': 'none',
|
|
||||||
},
|
|
||||||
}
|
|
||||||
addUtilities(newUtilities)
|
|
||||||
}),
|
|
||||||
// As of Tailwind CSS v3.3, the `@tailwindcss/line-clamp` plugin is now included by default
|
// As of Tailwind CSS v3.3, the `@tailwindcss/line-clamp` plugin is now included by default
|
||||||
// require('@tailwindcss/line-clamp'),
|
// require('@tailwindcss/line-clamp'),
|
||||||
],
|
],
|
||||||
|
|
Loading…
Add table
Reference in a new issue