Bug 38201: Migrate AgreementRelationships to RelationshipWidget

Signed-off-by: Michaela Sieber <michaela.sieber@kit.edu>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This commit is contained in:
Matt Blenkinsop 2025-01-29 12:58:19 +00:00 committed by Lucas Gass
parent c825932f2f
commit be28447afd
No known key found for this signature in database
GPG Key ID: 60B447398B0D36CA
6 changed files with 83 additions and 165 deletions

View File

@ -62,6 +62,32 @@ export default {
const currentValue = acc[key];
acc[key] = !!currentValue;
}
if (prop.type === "filter") {
Object.keys(prop.keys).forEach(k => {
if (
prop.keys[k].hasOwnProperty("filterType") &&
prop.keys[k].filterType
) {
acc[key] = {
[k]: {
[prop.keys[k].filterType]:
this.accessNestedProperty(
prop.keys[k].property,
this.resource
),
},
};
} else {
acc[key] = {
[k]: this.accessNestedProperty(
prop.keys[k].property,
this.resource
),
};
}
});
}
return acc;
}, {});
const attr = show ? this.attr.showElement : this.attr;

View File

@ -1,143 +0,0 @@
<template>
<fieldset class="rows" id="agreement_relationships">
<legend>{{ $__("Related agreements") }}</legend>
<fieldset
:id="`related_agreement_${counter}`"
class="rows"
v-for="(relationship, counter) in relationships"
v-bind:key="counter"
>
<legend>
{{ $__("Related agreement %s").format(counter + 1) }}
<a href="#" @click.prevent="deleteRelationship(counter)"
><i class="fa fa-trash"></i>
{{ $__("Remove this relationship") }}</a
>
</legend>
<ol>
<li v-for="(attr, index) in subFields" v-bind:key="index">
<FormElement
:resource="relationship"
:attr="attr"
:index="counter"
:options="agreements"
/>
</li>
<!-- <li>
<label
:for="`related_agreement_id_${counter}`"
class="required"
>{{ $__("Related agreement") }}:
</label>
<v-select
:id="`related_agreement_id_${counter}`"
v-model="relationship.related_agreement_id"
label="name"
:reduce="a => a.agreement_id"
:options="agreements"
>
<template #search="{ attributes, events }">
<input
:required="!relationship.related_agreement_id"
class="vs__search"
v-bind="attributes"
v-on="events"
/>
</template>
</v-select>
<span class="required">{{ $__("Required") }}</span>
</li>
<li>
<label
:for="`related_agreement_relationship_${counter}`"
class="required"
>{{ $__("Relationship") }}:
</label>
<v-select
:id="`related_agreement_relationship_${counter}`"
v-model="relationship.relationship"
label="description"
:reduce="av => av.value"
:options="av_agreement_relationships"
>
<template #search="{ attributes, events }">
<input
:required="!relationship.relationship"
class="vs__search"
v-bind="attributes"
v-on="events"
/>
</template>
</v-select>
<span class="required">{{ $__("Required") }}</span>
</li>
<li>
<label :for="`related_agreement_notes_${counter}`"
>{{ $__("Notes") }}:</label
>
<input
:id="`related_agreement_notes_${counter}`"
v-model="relationship.notes"
:placeholder="$__('Notes')"
/>
</li> -->
</ol>
</fieldset>
<a
v-if="agreements.length"
class="btn btn-default"
@click="addRelationship"
><font-awesome-icon icon="plus" />
{{ $__("Add new related agreement") }}</a
>
<span v-else>{{
$__("There are no other agreements created yet")
}}</span>
</fieldset>
</template>
<script>
import { APIClient } from "../../fetch/api-client.js";
import FormElement from "../FormElement.vue";
export default {
components: { FormElement },
data() {
return {
agreements: [],
};
},
beforeCreate() {
const client = APIClient.erm;
client.agreements
.getAll({ "me.agreement_id": { "!=": this.agreement_id } })
.then(
agreements => {
this.agreements = agreements;
this.initialized = true;
},
error => {}
);
},
methods: {
addRelationship() {
this.relationships.push({
related_agreement_id: null,
relationship: null,
notes: "",
});
},
deleteRelationship(counter) {
this.relationships.splice(counter, 1);
},
},
props: {
agreement_id: Number,
av_agreement_relationships: Array,
relationships: Array,
subFields: Array,
},
name: "AgreementRelationships",
};
</script>

