Page MenuHomeSealhub

deep-reverse-single-reference-list.ts
No OneTemporary

deep-reverse-single-reference-list.ts

import { Context } from "koa";
import { CollectionItem, FieldTypes as SealiousFieldTypes } from "sealious";
import { FormDataValue, FormData } from "../form-types.js";
import { CheckboxedListField } from "./checkboxed-list.js";
import { ExtractedFieldInfo } from "../../utils/extract-fields-from-collection.js";
export class DeepReverseSingleReferenceList extends CheckboxedListField<false> {
public item_label_getter: (item: CollectionItem<any>) => string = (item) =>
item.get("name") as string;
constructor(
public sealious_field: SealiousFieldTypes.DeepReverseSingleReference
) {
super(false, async (ctx: Context) => {
const { items } = await ctx.$app.collections["${target}"]
.list(ctx.$context)
.fetch();
return items.map((s) => ({
label: this.item_label_getter(s),
value: s.id,
}));
});
}
setItemLabelGetter(getter: (item: CollectionItem<any>) => string) {
this.item_label_getter = getter;
}
getSealiousCreateValue(): never {
throw new Error(
"This field is not set directly through field value, but instead relies on postSealiousCreate and postSealiousEdit"
);
}
async postSealiousCreate(
ctx: Context,
created_item: CollectionItem<any>,
form_data: FormData
) {
// First, we remove links refering to current item
const { items: existing_links } = await ctx.$app.collections[
this.sealious_field.intermediary_collection
]
.list(ctx.$context)
.filter({
[this.sealious_field.referencing_field]: created_item.id,
})
.fetch();
const value = this.getParsedValue(ctx, form_data.raw_values, false);
const should_exist_ids = Object.entries(value || {})
.filter(([, value]) => value === "on")
.map(([key]) => key);
const to_delete = existing_links.filter(
(link) =>
!should_exist_ids.includes(
link.get(
this.sealious_field.intermediary_field_that_points_there
) as string
)
);
const to_create_ids = should_exist_ids.filter(
(id) =>
!existing_links
.map(
(link) =>
this.sealious_field
.intermediary_field_that_points_there
)
.includes(id)
);
await Promise.all(to_delete.map((item) => item.remove(ctx.$context)));
// Then, we iterate over all selected values and insert appropriate missing links
const promises = to_create_ids.map(async (id) => {
await this.sealious_field
.getReferencingCollection()
.create(ctx.$context, {
[this.sealious_field.referencing_field]: created_item.id,
[this.sealious_field.intermediary_field_that_points_there]:
id,
});
});
await Promise.all(promises);
}
async postSealiousEdit(
ctx: Context,
edited_item: CollectionItem<any>,
value: FormData
) {
return this.postSealiousCreate(ctx, edited_item, value);
}
async sealiousValueToForm(
ctx: Context,
item: CollectionItem<any>
): Promise<FormDataValue> {
return Object.fromEntries(
((item.get(this.sealious_field.name) as string[]) || []).map(
(id) => [id, "on"]
)
);
}
getFieldDeclaration(
field_info: ExtractedFieldInfo,
vars: { form_field_types: string; sealious_field: string }
): string {
return `new ${vars.form_field_types}.${this.constructor.name}(${vars.sealious_field})`;
}
}

File Metadata

Mime Type
text/x-java
Expires
Sun, Nov 2, 16:58 (13 h, 44 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1030449
Default Alt Text
deep-reverse-single-reference-list.ts (3 KB)

Event Timeline