From f6d735d0fd4c9efa69077158599d95c216b6676c Mon Sep 17 00:00:00 2001 From: Arno Kaimbacher Date: Tue, 1 Aug 2023 17:06:51 +0200 Subject: [PATCH] - add model DatasetReference.ts - add references inside Creta.vue for Submitter /dataset - npm updates - extended enum types - added relations for Dataset.ts --- .../Http/Submitter/DatasetController.ts | 249 +++--- app/Models/Coverage.ts | 15 + app/Models/Dataset.ts | 6 + app/Models/DatasetReference.ts | 49 ++ app/Validators/CreateDatasetValidator.ts | 13 +- contracts/enums.ts | 21 + package-lock.json | 102 +-- package.json | 2 +- resources/js/Dataset.ts | 9 + .../js/Pages/Submitter/Dataset/Create.vue | 706 +++++++----------- 10 files changed, 580 insertions(+), 592 deletions(-) create mode 100644 app/Models/DatasetReference.ts diff --git a/app/Controllers/Http/Submitter/DatasetController.ts b/app/Controllers/Http/Submitter/DatasetController.ts index a3078a2..c990e15 100644 --- a/app/Controllers/Http/Submitter/DatasetController.ts +++ b/app/Controllers/Http/Submitter/DatasetController.ts @@ -6,6 +6,7 @@ import Project from 'App/Models/Project'; import Title from 'App/Models/Title'; import Description from 'App/Models/Description'; import Language from 'App/Models/Language'; +import Coverage from 'App/Models/Coverage'; // import CreateUserValidator from 'App/Validators/CreateUserValidator'; // import UpdateUserValidator from 'App/Validators/UpdateUserValidator'; import { schema, CustomMessages, rules } from '@ioc:Adonis/Core/Validator'; @@ -15,8 +16,9 @@ import Database from '@ioc:Adonis/Lucid/Database'; import { TransactionClientContract } from '@ioc:Adonis/Lucid/Database'; import Subject from 'App/Models/Subject'; import CreateDatasetValidator from 'App/Validators/CreateDatasetValidator'; -import { TitleTypes, DescriptionTypes, ContributorTypes, PersonNameTypes } from 'Contracts/enums'; +import { TitleTypes, DescriptionTypes, ContributorTypes, PersonNameTypes, ReferenceIdentifierTypes, RelationTypes } from 'Contracts/enums'; import type { ModelQueryBuilderContract } from '@ioc:Adonis/Lucid/Orm'; +import DatasetReference from 'App/Models/DatasetReference'; export default class DatasetController { public async index({ auth, request, inertia }: HttpContextContract) { @@ -115,6 +117,10 @@ export default class DatasetController { .map(([key, value]) => ({ value: key, label: value })), // descriptiontypes: DescriptionTypes projects: projects, + referenceIdentifierTypes: Object.entries(ReferenceIdentifierTypes) + .map(([key, value]) => ({ value: key, label: value })), + relationTypes: Object.entries(RelationTypes) + .map(([key, value]) => ({ value: key, label: value })), }); } @@ -239,6 +245,17 @@ export default class DatasetController { depth_min: schema.number.optional([rules.requiredIfExists('depth_max')]), depth_max: schema.number.optional([rules.requiredIfExists('depth_min')]), }), + references: schema.array([rules.uniqueArray('value')]).members( + schema.object().members({ + value: schema.string({ trim: true }, [ + rules.minLength(3), + rules.maxLength(255), + ]), + type: schema.enum(Object.values(ReferenceIdentifierTypes)), + relation: schema.enum(Object.values(RelationTypes)), + // language: schema.string({ trim: true }, [rules.minLength(2), rules.maxLength(255)]), + }), + ), subjects: schema.array([rules.minLength(3), rules.uniqueArray('value')]).members( schema.object().members({ value: schema.string({ trim: true }, [ @@ -263,6 +280,7 @@ export default class DatasetController { } return response.redirect().back(); } + public async store({ auth, request, response, session }: HttpContextContract) { // node ace make:validator CreateDataset try { @@ -277,134 +295,15 @@ export default class DatasetController { throw error; } - // const user = new User(); - // user.email = 'example@example.com'; - // user.password = 'password'; - // await user.useTransaction(trx).save(); - let trx: TransactionClientContract | null = null; try { trx = await Database.transaction(); const user = (await User.find(auth.user?.id)) as User; - // const dataset = await user.related('datasets').create({ - // type: request.input('type'), - // creatingCorporation: request.input('creating_corporation'), - // language: request.input('language'), - // }); - - // Create a new instance of the Dataset model: - const dataset = new Dataset(); - dataset.type = request.input('type'); - dataset.creatingCorporation = request.input('creating_corporation'); - dataset.language = request.input('language'); - dataset.embargoDate = request.input('embargo_date'); - //await dataset.related('user').associate(user); // speichert schon ab - // Dataset.$getRelation('user').boot(); - // Dataset.$getRelation('user').setRelated(dataset, user); - // dataset.$setRelated('user', user); - await user.useTransaction(trx).related('datasets').save(dataset); - - //store licenses: - const licenses: number[] = request.input('licenses', []); - dataset.useTransaction(trx).related('licenses').sync(licenses); - - const authors = request.input('authors', []); - for (const [key, person] of authors.entries()) { - const pivotData = { role: 'author', sort_order: key + 1 }; - - if (person.id !== undefined) { - await dataset - .useTransaction(trx) - .related('persons') - .attach({ - [person.id]: { - role: pivotData.role, - sort_order: pivotData.sort_order, - allow_email_contact: false, - }, - }); - } else { - const dataPerson = new Person(); - // use overwritten fill method - dataPerson.fill(person); - await dataset.useTransaction(trx).related('persons').save(dataPerson, false, { - role: pivotData.role, - sort_order: pivotData.sort_order, - allow_email_contact: false, - }); - } - } - - const contributors = request.input('contributors', []); - for (const [key, person] of contributors.entries()) { - const pivotData = { role: 'contributor', sort_order: key + 1 }; - - if (person.id !== undefined) { - await dataset - .useTransaction(trx) - .related('persons') - .attach({ - [person.id]: { - role: pivotData.role, - sort_order: pivotData.sort_order, - allow_email_contact: false, - }, - }); - } else { - const dataPerson = new Person(); - // use overwritten fill method - dataPerson.fill(person); - await dataset.useTransaction(trx).related('persons').save(dataPerson, false, { - role: pivotData.role, - sort_order: pivotData.sort_order, - allow_email_contact: false, - }); - } - } - - //save main and additional titles - const titles = request.input('titles', []); - for (const titleData of titles) { - const title = new Title(); - title.value = titleData.value; - title.language = titleData.language; - title.type = titleData.type; - await dataset.useTransaction(trx).related('titles').save(title); - } - - //save abstract and additional descriptions - const descriptions = request.input('descriptions', []); - for (const descriptionData of descriptions) { - // $descriptionReference = new Description($description); - // $dataset->abstracts()->save($descriptionReference); - const description = new Description(); - description.value = descriptionData.value; - description.language = descriptionData.language; - description.type = descriptionData.type; - await dataset.useTransaction(trx).related('descriptions').save(description); - } - - //save keywords - const keywords = request.input('subjects', []); - for (const keywordData of keywords) { - // $dataKeyword = new Subject($keyword); - // $dataset->subjects()->save($dataKeyword); - const keyword = await Subject.firstOrNew({ value: keywordData.value, type: keywordData.type }, keywordData); - if (keyword.$isNew === true) { - await dataset.useTransaction(trx).related('subjects').save(keyword); - } else { - await dataset.useTransaction(trx).related('subjects').attach([keyword.id]); - } - } - - // Dataset.$getRelation('persons').boot(); - // Dataset.$getRelation('persons').pushRelated(dataset, person) - // dataset.$pushRelated('persons', person); + await this.createDatasetAndAssociations(user, request, trx); await trx.commit(); - - console.log('Users and posts created successfully'); + console.log('Dataset and related models created successfully'); } catch (error) { if (trx !== null) { await trx.rollback(); @@ -425,8 +324,6 @@ export default class DatasetController { // fieldName: 'file' // size: 135624 - //const datasetFolder = 'files/' . dataset->id; - // await coverImage.moveToDisk('./') await coverImage.moveToDisk( '/test_dataset2', @@ -444,6 +341,110 @@ export default class DatasetController { return response.redirect().back(); } + private async createDatasetAndAssociations(user: User, request: HttpContextContract['request'], trx: TransactionClientContract) { + // Create a new instance of the Dataset model: + const dataset = new Dataset(); + dataset.type = request.input('type'); + dataset.creatingCorporation = request.input('creating_corporation'); + dataset.language = request.input('language'); + dataset.embargoDate = request.input('embargo_date'); + //await dataset.related('user').associate(user); // speichert schon ab + // Dataset.$getRelation('user').boot(); + // Dataset.$getRelation('user').setRelated(dataset, user); + // dataset.$setRelated('user', user); + await user.useTransaction(trx).related('datasets').save(dataset); + + //store licenses: + const licenses: number[] = request.input('licenses', []); + dataset.useTransaction(trx).related('licenses').sync(licenses); + + // save authors and contributors + await this.savePersons(dataset, request.input('authors', []), 'author', trx); + await this.savePersons(dataset, request.input('contributors', []), 'contributor', trx); + + //save main and additional titles + const titles = request.input('titles', []); + for (const titleData of titles) { + const title = new Title(); + title.value = titleData.value; + title.language = titleData.language; + title.type = titleData.type; + await dataset.useTransaction(trx).related('titles').save(title); + } + + // save descriptions + const descriptions = request.input('descriptions', []); + for (const descriptionData of descriptions) { + const description = new Description(); + description.value = descriptionData.value; + description.language = descriptionData.language; + description.type = descriptionData.type; + await dataset.useTransaction(trx).related('descriptions').save(description); + } + + //save references + const references = request.input('references', []); + for (const referencePayload of references) { + const dataReference = new DatasetReference(); + dataReference.fill(referencePayload); + // $dataReference = new DatasetReference($reference); + dataset.related('references').save(dataReference); + } + + //save keywords + const keywords = request.input('subjects', []); + for (const keywordData of keywords) { + // $dataKeyword = new Subject($keyword); + // $dataset->subjects()->save($dataKeyword); + const keyword = await Subject.firstOrNew({ value: keywordData.value, type: keywordData.type }, keywordData); + if (keyword.$isNew === true) { + await dataset.useTransaction(trx).related('subjects').save(keyword); + } else { + await dataset.useTransaction(trx).related('subjects').attach([keyword.id]); + } + } + + // save coverage + const coverageData = request.input('coverage'); + if (coverageData) { + // const formCoverage = request.input('coverage'); + const coverage = new Coverage(); + coverage.fill(coverageData); + // await dataset.coverage().save(coverageData); + await dataset.useTransaction(trx).related('coverage').save(coverage); + // Alternatively, you can associate the dataset with the coverage and then save it: + // await coverage.dataset().associate(dataset).save(); + // await coverage.useTransaction(trx).related('dataset').associate(dataset); + } + } + + private async savePersons(dataset: Dataset, persons: any[], role: string, trx: TransactionClientContract) { + for (const [key, person] of persons.entries()) { + const pivotData = { role: role, sort_order: key + 1 }; + + if (person.id !== undefined) { + await dataset + .useTransaction(trx) + .related('persons') + .attach({ + [person.id]: { + role: pivotData.role, + sort_order: pivotData.sort_order, + allow_email_contact: false, + }, + }); + } else { + const dataPerson = new Person(); + dataPerson.fill(person); + await dataset.useTransaction(trx).related('persons').save(dataPerson, false, { + role: pivotData.role, + sort_order: pivotData.sort_order, + allow_email_contact: false, + }); + } + } + } + public messages: CustomMessages = { 'minLength': '{{ field }} must be at least {{ options.minLength }} characters long', 'maxLength': '{{ field }} must be less then {{ options.maxLength }} characters long', diff --git a/app/Models/Coverage.ts b/app/Models/Coverage.ts index 48b3092..6baa2d7 100644 --- a/app/Models/Coverage.ts +++ b/app/Models/Coverage.ts @@ -7,6 +7,21 @@ export default class Coverage extends BaseModel { public static primaryKey = 'id'; public static table = 'coverage'; public static selfAssignPrimaryKey = false; + public static fillable: string[] = [ + 'elevation_min', + 'elevation_max', + 'elevation_absolut', + 'depth_min', + 'depth_max', + 'depth_absolut', + 'time_min', + 'time_max', + 'time_absolut', + 'x_min', + 'x_max', + 'y_min', + 'y_max', + ]; @column({ isPrimary: true, diff --git a/app/Models/Dataset.ts b/app/Models/Dataset.ts index 33eaada..0b96463 100644 --- a/app/Models/Dataset.ts +++ b/app/Models/Dataset.ts @@ -22,6 +22,7 @@ import License from './License'; import Subject from './Subject'; import File from './File'; import Coverage from './Coverage'; +import DatasetReference from './DatasetReference'; export default class Dataset extends BaseModel { public static namingStrategy = new SnakeCaseNamingStrategy(); @@ -138,6 +139,11 @@ export default class Dataset extends BaseModel { }) public coverage: HasOne; + @hasMany(() => DatasetReference, { + foreignKey: 'document_id', + }) + public references: HasMany; + @computed({ serializeAs: 'main_title', diff --git a/app/Models/DatasetReference.ts b/app/Models/DatasetReference.ts new file mode 100644 index 0000000..e478cf3 --- /dev/null +++ b/app/Models/DatasetReference.ts @@ -0,0 +1,49 @@ +import { column, BaseModel, SnakeCaseNamingStrategy, belongsTo, BelongsTo } from '@ioc:Adonis/Lucid/Orm'; +import { DateTime } from 'luxon'; +import Dataset from './Dataset'; + +export default class DatasetReference extends BaseModel { + public static namingStrategy = new SnakeCaseNamingStrategy(); + public static primaryKey = 'id'; + public static table = 'document_references'; + public static fillable: string[] = ['value', 'label', 'type', 'relation']; + + @column({ + isPrimary: true, + }) + public id: number; + + @column({}) + public document_id: number; + + @column({}) + public related_document_id?: number; + + @column({}) + public type: string; + + @column({}) + public relation: string; + + @column({}) + public value: string; + + @column({}) + public label: string; + + @column.dateTime({ + autoCreate: true, + }) + public created_at?: DateTime; + + @column.dateTime({ + autoCreate: true, + autoUpdate: true, + }) + public updated_at?: DateTime; + + @belongsTo(() => Dataset, { + foreignKey: 'document_id', + }) + public dataset: BelongsTo; +} diff --git a/app/Validators/CreateDatasetValidator.ts b/app/Validators/CreateDatasetValidator.ts index 5870d94..8fd41c6 100644 --- a/app/Validators/CreateDatasetValidator.ts +++ b/app/Validators/CreateDatasetValidator.ts @@ -1,7 +1,7 @@ import { schema, CustomMessages, rules } from '@ioc:Adonis/Core/Validator'; import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'; import dayjs from 'dayjs'; -import { TitleTypes, DescriptionTypes } from 'Contracts/enums'; +import { TitleTypes, DescriptionTypes, RelationTypes, ReferenceIdentifierTypes } from 'Contracts/enums'; export default class CreateDatasetValidator { constructor(protected ctx: HttpContextContract) {} @@ -73,6 +73,17 @@ export default class CreateDatasetValidator { depth_min: schema.number.optional([rules.requiredIfExists('depth_max')]), depth_max: schema.number.optional([rules.requiredIfExists('depth_min')]), }), + references: schema.array([rules.uniqueArray('value')]).members( + schema.object().members({ + value: schema.string({ trim: true }, [ + rules.minLength(3), + rules.maxLength(255), + ]), + type: schema.enum(Object.values(ReferenceIdentifierTypes)), + relation: schema.enum(Object.values(RelationTypes)), + // language: schema.string({ trim: true }, [rules.minLength(2), rules.maxLength(255)]), + }), + ), subjects: schema.array([rules.minLength(3), rules.uniqueArray('value')]).members( schema.object().members({ value: schema.string({ trim: true }, [ diff --git a/contracts/enums.ts b/contracts/enums.ts index f0298cf..917e7db 100644 --- a/contracts/enums.ts +++ b/contracts/enums.ts @@ -79,3 +79,24 @@ export enum ContributorTypes { export enum SubjectTypes { uncontrolled = 'uncontrolled', } + +export enum ReferenceIdentifierTypes { + DOI = 'DOI', + Handle = 'Handle', + ISBN = 'ISBN', + ISSN = 'ISSN', + URL = 'URL', + URN = 'URN', +} + +export enum RelationTypes { + IsSupplementTo = 'IsSupplementTo', + IsSupplementedBy = 'IsSupplementedBy', + IsContinuedBy = 'IsContinuedBy', + Continues = 'Continues', + IsNewVersionOf = 'IsNewVersionOf', + IsPartOf = 'IsPartOf', + HasPart = 'HasPart', + Compiles = 'Compiles', + IsVariantFormOf = 'IsVariantFormOf', +} diff --git a/package-lock.json b/package-lock.json index d4ce931..402fe31 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,7 +33,6 @@ "reflect-metadata": "^0.1.13", "saxon-js": "^2.5.0", "source-map-support": "^0.5.21", - "vue-facing-decorator": "^2.1.13", "vuedraggable": "^4.1.0", "xmlbuilder2": "^3.1.1" }, @@ -74,6 +73,7 @@ "ts-loader": "^9.4.2", "typescript": "^5.1.3", "vue": "^3.2.47", + "vue-facing-decorator": "^3.0.0", "vue-loader": "^17.0.1", "xslt3": "^2.5.0", "youch": "^3.2.0", @@ -2699,9 +2699,9 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz", - "integrity": "sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.1.tgz", + "integrity": "sha512-9t7ZA7NGGK8ckelF0PQCfcxIUzs1Md5rrO6U/c+FIQNanea5UZC0wqKXH4vHBccmu4ZJgZ2idtPeW7+Q2npOEA==", "dev": true, "dependencies": { "ajv": "^6.12.4", @@ -2767,9 +2767,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz", - "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==", + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.46.0.tgz", + "integrity": "sha512-a8TLtmPi8xzPkCbp/OGFUo5yhRkHM2Ko9kOWP4znJr0WAhWyThaw3PnwX4vOTWOAMsV2uRt32PPDcEz63esSaA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4168,9 +4168,9 @@ } }, "node_modules/@types/validator": { - "version": "13.7.17", - "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.17.tgz", - "integrity": "sha512-aqayTNmeWrZcvnG2MG9eGYI6b7S5fl+yKgPs6bAjOTwPS316R5SxBGKvtSExfyoJU7pIeHJfsHI0Ji41RVMkvQ==" + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.9.0.tgz", + "integrity": "sha512-NclP0IbzHj/4tJZKFqKh8E7kZdgss+MCUYV9G+TLltFfDA4lFgE4PKPpDIyS2FlcdANIfSx273emkupvChigbw==" }, "node_modules/@types/ws": { "version": "8.5.5", @@ -5864,9 +5864,9 @@ } }, "node_modules/browserslist": { - "version": "4.21.9", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz", - "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==", + "version": "4.21.10", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", + "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==", "dev": true, "funding": [ { @@ -5883,9 +5883,9 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001503", - "electron-to-chromium": "^1.4.431", - "node-releases": "^2.0.12", + "caniuse-lite": "^1.0.30001517", + "electron-to-chromium": "^1.4.477", + "node-releases": "^2.0.13", "update-browserslist-db": "^1.0.11" }, "bin": { @@ -6081,9 +6081,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001517", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001517.tgz", - "integrity": "sha512-Vdhm5S11DaFVLlyiKu4hiUTkpZu+y1KA/rZZqVQfOD5YdDT/eQKlkt7NaE0WGOFgX32diqt9MiP9CAiFeRklaA==", + "version": "1.0.30001518", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001518.tgz", + "integrity": "sha512-rup09/e3I0BKjncL+FesTayKtPrdwKhUufQFd3riFw1hHg8JmIFoInYfB102cFcY/pPgGmdyl/iy+jgiDi2vdA==", "dev": true, "funding": [ { @@ -7950,9 +7950,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.475", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.475.tgz", - "integrity": "sha512-mTye5u5P98kSJO2n7zYALhpJDmoSQejIGya0iR01GpoRady8eK3bw7YHHnjA1Rfi4ZSLdpuzlAC7Zw+1Zu7Z6A==", + "version": "1.4.479", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.479.tgz", + "integrity": "sha512-ABv1nHMIR8I5n3O3Een0gr6i0mfM+YcTZqjHy3pAYaOjgFG+BMquuKrSyfYf5CbEkLr9uM05RA3pOk4udNB/aQ==", "dev": true }, "node_modules/emittery": { @@ -8011,9 +8011,9 @@ } }, "node_modules/enquirer": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.0.tgz", - "integrity": "sha512-ehu97t6FTYK2I3ZYtnp0BZ9vt0mvEL/cnHBds7Ct6jo9VX1VIkiFhOvVRWh6eblQqd7KOoICIQV+syZ3neXO/Q==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", "dependencies": { "ansi-colors": "^4.1.1", "strip-ansi": "^6.0.1" @@ -8101,27 +8101,27 @@ } }, "node_modules/eslint": { - "version": "8.45.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.45.0.tgz", - "integrity": "sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw==", + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.46.0.tgz", + "integrity": "sha512-cIO74PvbW0qU8e0mIvk5IV3ToWdCq5FYG6gWPHHkx6gNdjlbAYvtfHmlCMXxjcoVaIdwy/IAt3+mDkZkfvb2Dg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.1.0", - "@eslint/js": "8.44.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.1", + "@eslint/js": "^8.46.0", "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.1", - "espree": "^9.6.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.2", + "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -8212,9 +8212,9 @@ } }, "node_modules/eslint-scope": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.1.tgz", - "integrity": "sha512-CvefSOsDdaYYvxChovdrPo/ZGt8d5lrJWleAc1diXRKhHGiTYEI26cvo8Kle/wGnsizoCJjK73FMg1/IkIwiNA==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", @@ -8228,9 +8228,9 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.2.tgz", + "integrity": "sha512-8drBzUEyZ2llkpCA67iYrgEssKDUu68V8ChqqOfFupIaG/LCVPUT+CoGJpT77zJprs4T/W7p07LP7zAIMuweVw==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -12710,13 +12710,13 @@ } }, "node_modules/pg": { - "version": "8.11.1", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.1.tgz", - "integrity": "sha512-utdq2obft07MxaDg0zBJI+l/M3mBRfIpEN3iSemsz0G5F2/VXx+XzqF4oxrbIZXQxt2AZzIUzyVg/YM6xOP/WQ==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.2.tgz", + "integrity": "sha512-l4rmVeV8qTIrrPrIR3kZQqBgSN93331s9i6wiUiLOSk0Q7PmUxZD/m1rQI622l3NfqBby9Ar5PABfS/SulfieQ==", "dependencies": { "buffer-writer": "2.0.0", "packet-reader": "1.0.0", - "pg-connection-string": "^2.6.1", + "pg-connection-string": "^2.6.2", "pg-pool": "^3.6.1", "pg-protocol": "^1.6.0", "pg-types": "^2.1.0", @@ -12784,6 +12784,11 @@ "node": ">=4" } }, + "node_modules/pg/node_modules/pg-connection-string": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz", + "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==" + }, "node_modules/pgpass": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", @@ -16716,9 +16721,10 @@ } }, "node_modules/vue-facing-decorator": { - "version": "2.1.20", - "resolved": "https://registry.npmjs.org/vue-facing-decorator/-/vue-facing-decorator-2.1.20.tgz", - "integrity": "sha512-Xv987Q+XhhWTPXxzG4HllHxckMahV04wDcRebdd/AWlU/hYm7+tGRo2eD84mpl3rZLZQ74Cr41UlWbGbEQptNA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/vue-facing-decorator/-/vue-facing-decorator-3.0.0.tgz", + "integrity": "sha512-NnbFHlJCYzQv8Mx9ehm486NLxidx/KeqbSDgi4V9kLXakLIijzLHqRWMpuEWW4hsQFxRh3bTtPCTCZMP2OL+4Q==", + "dev": true, "peerDependencies": { "vue": "^3.0.0" } diff --git a/package.json b/package.json index 4621686..845c1a8 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,7 @@ "ts-loader": "^9.4.2", "typescript": "^5.1.3", "vue": "^3.2.47", + "vue-facing-decorator": "^3.0.0", "vue-loader": "^17.0.1", "xslt3": "^2.5.0", "youch": "^3.2.0", @@ -86,7 +87,6 @@ "reflect-metadata": "^0.1.13", "saxon-js": "^2.5.0", "source-map-support": "^0.5.21", - "vue-facing-decorator": "^2.1.13", "vuedraggable": "^4.1.0", "xmlbuilder2": "^3.1.1" } diff --git a/resources/js/Dataset.ts b/resources/js/Dataset.ts index 463266d..0ef2a69 100644 --- a/resources/js/Dataset.ts +++ b/resources/js/Dataset.ts @@ -11,6 +11,7 @@ export interface Dataset { | number | (IErrorMessage | undefined) | Coverage + | Array | Array; language: Ref; // licenses: Array; @@ -27,6 +28,7 @@ export interface Dataset { errors?: IErrorMessage; // async (user): Promise; subjects: Array; + references: Array; files: Array | undefined; // upload: TethysFile } @@ -53,6 +55,13 @@ export interface Subject { value: string; external_key?: string; } +export interface DatasetReference { + // id: number; + value: string; + label: string; + type: string; + relation: string; +} export interface Title { value: string; diff --git a/resources/js/Pages/Submitter/Dataset/Create.vue b/resources/js/Pages/Submitter/Dataset/Create.vue index 2970d93..faf20e7 100644 --- a/resources/js/Pages/Submitter/Dataset/Create.vue +++ b/resources/js/Pages/Submitter/Dataset/Create.vue @@ -12,7 +12,8 @@ import { mdiBookOpenPageVariant, mdiImageText, mdiEarthPlus, - mdiAlertBoxOutline + mdiAlertBoxOutline, + mdiTrashCan } from '@mdi/js'; import LayoutAuthenticated from '@/Layouts/LayoutAuthenticated.vue'; import SectionMain from '@/Components/SectionMain.vue'; @@ -67,6 +68,14 @@ const props = defineProps({ type: Object, default: () => ({}), }, + referenceIdentifierTypes: { + type: Object, + default: () => ({}), + }, + relationTypes: { + type: Object, + default: () => ({}), + }, errors: { type: Object, default: () => ({}), @@ -127,6 +136,7 @@ if (Object.keys(mainService.dataset).length == 0) { { value: '', type: 'uncontrolled', language: language.value }, { value: '', type: 'uncontrolled', language: language.value }, ], + references: [], files: [], // upload: { label: 'test', sorting: 0 }, }; @@ -151,6 +161,7 @@ if (Object.keys(mainService.dataset).length == 0) { embargo_date: mainService.dataset.embargo_date, coverage: mainService.dataset.coverage, subjects: mainService.dataset.subjects, + references: mainService.dataset.references, files: mainService.dataset.files, // upload: mainService.dataset.upload, }; @@ -324,6 +335,7 @@ const submit = async () => { { value: '', type: 'uncontrolled', language: language.value }, { value: '', type: 'uncontrolled', language: language.value }, ], + references: [], files: [] as Array, upload: { label: 'test', sorting: 0 }, }; @@ -388,6 +400,19 @@ const addKeyword = () => { form.subjects.push(newSubject); }; +const addReference = () => { + let newReference = { value: '', label: '', relation: '', type: '' }; + //this.dataset.files.push(uploadedFiles[i]); + form.references.push(newReference); +}; +/* +Removes a selected reference +*/ +const removeReference = (key) => { + form.references.splice(key, 1); +}; + /* + // const onChangeFile = (event) => { // // let uploadedFile = event.target.files[0]; @@ -398,8 +423,8 @@ const addKeyword = () => { // // console.log(file.file); // }; /* - Removes a selected keyword - */ +Removes a selected keyword +*/ // const removeKeyword = (key) => { // form.subjects.splice(key, 1); // }; @@ -411,17 +436,16 @@ const addKeyword = () => {
  • die Data Policy von Tethys RDR sowie die Terms & Conditions von Tethys gelesen und verstanden zu haben (siehe hier) + href="/docs/HandbuchTethys.pdf" target="_blank">siehe hier) +
  • +
  • das Einverständnis aller Co-Autoren über die bevorstehende Datenpublikation schriftlich eingeholt zu haben
  • -
  • das Einverständnis aller Co-Autoren über die bevorstehende Datenpublikation schriftlich eingeholt zu haben
  • sowohl mit der Data Policy als auch mit den Terms & Conditions einverstanden zu sein