View File

@ -233,7 +233,7 @@ export default {
},
{
name: "periods",
type: "relationship",
type: "relationshipWidget",
showElement: {
type: "table",
columnData: "periods",
@ -418,7 +418,7 @@ export default {
},
{
name: "licenses",
type: "relationship",
type: "relationshipWidget",
label: __("Licenses"),
showElement: {
type: "table",
@ -541,8 +541,8 @@ export default {
},
{
name: "relationships",
type: "relationship",
componentPath: "./ERM/AgreementRelationships.vue",
type: "relationshipWidget",
label: __("Relationships"),
showElement: {
type: "component",
hidden: agreement =>
@ -556,19 +556,37 @@ export default {
},
},
},
apiClient: APIClient.erm.agreements,
props: {
agreement_id: {
type: "resourceProperty",
resourceProperty: "agreement_id",
newRelationship: {
type: "object",
value: {
related_agreement_id: null,
relationship: null,
notes: "",
},
},
av_agreement_relationships: {
type: "av",
av: null,
},
relationships: {
resourceRelationships: {
type: "resourceProperty",
resourceProperty: "agreement_relationships",
},
resourceName: {
type: "string",
value: "relationship",
},
filters: {
type: "filter",
keys: {
"me.agreement_id": {
property: "agreement_id",
filterType: "!=",
},
},
},
fetchOptions: {
type: "boolean",
value: true,
},
},
subFields: [
{
@ -577,12 +595,14 @@ export default {
label: __("Related agreement"),
requiredKey: "agreement_id",
selectLabel: "name",
required: true,
},
{
name: "relationship",
type: "select",
label: __("Relationship"),
avCat: "av_agreement_relationships",
required: true,
},
{
name: "notes",

View File

@ -122,11 +122,7 @@
v-on="getEventHandlers()"
></component>
</template>
<template
v-else-if="
attr.type == 'relationship' && !attr.componentPath && attr.props
"
>
<template v-else-if="attr.type == 'relationshipWidget'">
<component
:is="relationshipWidget"
:title="attr.label"

View File

@ -25,6 +25,7 @@
:resource="resourceRelationship"
:attr="attr"
:index="counter"
v-bind="handleOptions()"
/>
</li>
</ol>
@ -55,6 +56,7 @@ export default {
data() {
return {
resourceRelationshipCount: null,
options: null,
};
},
props: {
@ -65,13 +67,18 @@ export default {
apiClient: Object,
newRelationship: Object,
filters: Object,
fetchOptions: Boolean,
},
beforeCreate() {
if (this.apiClient) {
this.apiClient.count().then(
count => {
this.resourceRelationshipCount = count;
this.initialized = true;
if (this.fetchOptions) {
this.getSelectOptions(this.filters);
} else {
this.resourceRelationshipCount = count;
this.initialized = true;
}
},
error => {}
);
@ -87,6 +94,18 @@ export default {
deleteResourceRelationship(counter) {
this.resourceRelationships.splice(counter, 1);
},
getSelectOptions(filters) {
const searchFilters = filters ? filters : {};
this.apiClient.getAll(searchFilters).then(options => {
this.options = options;
this.resourceRelationshipCount = options.length;
this.initialized = true;
});
},
handleOptions() {
if (!this.options) return {};
return { options: this.options };
},
},
components: {
FormElement,

View File

@ -33,8 +33,8 @@
</ol>
</fieldset>
<template
v-for="(attr, index) in resourceAttrs.filter(
attr => attr.type === 'relationship'
v-for="(attr, index) in resourceAttrs.filter(attr =>
attr.type.includes('relationship')
)"
v-bind:key="'rel-' + index"
>
@ -94,7 +94,7 @@ export default {
},
getFieldGroupings() {
const nonRelationalFields = this.resourceAttrs.filter(
attr => attr.type !== "relationship"
attr => !attr.type.includes("relationship")
);
const groupings = nonRelationalFields.reduce((acc, attr) => {
if (