Files
directus/app/src/stores/relations.ts
Rijk van Zanten 2720e0c18e Add new field flow (#9109)
* Add new grouping setup to interfaces

* [WIP] Start on new field flow

* Add preview svgs

* Update preview svg

* Add basic saving mechanism. Start on magic

* Add interface options to simple inputs

* Fix missing t

* Fix custom options not rendering

* Fix interface options overrides

* Sync m2o name key

* Setup m2o related collection input

* Add collections generation

* Add circular prevention & type syncing

* Small fixes in m2o context generation

* Move o2m options to fn structure

* Conclude o2m (i think)

* Start on toggle to advanced

* Style advanced toggle button

* Add localType File support, start documenting

* Add presentation/group localtypes

* Use function style interface options in m2m

* Don't require collection prop in field template component

* Implement most of m2m magic

* Restructure store updater

* Finish useFieldDetailStore restructure

* Only register root index in module folders

* Do the thing

* Finish m2m magic, tweak fallback styles

* Fix o2m display template setup

* Remove options comp for translations interface

* Show languages collection picker in translations

* Finish translations alterations

* Add magic for files type

* Officially wave goodbye to the old store setup

It served it's purpose, but what a nightmare to maintain. Welcome to the new version

* Update schema tab

* Add field pane

* Finish interface section

* Add display section

* Add conditions

* Update tabs to use localType from store

* Start on relationship tab

* Update m2m relational setup

* Start on m2o

* Finish m2o setup

* Finish o2m setup

* Add m2a magic

* Various tweaks

* Add m2a setup

* Add save button to advanced flow

* Load existing values on start

* Add upsert to stores, allow updating existing items

* Please the linter gods

* Remove seemingly redundant interface option

@Oreilles Seeing the geometry type is already configured in the schema configuration, this particular option on the interface feels redundant (?)

* Remove unnecessary option component overrides

* Track relationships in required fields for save state

* Fix relations previews on editing existing fields

* Use standard vs advanced for input options

* Remove note from simple field setup

* Add divider to field config

* Use background subdued

* Default required to false

* Add required icons to key/relationship

* Tweak colors

* Fix infinite loop in group creation

* Make setup responsive

* Allow switching interface at will

* Add m2a related collections picker

* Fix relations persisting on field deletion

* Add "Create in Advanced" shortcut

Just for you @joselcvarela

* Fix PK field staging on collection create

* Revert "Remove seemingly redundant interface option"

This reverts commit e5e09a051e.

* Fix map interface options
2021-10-25 20:29:04 -04:00

109 lines
3.6 KiB
TypeScript

import api from '@/api';
import { useFieldsStore } from '@/stores/';
import { unexpectedError } from '@/utils/unexpected-error';
import { Relation, DeepPartial } from '@directus/shared/types';
import { isEqual } from 'lodash';
import { defineStore } from 'pinia';
export const useRelationsStore = defineStore({
id: 'relationsStore',
state: () => ({
relations: [] as Relation[],
}),
actions: {
async hydrate() {
const response = await api.get(`/relations`, { params: { limit: -1 } });
this.relations = response.data.data;
},
async dehydrate() {
this.$reset();
},
getRelationsForCollection(collection: string) {
return this.relations.filter((relation) => {
return relation.collection === collection || relation.related_collection === collection;
});
},
async upsertRelation(collection: string, field: string, values: DeepPartial<Relation>) {
const existing = this.getRelationForField(collection, field);
try {
if (existing) {
if (isEqual(existing, values)) return;
const updatedRelationResponse = await api.patch<{ data: Relation }>(
`/relations/${collection}/${field}`,
values
);
this.relations = this.relations.map((relation) => {
if (relation.collection === collection && relation.field === field) {
return updatedRelationResponse.data.data;
}
return relation;
});
} else {
const createdRelationResponse = await api.post<{ data: Relation }>(`/relations`, values);
this.relations = [...this.relations, createdRelationResponse.data.data];
}
} catch (err: any) {
unexpectedError(err);
}
},
/**
* Retrieve all relation rows that apply to the current field. Regardless of relational direction
*/
getRelationsForField(collection: string, field: string): Relation[] {
const fieldsStore = useFieldsStore();
const fieldInfo = fieldsStore.getField(collection, field);
if (!fieldInfo) return [];
const relations: Relation[] = this.getRelationsForCollection(collection).filter((relation: Relation) => {
return (
(relation.collection === collection && relation.field === field) ||
(relation.related_collection === collection && relation.meta?.one_field === field)
);
});
if (relations.length > 0) {
const isM2M = relations[0].meta?.junction_field !== null;
// If the relation matching the field has a junction field, it's a m2m. In that case,
// we also want to return the secondary relationship (from the jt to the related)
// so any ui elements (interfaces) can utilize the full relationship
if (isM2M) {
const secondaryRelation = this.relations.find((relation) => {
return (
relation.collection === relations[0].collection && relation.field === relations[0].meta?.junction_field
);
});
if (secondaryRelation) relations.push(secondaryRelation);
}
}
return relations;
},
/**
* Retrieve the passed fields relationship. This is only the current m2o foreign key relationship
*/
getRelationForField(collection: string, field: string): Relation | null {
const fieldsStore = useFieldsStore();
const fieldInfo = fieldsStore.getField(collection, field);
if (!fieldInfo) return null;
const relations: Relation[] = this.getRelationsForCollection(collection).filter((relation: Relation) => {
return (
(relation.collection === collection && relation.field === field) ||
(relation.related_collection === collection && relation.meta?.one_field === field)
);
});
return relations.find((relation) => relation.collection === collection && relation.field === field) || null;
},
},
});