+ @@ -450,7 +474,8 @@ const addKeyword = () => { - + @@ -460,20 +485,11 @@ const addKeyword = () => {
- - + +
{{ form.errors.language.join(', ') }}
@@ -481,12 +497,8 @@ const addKeyword = () => {
- + @@ -494,23 +506,15 @@ const addKeyword = () => { terms and conditions --> - +
@@ -522,43 +526,24 @@ const addKeyword = () => {
- - -
+ + +
{{ form.errors.type.join(', ') }}
- - -
+ + +
{{ form.errors.creating_corporation.join(', ') }}
@@ -567,42 +552,27 @@ const addKeyword = () => { - +
- - -
+ + +
{{ form.errors['titles.0.value'].join(', ') }}
- - -
+ class="w-full mx-2 flex-1"> + +
{{ form.errors['titles.0.language'].join(', ') }}
@@ -614,60 +584,38 @@ const addKeyword = () => {
- + - - -
+ class="w-full mx-2 flex-1"> + +
{{ form.errors[`titles.${index}.value`].join(', ') }}
- - -
+ class="w-full mx-2 flex-1"> + +
{{ form.errors[`titles.${index}.type`].join(', ') }}
- - -
+ class="w-full mx-2 flex-1"> + +
{{ form.errors[`titles.${index}.language`].join(', ') }}
@@ -679,48 +627,27 @@ const addKeyword = () => { - +
- - -
+ class="w-full mx-2 flex-1"> + +
{{ form.errors['descriptions.0.value'].join(', ') }}
- - -
+ class="w-full mx-2 flex-1"> + +
{{ form.errors['descriptions.0.language'].join(', ') }}
@@ -732,75 +659,40 @@ const addKeyword = () => {
- + - - -
+ class="w-full mx-2 flex-1"> + +
{{ form.errors[`descriptions.${index}.value`].join(', ') }}
- - -
+ class="w-full mx-2 flex-1"> + +
{{ form.errors[`descriptions.${index}.type`].join(', ') }}
- - -
+ class="w-full mx-2 flex-1"> + +
{{ form.errors[`descriptions.${index}.language`].join(', ') }}
@@ -812,12 +704,8 @@ const addKeyword = () => { - +
@@ -827,12 +715,9 @@ const addKeyword = () => { - + + @@ -841,39 +726,20 @@ const addKeyword = () => {
- - + +
{{ form.errors.project_id.join(', ') }}
- - + +
{{ form.errors.embargo_date.join(', ') }}
@@ -883,71 +749,50 @@ const addKeyword = () => { - +
- - -
+ + +
{{ form.errors['coverage.x_min'].join(', ') }}
- - -
+ + +
{{ form.errors['coverage.x_max'].join(', ') }}
- - -
+ + +
{{ form.errors['coverage.y_min'].join(', ') }}
- - -
+ + +
{{ form.errors['coverage.y_max'].join(', ') }}
@@ -967,58 +812,41 @@ const addKeyword = () => { elevation range (m)
- - -
+ class="w-full mx-2 flex-1"> + +
{{ form.errors['coverage.elevation_absolut'].join(', ') }}
- - -
+ class="w-full mx-2 flex-1"> + +
{{ form.errors['coverage.elevation_min'].join(', ') }}
- - -
+ class="w-full mx-2 flex-1"> + +
{{ form.errors['coverage.elevation_max'].join(', ') }}
@@ -1041,43 +869,35 @@ const addKeyword = () => {
- - -
+ class="w-full mx-2 flex-1"> + +
{{ form.errors['coverage.depth_absolut'].join(', ') }}
-
- + + - -
+ class="w-full mx-2 flex-1"> + +
{{ form.errors['coverage.depth_min'].join(', ') }}
- - -
+ class="w-full mx-2 flex-1"> + +
{{ form.errors['coverage.depth_max'].join(', ') }}
@@ -1085,20 +905,72 @@ const addKeyword = () => {
- + + + + + + + + + + + + + + + + + + + + + +
Value of the identifierTypeRelationLabel
+ + + +
+ {{ form.errors[`references.${index}.type`].join(', ') }} +
+
+
+ + +
+ {{ form.errors[`references.${index}.relation`].join(', ') }} +
+
+
+ + + + +
+
+ + + - +
@@ -1113,14 +985,15 @@ const addKeyword = () => { Drag your file(s) here to begin
or click to browse

-
--> +
-->
{{ form.errors['file'].join(', ') }}
-
+
{{ form.errors['upload.label'].join(', ') }}
@@ -1129,34 +1002,26 @@ const addKeyword = () => { @@ -1165,18 +1030,21 @@ const addKeyword = () => {