From f403c3109f818f12c785ae07d3f6862252a44565 Mon Sep 17 00:00:00 2001 From: Arno Kaimbacher Date: Tue, 27 Jun 2023 18:23:18 +0200 Subject: [PATCH] - add methods for releasing datasets from submitter - npm updates - side menu with child items - flash messages via HttpContext response (extended via macro) --- .../Http/Submitter/DatasetController.ts | 145 ++++++++++++ app/FlashResponse.ts | 34 +++ app/Models/Dataset.ts | 42 +++- app/Models/File.ts | 14 +- contracts/response.ts | 7 + database/migrations/dataset_1_projects.ts | 2 +- .../migrations/dataset_6_collection_roles.ts | 1 - database/migrations/dataset_7_collections.ts | 4 +- .../dataset_8_link_documents_collections.ts | 22 +- database/migrations/dataset_9_persons.ts | 1 - .../files_4_link_documents_licences.ts | 12 +- database/migrations/lookup_1_mime_types.ts | 2 +- package-lock.json | 177 +++++++------- providers/AppProvider.ts | 20 +- providers/HashDriver/index.ts | 10 +- resources/js/Components/AsideMenuItem.vue | 13 +- resources/js/Components/AsideMenuLayer.vue | 2 +- resources/js/Components/AsideMenuList.vue | 4 +- .../js/Components/Charts/chart.config.js | 84 ++++--- resources/js/Components/Map/Control.ts | 20 +- resources/js/Components/Map/LayerOptions.ts | 3 +- resources/js/Components/Map/utilities.ts | 18 +- resources/js/Components/TablePersons.vue | 19 +- resources/js/Pages/Admin/User/AccountInfo.vue | 223 ++++++++++-------- .../js/Pages/Submitter/Dataset/Index.vue | 141 +++++++++++ .../js/Pages/Submitter/Dataset/Release.vue | 131 ++++++++++ resources/js/Stores/layout.ts | 18 +- resources/js/Stores/main.ts | 2 +- resources/js/Stores/map.service.ts | 12 +- resources/js/Stores/style.ts | 84 ++++--- resources/js/Stores/time.service.ts | 14 +- resources/js/app.js | 5 +- resources/js/colors.js | 171 +++++++------- resources/js/config.js | 6 +- resources/js/menu.ts | 29 ++- start/routes.ts | 9 + tests/functional/home.spec.ts | 1 - 37 files changed, 1020 insertions(+), 482 deletions(-) create mode 100644 app/FlashResponse.ts create mode 100644 contracts/response.ts create mode 100644 resources/js/Pages/Submitter/Dataset/Index.vue create mode 100644 resources/js/Pages/Submitter/Dataset/Release.vue diff --git a/app/Controllers/Http/Submitter/DatasetController.ts b/app/Controllers/Http/Submitter/DatasetController.ts index 6d34006..4e3cb79 100644 --- a/app/Controllers/Http/Submitter/DatasetController.ts +++ b/app/Controllers/Http/Submitter/DatasetController.ts @@ -17,8 +17,68 @@ import { TransactionClientContract } from '@ioc:Adonis/Lucid/Database'; import Subject from 'App/Models/Subject'; import CreateDatasetValidator from 'App/Validators/CreateDatasetValidator'; import { TitleTypes, DescriptionTypes } from 'Contracts/enums'; +import type { ModelQueryBuilderContract } from '@ioc:Adonis/Lucid/Orm'; export default class DatasetController { + public async index({ auth, request, inertia }: HttpContextContract) { + const user = (await User.find(auth.user?.id)) as User; + const page = request.input('page', 1); + let datasets: ModelQueryBuilderContract = Dataset.query(); + + // if (request.input('search')) { + // // users = users.whereRaw('name like %?%', [request.input('search')]) + // const searchTerm = request.input('search'); + // datasets.where('name', 'ilike', `%${searchTerm}%`); + // } + + if (request.input('sort')) { + type SortOrder = 'asc' | 'desc' | undefined; + let attribute = request.input('sort'); + let sort_order: SortOrder = 'asc'; + + if (attribute.substr(0, 1) == '-') { + sort_order = 'desc'; + // attribute = substr(attribute, 1); + attribute = attribute.substr(1); + } + datasets.orderBy(attribute, sort_order); + } else { + // users.orderBy('created_at', 'desc'); + datasets.orderBy('id', 'asc'); + } + + // const users = await User.query().orderBy('login').paginate(page, limit); + const myDatasets = await datasets + .whereIn('server_state', [ + 'inprogress', + 'released', + 'editor_accepted', + 'approved', + 'reviewed', + 'rejected_editor', + 'rejected_reviewer', + ]) + .where('account_id', user.id) + .preload('titles') + .preload('user', (query) => query.select('id', 'login')) + // .preload('titles', (builder) => { + // // pull the actual preload data + + // builder.where('type', 'Main'); + // }) + .paginate(page, 10); + + return inertia.render('Submitter/Dataset/Index', { + // testing: 'this is a test', + datasets: myDatasets.serialize(), + filters: request.all(), + can: { + // create: await auth.user?.can(['user-create']), + edit: await auth.user?.can(['dataset-edit']), + delete: await auth.user?.can(['dataset-delete']), + }, + }); + } public async create({ inertia }: HttpContextContract) { const licenses = await License.query().select('id', 'name_long').pluck('name_long', 'id'); @@ -423,4 +483,89 @@ export default class DatasetController { 'files.*.size': 'file size is to big', 'files.extnames': 'file extension is not supported', }; + + // public async release({ params, view }) { + public async release({ request, inertia }: HttpContextContract) { + const id = request.param('id'); + + const dataset = await Dataset.query() + .preload('user', (builder) => { + builder.select('id', 'login'); + }) + .where('id', id) + .firstOrFail(); + + // const editors = await User.query() + // .whereHas('roles', (builder) => { + // builder.where('name', 'editor'); + // }) + // .pluck('login', 'id'); + + return inertia.render('Submitter/Dataset/Release', { + dataset, + }); + } + + public async releaseUpdate({ request, response }: HttpContextContract) { + const id = request.param('id'); + const dataset = await Dataset.query().preload('files').where('id', id).firstOrFail(); + if (dataset.files.length === 0) { + return response.flash('message', 'At least minimum one file is required.').redirect('back'); + } + + const preferation = request.input('preferation', ''); + const preferredReviewer = request.input('preferred_reviewer'); + const preferredReviewerEmail = request.input('preferred_reviewer_email'); + + if (preferation === 'yes_preferation') { + const newSchema = schema.create({ + preferred_reviewer: schema.string({ trim: true }, [rules.minLength(3), rules.maxLength(255)]), + preferred_reviewer_email: schema.string([rules.email()]), + }); + + try { + await request.validate({ schema: newSchema }); + } catch (error) { + // return response.badRequest(error.messages); + throw error; + } + } + + const input = { + preferred_reviewer: preferredReviewer || null, + preferred_reviewer_email: preferredReviewerEmail || null, + server_state: 'released', + editor_id: null, + reviewer_id: null, + reject_editor_note: null, + reject_reviewer_note: null, + }; + + // Clear editor_id if it exists + if (dataset.editor_id !== null) { + input.editor_id = null; + } + + // Clear reject_editor_note if it exists + if (dataset.reject_editor_note !== null) { + input.reject_editor_note = null; + } + + // Clear reviewer_id if it exists + if (dataset.reviewer_id !== null) { + input.reviewer_id = null; + } + + // Clear reject_reviewer_note if it exists + if (dataset.reject_reviewer_note !== null) { + input.reject_reviewer_note = null; + } + + // if (await dataset.merge(input).save()) { + // return response.redirect().route('publish.workflow.submit.index').flash('flash_message', 'You have released your dataset!'); + // } + return response.toRoute('dataset.list').flash('message', 'You have released your dataset'); + + // throw new GeneralException(trans('exceptions.publish.release.update_error')); + } } diff --git a/app/FlashResponse.ts b/app/FlashResponse.ts new file mode 100644 index 0000000..004a6d5 --- /dev/null +++ b/app/FlashResponse.ts @@ -0,0 +1,34 @@ +import { Response } from '@adonisjs/http-server/build/src/Response'; +import { ServerResponse, IncomingMessage } from 'http'; +import { RouterContract } from '@ioc:Adonis/Core/Route'; +import { EncryptionContract } from '@ioc:Adonis/Core/Encryption'; +import { ResponseConfig, ResponseContract } from '@ioc:Adonis/Core/Response'; + +class FlashResponse extends Response implements ResponseContract { + protected static macros = {}; + protected static getters = {}; + constructor( + public request: IncomingMessage, + public response: ServerResponse, + flashEncryption: EncryptionContract, + flashConfig: ResponseConfig, + flashRouter: RouterContract, + ) { + super(request, response, flashEncryption, flashConfig, flashRouter); + } + nonce: string; + + public flash(key: string, message: any): this { + // Store the flash message in the session + this.ctx?.session.flash(key, message); + return this; + } + + public toRoute(route: string): this { + // Redirect to the specified route + super.redirect().toRoute(route); + return this; + } +} + +export default FlashResponse; diff --git a/app/Models/Dataset.ts b/app/Models/Dataset.ts index 6c29345..a6175f6 100644 --- a/app/Models/Dataset.ts +++ b/app/Models/Dataset.ts @@ -8,14 +8,17 @@ import { BelongsTo, hasMany, HasMany, + computed, } from '@ioc:Adonis/Lucid/Orm'; import { DateTime } from 'luxon'; +import dayjs from 'dayjs'; import Person from './Person'; import User from './User'; import Title from './Title'; import Description from './Description'; import License from './License'; import Subject from './Subject'; +import File from './File'; export default class Dataset extends BaseModel { public static namingStrategy = new SnakeCaseNamingStrategy(); @@ -47,10 +50,29 @@ export default class Dataset extends BaseModel { @column({}) public account_id: number | null = null; + @column({}) + public editor_id: number | null = null; + + @column({}) + public reviewer_id: number | null = null; + + @column({}) + public reject_editor_note: string; + + @column({}) + public reject_reviewer_note: string; + @column.dateTime({ columnName: 'server_date_published' }) public serverDatePublished: DateTime; - @column.dateTime({ autoCreate: true, columnName: 'created_at' }) + // @column.dateTime({ autoCreate: true, columnName: 'created_at' }) + @column.dateTime({ + serialize: (value: Date | null) => { + return value ? dayjs(value).format('MMMM D YYYY HH:mm a') : value; + }, + autoCreate: true, + columnName: 'created_at', + }) public createdAt: DateTime; @column.dateTime({ autoCreate: true, autoUpdate: true, columnName: 'server_date_modified' }) @@ -100,9 +122,17 @@ export default class Dataset extends BaseModel { }) public subjects: ManyToMany; - // async save(): Promise { - // // Call the parent save method to persist changes to the database - // await super.save(); - // return this; - // } + @hasMany(() => File, { + foreignKey: 'document_id', + }) + public files: HasMany; + + @computed({ + serializeAs: 'main_title', + }) + public get mainTitle() { + // return `${this.firstName} ${this.lastName}`; + const mainTitle = this.titles?.find((title) => title.type === 'Main'); + return mainTitle ? mainTitle.value : null; + } } diff --git a/app/Models/File.ts b/app/Models/File.ts index 0d77f1a..5044791 100644 --- a/app/Models/File.ts +++ b/app/Models/File.ts @@ -4,11 +4,14 @@ import { BaseModel, hasMany, HasMany, + belongsTo, + BelongsTo, // manyToMany, // ManyToMany, SnakeCaseNamingStrategy, } from '@ioc:Adonis/Lucid/Orm'; import HashValue from './HashValue'; +import Dataset from './Dataset'; export default class File extends BaseModel { public static namingStrategy = new SnakeCaseNamingStrategy(); @@ -21,6 +24,9 @@ export default class File extends BaseModel { }) public id: number; + @column({}) + public document_id: number; + @column({}) public pathName: string; @@ -51,10 +57,14 @@ export default class File extends BaseModel { @column.dateTime({ autoCreate: true, autoUpdate: true }) public updatedAt: DateTime; - // public function hashvalues() + // public function dataset() // { - // return $this->hasMany(HashValue::class, 'file_id', 'id'); + // return $this->belongsTo(Dataset::class, 'document_id', 'id'); // } + @belongsTo(() => Dataset, { + foreignKey: 'document_id', + }) + public dataset: BelongsTo; @hasMany(() => HashValue, { foreignKey: 'file_id', diff --git a/contracts/response.ts b/contracts/response.ts new file mode 100644 index 0000000..d8eb1a7 --- /dev/null +++ b/contracts/response.ts @@ -0,0 +1,7 @@ +declare module '@ioc:Adonis/Core/Response' { + interface ResponseContract { + flash(key: string, message: any): this; + + toRoute(route: string): this; + } +} diff --git a/database/migrations/dataset_1_projects.ts b/database/migrations/dataset_1_projects.ts index 167dad7..64d7f3c 100644 --- a/database/migrations/dataset_1_projects.ts +++ b/database/migrations/dataset_1_projects.ts @@ -34,4 +34,4 @@ export default class Projects extends BaseSchema { // OWNER to tethys_admin; // REVOKE ALL ON TABLE projects FROM tethys_app; // GRANT ALL ON TABLE projects TO tethys_admin; -// GRANT DELETE, UPDATE, INSERT, SELECT ON TABLE projects TO tethys_app; \ No newline at end of file +// GRANT DELETE, UPDATE, INSERT, SELECT ON TABLE projects TO tethys_app; diff --git a/database/migrations/dataset_6_collection_roles.ts b/database/migrations/dataset_6_collection_roles.ts index 6125546..d8bd289 100644 --- a/database/migrations/dataset_6_collection_roles.ts +++ b/database/migrations/dataset_6_collection_roles.ts @@ -37,4 +37,3 @@ export default class CollectionsRoles extends BaseSchema { // REVOKE ALL ON TABLE collections_roles FROM tethys_app; // GRANT ALL ON TABLE collections_roles TO tethys_admin; // GRANT DELETE, UPDATE, INSERT, SELECT ON TABLE collections_roles TO tethys_app; - diff --git a/database/migrations/dataset_7_collections.ts b/database/migrations/dataset_7_collections.ts index 349e147..1e2f53f 100644 --- a/database/migrations/dataset_7_collections.ts +++ b/database/migrations/dataset_7_collections.ts @@ -6,7 +6,7 @@ export default class Collections extends BaseSchema { public async up() { this.schema.createTable(this.tableName, (table) => { table.increments('id').defaultTo("nextval('collections_id_seq')"); - table.integer('role_id').unsigned(); + table.integer('role_id').unsigned(); table .foreign('role_id', 'collections_role_id_foreign') .references('id') @@ -58,4 +58,4 @@ export default class Collections extends BaseSchema { // OWNER to tethys_admin; // REVOKE ALL ON TABLE collections FROM tethys_app; // GRANT ALL ON TABLE collections TO tethys_admin; -// GRANT DELETE, INSERT, SELECT, UPDATE ON TABLE collections TO tethys_app; \ No newline at end of file +// GRANT DELETE, INSERT, SELECT, UPDATE ON TABLE collections TO tethys_app; diff --git a/database/migrations/dataset_8_link_documents_collections.ts b/database/migrations/dataset_8_link_documents_collections.ts index 02b5f8e..44f8229 100644 --- a/database/migrations/dataset_8_link_documents_collections.ts +++ b/database/migrations/dataset_8_link_documents_collections.ts @@ -7,18 +7,18 @@ export default class LinkDocumentsCollections extends BaseSchema { this.schema.createTable(this.tableName, (table) => { table.integer('collection_id').index('link_documents_collections_collection_id_index').notNullable(); table - .foreign('collection_id', 'link_documents_collections_collection_id_foreign') - .references('id') - .inTable('collections') - .onDelete('CASCADE') // don't delete this when collection is deleted - .onUpdate('CASCADE'); + .foreign('collection_id', 'link_documents_collections_collection_id_foreign') + .references('id') + .inTable('collections') + .onDelete('CASCADE') // don't delete this when collection is deleted + .onUpdate('CASCADE'); table.integer('document_id').index('link_documents_collections_document_id_index').notNullable(); table - .foreign('document_id', 'link_documents_collections_document_id_foreign') - .references('id') - .inTable('documents') - .onDelete('CASCADE') // don't delete this when document is deleted - .onUpdate('CASCADE'); + .foreign('document_id', 'link_documents_collections_document_id_foreign') + .references('id') + .inTable('documents') + .onDelete('CASCADE') // don't delete this when document is deleted + .onUpdate('CASCADE'); table.primary(['collection_id', 'document_id']); }); } @@ -56,4 +56,4 @@ export default class LinkDocumentsCollections extends BaseSchema { // -- Index: link_documents_collections_document_id_index // -- DROP INDEX IF EXISTS link_documents_collections_document_id_index; // CREATE INDEX IF NOT EXISTS link_documents_collections_document_id_index -// ON link_documents_collections USING btree (document_id ASC); \ No newline at end of file +// ON link_documents_collections USING btree (document_id ASC); diff --git a/database/migrations/dataset_9_persons.ts b/database/migrations/dataset_9_persons.ts index 9f06bc3..a8d5b23 100644 --- a/database/migrations/dataset_9_persons.ts +++ b/database/migrations/dataset_9_persons.ts @@ -29,7 +29,6 @@ export default class Persons extends BaseSchema { } } - // -- Table: persons // CREATE TABLE IF NOT EXISTS persons // ( diff --git a/database/migrations/files_4_link_documents_licences.ts b/database/migrations/files_4_link_documents_licences.ts index 3515a01..4efa8dd 100644 --- a/database/migrations/files_4_link_documents_licences.ts +++ b/database/migrations/files_4_link_documents_licences.ts @@ -15,12 +15,12 @@ export default class LinkDocumentsLicences extends BaseSchema { // table.index('licence_id', 'link_documents_licences_licence_id_index') table.integer('document_id').index('link_documents_licences_document_id_index').notNullable(); table - .foreign('document_id', 'link_documents_licences_document_id_foreign') - .references('id') - .inTable('documents') - .onDelete('CASCADE') // delete this when document is deleted - .onUpdate(' CASCADE'); - // table.index('licence_id', 'link_documents_licences_document_id_index') + .foreign('document_id', 'link_documents_licences_document_id_foreign') + .references('id') + .inTable('documents') + .onDelete('CASCADE') // delete this when document is deleted + .onUpdate(' CASCADE'); + // table.index('licence_id', 'link_documents_licences_document_id_index') table.primary(['licence_id', 'document_id']); }); } diff --git a/database/migrations/lookup_1_mime_types.ts b/database/migrations/lookup_1_mime_types.ts index 8592c43..08b1bb4 100644 --- a/database/migrations/lookup_1_mime_types.ts +++ b/database/migrations/lookup_1_mime_types.ts @@ -34,4 +34,4 @@ export default class MimeTypes extends BaseSchema { // OWNER to tethys_admin; // REVOKE ALL ON TABLE mime_types FROM tethys_app; // GRANT ALL ON TABLE mime_types TO tethys_admin; -// GRANT DELETE, UPDATE, INSERT, SELECT ON TABLE mime_types TO tethys_app; \ No newline at end of file +// GRANT DELETE, UPDATE, INSERT, SELECT ON TABLE mime_types TO tethys_app; diff --git a/package-lock.json b/package-lock.json index 37f5973..b3cca0c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3848,6 +3848,12 @@ "resolved": "https://registry.npmjs.org/@types/he/-/he-1.2.0.tgz", "integrity": "sha512-uH2smqTN4uGReAiKedIVzoLUAXIYLBTbSofhx3hbNqj74Ua6KqFsLYszduTrLCMEAEAozF73DbGi/SC1bzQq4g==" }, + "node_modules/@types/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==", + "dev": true + }, "node_modules/@types/http-proxy": { "version": "1.17.11", "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.11.tgz", @@ -3941,9 +3947,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.3.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.1.tgz", - "integrity": "sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==" + "version": "20.3.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.2.tgz", + "integrity": "sha512-vOBLVQeCQfIcF/2Y7eKFTqrMnizK5lRNQ7ykML/5RuwVXVWxYkgwS7xbt4B6fKCUPgbSL5FSsjHQpaGQP/dQmw==" }, "node_modules/@types/pino": { "version": "6.3.12", @@ -4027,11 +4033,12 @@ } }, "node_modules/@types/serve-static": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.1.tgz", - "integrity": "sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==", + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.2.tgz", + "integrity": "sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==", "dev": true, "dependencies": { + "@types/http-errors": "*", "@types/mime": "*", "@types/node": "*" } @@ -4094,15 +4101,15 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.60.0.tgz", - "integrity": "sha512-78B+anHLF1TI8Jn/cD0Q00TBYdMgjdOn980JfAVa9yw5sop8nyTfVOQAv6LWywkOGLclDBtv5z3oxN4w7jxyNg==", + "version": "5.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.60.1.tgz", + "integrity": "sha512-KSWsVvsJsLJv3c4e73y/Bzt7OpqMCADUO846bHcuWYSYM19bldbAeDv7dYyV0jwkbMfJ2XdlzwjhXtuD7OY6bw==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.60.0", - "@typescript-eslint/type-utils": "5.60.0", - "@typescript-eslint/utils": "5.60.0", + "@typescript-eslint/scope-manager": "5.60.1", + "@typescript-eslint/type-utils": "5.60.1", + "@typescript-eslint/utils": "5.60.1", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", @@ -4128,14 +4135,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.60.0.tgz", - "integrity": "sha512-jBONcBsDJ9UoTWrARkRRCgDz6wUggmH5RpQVlt7BimSwaTkTjwypGzKORXbR4/2Hqjk9hgwlon2rVQAjWNpkyQ==", + "version": "5.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.60.1.tgz", + "integrity": "sha512-pHWlc3alg2oSMGwsU/Is8hbm3XFbcrb6P5wIxcQW9NsYBfnrubl/GhVVD/Jm/t8HXhA2WncoIRfBtnCgRGV96Q==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.60.0", - "@typescript-eslint/types": "5.60.0", - "@typescript-eslint/typescript-estree": "5.60.0", + "@typescript-eslint/scope-manager": "5.60.1", + "@typescript-eslint/types": "5.60.1", + "@typescript-eslint/typescript-estree": "5.60.1", "debug": "^4.3.4" }, "engines": { @@ -4155,13 +4162,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.60.0.tgz", - "integrity": "sha512-hakuzcxPwXi2ihf9WQu1BbRj1e/Pd8ZZwVTG9kfbxAMZstKz8/9OoexIwnmLzShtsdap5U/CoQGRCWlSuPbYxQ==", + "version": "5.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.60.1.tgz", + "integrity": "sha512-Dn/LnN7fEoRD+KspEOV0xDMynEmR3iSHdgNsarlXNLGGtcUok8L4N71dxUgt3YvlO8si7E+BJ5Fe3wb5yUw7DQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.60.0", - "@typescript-eslint/visitor-keys": "5.60.0" + "@typescript-eslint/types": "5.60.1", + "@typescript-eslint/visitor-keys": "5.60.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4172,13 +4179,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.60.0.tgz", - "integrity": "sha512-X7NsRQddORMYRFH7FWo6sA9Y/zbJ8s1x1RIAtnlj6YprbToTiQnM6vxcMu7iYhdunmoC0rUWlca13D5DVHkK2g==", + "version": "5.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.60.1.tgz", + "integrity": "sha512-vN6UztYqIu05nu7JqwQGzQKUJctzs3/Hg7E2Yx8rz9J+4LgtIDFWjjl1gm3pycH0P3mHAcEUBd23LVgfrsTR8A==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.60.0", - "@typescript-eslint/utils": "5.60.0", + "@typescript-eslint/typescript-estree": "5.60.1", + "@typescript-eslint/utils": "5.60.1", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -4199,9 +4206,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.60.0.tgz", - "integrity": "sha512-ascOuoCpNZBccFVNJRSC6rPq4EmJ2NkuoKnd6LDNyAQmdDnziAtxbCGWCbefG1CNzmDvd05zO36AmB7H8RzKPA==", + "version": "5.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.60.1.tgz", + "integrity": "sha512-zDcDx5fccU8BA0IDZc71bAtYIcG9PowaOwaD8rjYbqwK7dpe/UMQl3inJ4UtUK42nOCT41jTSCwg76E62JpMcg==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4212,13 +4219,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.0.tgz", - "integrity": "sha512-R43thAuwarC99SnvrBmh26tc7F6sPa2B3evkXp/8q954kYL6Ro56AwASYWtEEi+4j09GbiNAHqYwNNZuNlARGQ==", + "version": "5.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.1.tgz", + "integrity": "sha512-hkX70J9+2M2ZT6fhti5Q2FoU9zb+GeZK2SLP1WZlvUDqdMbEKhexZODD1WodNRyO8eS+4nScvT0dts8IdaBzfw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.60.0", - "@typescript-eslint/visitor-keys": "5.60.0", + "@typescript-eslint/types": "5.60.1", + "@typescript-eslint/visitor-keys": "5.60.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -4289,17 +4296,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.60.0.tgz", - "integrity": "sha512-ba51uMqDtfLQ5+xHtwlO84vkdjrqNzOnqrnwbMHMRY8Tqeme8C2Q8Fc7LajfGR+e3/4LoYiWXUM6BpIIbHJ4hQ==", + "version": "5.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.60.1.tgz", + "integrity": "sha512-tiJ7FFdFQOWssFa3gqb94Ilexyw0JVxj6vBzaSpfN/8IhoKkDuSAenUKvsSHw2A/TMpJb26izIszTXaqygkvpQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.60.0", - "@typescript-eslint/types": "5.60.0", - "@typescript-eslint/typescript-estree": "5.60.0", + "@typescript-eslint/scope-manager": "5.60.1", + "@typescript-eslint/types": "5.60.1", + "@typescript-eslint/typescript-estree": "5.60.1", "eslint-scope": "^5.1.1", "semver": "^7.3.7" }, @@ -4337,12 +4344,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.0.tgz", - "integrity": "sha512-wm9Uz71SbCyhUKgcaPRauBdTegUyY/ZWl8gLwD/i/ybJqscrrdVSFImpvUz16BLPChIeKBK5Fa9s6KDQjsjyWw==", + "version": "5.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.1.tgz", + "integrity": "sha512-xEYIxKcultP6E/RMKqube11pGjXH1DCo60mQoWhVYyKfLkwbIVVjYxmOenNMxILx0TjCujPTjjnTIVzm09TXIw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.60.0", + "@typescript-eslint/types": "5.60.1", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -5943,9 +5950,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001506", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001506.tgz", - "integrity": "sha512-6XNEcpygZMCKaufIcgpQNZNf00GEqc7VQON+9Rd0K1bMYo8xhMZRAo5zpbnbMNizi4YNgIDAFrdykWsvY3H4Hw==", + "version": "1.0.30001508", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001508.tgz", + "integrity": "sha512-sdQZOJdmt3GJs1UMNpCCCyeuS2IEGLXnHyAo9yIO5JJDjbjoVRij4M1qep6P6gFpptD1PqIYgzM+gwJbOi92mw==", "dev": true, "funding": [ { @@ -7648,9 +7655,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.436", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.436.tgz", - "integrity": "sha512-aktOxo8fnrMC8vOIBMVS3PXbT1nrPQ+SouUuN7Y0a+Rw3pOMrvIV92Ybnax7x4tugA+ZpYA5fOHTby7ama8OQQ==", + "version": "1.4.441", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.441.tgz", + "integrity": "sha512-LlCgQ8zgYZPymf5H4aE9itwiIWH4YlCiv1HFLmmcBeFYi5E+3eaIFnjHzYtcFQbaKfAW+CqZ9pgxo33DZuoqPg==", "dev": true }, "node_modules/emittery": { @@ -7729,9 +7736,9 @@ } }, "node_modules/envinfo": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.9.0.tgz", - "integrity": "sha512-RODB4txU+xImYDemN5DqaKC0CHk05XSVkOX4pq0hK26Qx+1LChkuOyUDlGEjYb3ACr0n9qBhFjg37hQuJvpkRQ==", + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.10.0.tgz", + "integrity": "sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw==", "dev": true, "peer": true, "bin": { @@ -9571,9 +9578,9 @@ } }, "node_modules/html-entities": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.6.tgz", - "integrity": "sha512-9o0+dcpIw2/HxkNuYKxSJUF/MMRZQECK4GnF+oQOmJ83yCVHTWgCH5aOXxK5bozNRmM8wtgryjHD3uloPBDEGw==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz", + "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==", "funding": [ { "type": "github", @@ -12377,14 +12384,14 @@ } }, "node_modules/pg": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.0.tgz", - "integrity": "sha512-meLUVPn2TWgJyLmy7el3fQQVwft4gU5NGyvV0XbD41iU9Jbg8lCH4zexhIkihDzVHJStlt6r088G6/fWeNjhXA==", + "version": "8.11.1", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.1.tgz", + "integrity": "sha512-utdq2obft07MxaDg0zBJI+l/M3mBRfIpEN3iSemsz0G5F2/VXx+XzqF4oxrbIZXQxt2AZzIUzyVg/YM6xOP/WQ==", "dependencies": { "buffer-writer": "2.0.0", "packet-reader": "1.0.0", - "pg-connection-string": "^2.6.0", - "pg-pool": "^3.6.0", + "pg-connection-string": "^2.6.1", + "pg-pool": "^3.6.1", "pg-protocol": "^1.6.0", "pg-types": "^2.1.0", "pgpass": "1.x" @@ -12393,7 +12400,7 @@ "node": ">= 8.0.0" }, "optionalDependencies": { - "pg-cloudflare": "^1.1.0" + "pg-cloudflare": "^1.1.1" }, "peerDependencies": { "pg-native": ">=3.0.1" @@ -12405,9 +12412,9 @@ } }, "node_modules/pg-cloudflare": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.0.tgz", - "integrity": "sha512-tGM8/s6frwuAIyRcJ6nWcIvd3+3NmUKIs6OjviIm1HPPFEt5MzQDOTBQyhPWg/m0kCl95M6gA1JaIXtS8KovOA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", + "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", "optional": true }, "node_modules/pg-connection-string": { @@ -12424,9 +12431,9 @@ } }, "node_modules/pg-pool": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.0.tgz", - "integrity": "sha512-clFRf2ksqd+F497kWFyM21tMjeikn60oGDmqMT8UBrynEwVEX/5R5xd2sdvdo1cZCFlguORNpVuqxIj+aK4cfQ==", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz", + "integrity": "sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==", "peerDependencies": { "pg": ">=8.0" } @@ -12452,9 +12459,9 @@ } }, "node_modules/pg/node_modules/pg-connection-string": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.0.tgz", - "integrity": "sha512-x14ibktcwlHKoHxx9X3uTVW9zIGR41ZB6QNhHb21OPNdCCO3NaRnpJuwKIQSR4u+Yqjx4HCvy7Hh7VSy1U4dGg==" + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.1.tgz", + "integrity": "sha512-w6ZzNu6oMmIzEAYVw+RLK0+nqHPt8K3ZnknKi+g48Ak2pr3dtljJW3o+D/n2zzCG07Zoe9VOX3aiKpj+BN0pjg==" }, "node_modules/pgpass": { "version": "1.0.5", @@ -12622,9 +12629,9 @@ } }, "node_modules/pino-std-serializers": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.1.tgz", - "integrity": "sha512-wHuWB+CvSVb2XqXM0W/WOYUkVSPbiJb9S5fNB7TBhd8s892Xq910bRxwHtC4l71hgztObTjXL6ZheZXFjhDrDQ==" + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.2.tgz", + "integrity": "sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==" }, "node_modules/pino/node_modules/pino-std-serializers": { "version": "3.2.0", @@ -14206,9 +14213,9 @@ } }, "node_modules/semver": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", - "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", "dependencies": { "lru-cache": "^6.0.0" }, @@ -15843,9 +15850,9 @@ } }, "node_modules/tslib": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==" + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz", + "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==" }, "node_modules/tsscmp": { "version": "1.0.6", @@ -17001,9 +17008,9 @@ } }, "node_modules/youch-terminal": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/youch-terminal/-/youch-terminal-2.2.0.tgz", - "integrity": "sha512-LLYtvG/4XoRO/vhf2eBkzT6dI1hWliLSp7NuXRKsvBAITuIxODS61X7AQOHl5Aaf8oquS9JlHSpjTFjX140XKA==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/youch-terminal/-/youch-terminal-2.2.1.tgz", + "integrity": "sha512-enW8MxCaZKbss1zwJEP5IGP7b3/QWOc00payGqMaCzfia+QnFJYg0rLrboHXLd/rLsISc2VpRWaTqMsY8kmfMw==", "dev": true, "dependencies": { "kleur": "^4.1.5", diff --git a/providers/AppProvider.ts b/providers/AppProvider.ts index 9e65fb2..37e29b6 100644 --- a/providers/AppProvider.ts +++ b/providers/AppProvider.ts @@ -1,5 +1,7 @@ import type { ApplicationContract } from '@ioc:Adonis/Core/Application'; -import Hash from '@ioc:Adonis/Core/Hash'; +import type Hash from '@ioc:Adonis/Core/Hash'; +// import HttpContextContract from '@ioc:Adonis/Core/HttpContext'; +import type Response from '@ioc:Adonis/Core/Response'; import { LaravelHash } from './HashDriver'; export default class AppProvider { @@ -15,6 +17,22 @@ export default class AppProvider { hashInstance.extend('bcrypt', () => { return new LaravelHash(); }); + + const responseInstance: typeof Response = this.app.container.use('Adonis/Core/Response'); + responseInstance.macro('flash', function (key: string, message: any) { + this.ctx!.session.flash(key, message); + return this; + }); + responseInstance.macro('toRoute', function (route: string) { + this.redirect().toRoute(route); + return this; + }); + // this.app.container.singleton('Adonis/Core/Response', () => { + // return FlashResponse; + // }); + + // this.app.container.singleton('Adonis/Core/HttpContext', () => { + // }); } public async ready() { diff --git a/providers/HashDriver/index.ts b/providers/HashDriver/index.ts index 7d0b141..ff288ae 100644 --- a/providers/HashDriver/index.ts +++ b/providers/HashDriver/index.ts @@ -1,6 +1,6 @@ -import { HashDriverContract } from "@ioc:Adonis/Core/Hash"; +import { HashDriverContract } from '@ioc:Adonis/Core/Hash'; // const bcrypt = require("bcrypt"); -import bcrypt from "bcryptjs"; +import bcrypt from 'bcryptjs'; const saltRounds = 10; export class LaravelHash implements HashDriverContract { @@ -11,11 +11,11 @@ export class LaravelHash implements HashDriverContract { public async verify(hashedValue: string, plainValue: string) { let newHash: string; - if (hashedValue.includes("$2y$10$")) { - newHash = hashedValue.replace("$2y$10$", "$2a$10$"); + if (hashedValue.includes('$2y$10$')) { + newHash = hashedValue.replace('$2y$10$', '$2a$10$'); } else { newHash = hashedValue; } return await bcrypt.compareSync(plainValue, newHash); } -} \ No newline at end of file +} diff --git a/resources/js/Components/AsideMenuItem.vue b/resources/js/Components/AsideMenuItem.vue index c9ef856..8bd0537 100644 --- a/resources/js/Components/AsideMenuItem.vue +++ b/resources/js/Components/AsideMenuItem.vue @@ -31,7 +31,7 @@ const hasColor = computed(() => props.item && props.item.color); const isDropdownActive = ref(false); const componentClass = computed(() => [ - props.isDropdownList ? 'py-3 px-6 text-sm' : 'py-3 px-6', + props.isDropdownList ? 'py-3 px-6 text-sm font-semibold' : 'py-3 px-6', hasColor.value ? getButtonColor(props.item.color, false, true) : styleService.asideMenuItemStyle, ]); @@ -76,18 +76,19 @@ const is = computed(() => { + @click.prevent="menuClick" v-bind:target="props.item.target ?? null"> {{ item.label }} - + + - + ]" is-dropdown-list /> diff --git a/resources/js/Components/AsideMenuLayer.vue b/resources/js/Components/AsideMenuLayer.vue index a571f46..1a61312 100644 --- a/resources/js/Components/AsideMenuLayer.vue +++ b/resources/js/Components/AsideMenuLayer.vue @@ -55,7 +55,7 @@ const menuClick = (event, item) => {
- +