From f89b119b18163952cbc5c431df4160a7f66a6882 Mon Sep 17 00:00:00 2001
From: Arno Kaimbacher
Date: Mon, 31 Mar 2025 15:14:34 +0200
Subject: [PATCH] hotfix (dashboard): display allow email contact in card box
client
- Added the `allowEmailContact` property to the `CardBoxClient` component to display the email contact status.
- Added the `allowEmailContact` computed property to the `Person` model to determine if email contact is allowed based on the related datasets.
- Preloaded the datasets relation in the `AuthorsController` to access the pivot attributes.
- Updated the `Dashboard.vue` to pass the `allowEmailContact` prop to the `CardBoxClient` component.
- Updated the `array_contains_types` validation rule to correct the error message for descriptions.
- Updated the `FormCheckRadio.vue` to correctly handle the radio button and checkbox components.
---
app/Controllers/Http/Api/AuthorsController.ts | 1 +
app/models/person.ts | 15 ++++--
resources/js/Components/CardBoxClient.vue | 9 ++--
resources/js/Components/FormCheckRadio.vue | 50 ++++---------------
resources/js/Pages/Dashboard.vue | 1 +
start/rules/array_contains_types.ts | 4 +-
6 files changed, 31 insertions(+), 49 deletions(-)
diff --git a/app/Controllers/Http/Api/AuthorsController.ts b/app/Controllers/Http/Api/AuthorsController.ts
index 111c219..7209699 100644
--- a/app/Controllers/Http/Api/AuthorsController.ts
+++ b/app/Controllers/Http/Api/AuthorsController.ts
@@ -9,6 +9,7 @@ export default class AuthorsController {
// where exists (select * from gba.documents inner join gba.link_documents_persons on "documents"."id" = "link_documents_persons"."document_id"
// where ("link_documents_persons"."role" = 'author') and ("persons"."id" = "link_documents_persons"."person_id"));
const authors = await Person.query()
+ .preload('datasets')
.where('name_type', 'Personal')
.whereHas('datasets', (dQuery) => {
dQuery.wherePivot('role', 'author');
diff --git a/app/models/person.ts b/app/models/person.ts
index 4e6b60b..cdc612d 100644
--- a/app/models/person.ts
+++ b/app/models/person.ts
@@ -3,7 +3,7 @@ import { DateTime } from 'luxon';
import dayjs from 'dayjs';
import Dataset from './dataset.js';
import BaseModel from './base_model.js';
-import type { ManyToMany } from "@adonisjs/lucid/types/relations";
+import type { ManyToMany } from '@adonisjs/lucid/types/relations';
export default class Person extends BaseModel {
public static namingStrategy = new SnakeCaseNamingStrategy();
@@ -64,9 +64,8 @@ export default class Person extends BaseModel {
// return '2023-03-21 08:45:00';
// }
-
@computed({
- serializeAs: 'dataset_count',
+ serializeAs: 'dataset_count',
})
public get datasetCount() {
const stock = this.$extras.datasets_count; //my pivot column name was "stock"
@@ -79,6 +78,16 @@ export default class Person extends BaseModel {
return contributor_type;
}
+ @computed({ serializeAs: 'allow_email_contact' })
+ public get allowEmailContact() {
+ // If the datasets relation is missing or empty, return false instead of null.
+ if (!this.datasets || this.datasets.length === 0) {
+ return false;
+ }
+ // Otherwise return the pivot attribute from the first related dataset.
+ return this.datasets[0].$extras?.pivot_allow_email_contact;
+ }
+
@manyToMany(() => Dataset, {
pivotForeignKey: 'person_id',
pivotRelatedForeignKey: 'document_id',
diff --git a/resources/js/Components/CardBoxClient.vue b/resources/js/Components/CardBoxClient.vue
index b89ed7a..cd9bf57 100644
--- a/resources/js/Components/CardBoxClient.vue
+++ b/resources/js/Components/CardBoxClient.vue
@@ -39,6 +39,10 @@ const props = defineProps({
type: String,
default: null,
},
+ allowEmailContact: {
+ type: Boolean,
+ default: false,
+ }
});
const pillType = computed(() => {
@@ -81,9 +85,8 @@ const pillType = computed(() => {
{{ name }}
-
-
- {{ email }}
+
+
{{ email }}
diff --git a/resources/js/Components/FormCheckRadio.vue b/resources/js/Components/FormCheckRadio.vue
index ca27675..5d22212 100644
--- a/resources/js/Components/FormCheckRadio.vue
+++ b/resources/js/Components/FormCheckRadio.vue
@@ -1,7 +1,6 @@
diff --git a/resources/js/Pages/Dashboard.vue b/resources/js/Pages/Dashboard.vue
index b1ddc6a..5174274 100644
--- a/resources/js/Pages/Dashboard.vue
+++ b/resources/js/Pages/Dashboard.vue
@@ -113,6 +113,7 @@ const userHasRoles = (roleNames: Array): boolean => {
:date="client.created_at"
:text="client.identifier_orcid"
:count="client.dataset_count"
+
/>
diff --git a/start/rules/array_contains_types.ts b/start/rules/array_contains_types.ts
index 30c2363..fdb05ed 100644
--- a/start/rules/array_contains_types.ts
+++ b/start/rules/array_contains_types.ts
@@ -53,9 +53,9 @@ async function arrayContainsTypes(value: unknown, options: Options, field: Field
} else if (field.getFieldPath() === 'descriptions') {
// For descriptions we expect one abstracts description and minimum one translated description.
if (!hasTypeA && !hasTypeB) {
- errorMessage = 'For descriptions, define one abstracts description and minimum one translated description.';
+ errorMessage = 'For descriptions, define one abstract description and minimum one translated description.';
} else if (!hasTypeA) {
- errorMessage = 'For descriptions, define one abstracts description.';
+ errorMessage = 'For descriptions, define one abstract description.';
} else if (!hasTypeB) {
errorMessage = 'For descriptions, define minimum one translated description.';
}