Added chronology events, removed eras
This commit is contained in:
parent
e91642616d
commit
4fd59464ba
|
@ -1,87 +0,0 @@
|
||||||
import { CollectionConfig } from "payload/types";
|
|
||||||
import { mustBeAdmin } from "../../accesses/collections/mustBeAdmin";
|
|
||||||
import { CollectionGroups, Collections } from "../../constants";
|
|
||||||
import { backPropagationField } from "../../fields/backPropagationField/backPropagationField";
|
|
||||||
import { rowField } from "../../fields/rowField/rowField";
|
|
||||||
import { slugField } from "../../fields/slugField/slugField";
|
|
||||||
import { translatedFields } from "../../fields/translatedFields/translatedFields";
|
|
||||||
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
|
||||||
import { createEditor } from "../../utils/editor";
|
|
||||||
import { getAllEndpoint } from "./endpoints/getAllEndpoint";
|
|
||||||
import { importFromStrapi } from "./endpoints/importFromStrapi";
|
|
||||||
import { beforeValidateEndingGreaterThanStarting } from "./hooks/beforeValidateEndingGreaterThanStarting";
|
|
||||||
import { beforeValidateNoIntersection } from "./hooks/beforeValidateNoIntersection";
|
|
||||||
|
|
||||||
const fields = {
|
|
||||||
slug: "slug",
|
|
||||||
startingYear: "startingYear",
|
|
||||||
endingYear: "endingYear",
|
|
||||||
translations: "translations",
|
|
||||||
translationsTitle: "title",
|
|
||||||
translationsDescription: "description",
|
|
||||||
events: "events",
|
|
||||||
} as const satisfies Record<string, string>;
|
|
||||||
|
|
||||||
export const ChronologyEras: CollectionConfig = buildCollectionConfig({
|
|
||||||
slug: Collections.ChronologyEras,
|
|
||||||
labels: {
|
|
||||||
singular: "Chronology Era",
|
|
||||||
plural: "Chronology Eras",
|
|
||||||
},
|
|
||||||
defaultSort: fields.startingYear,
|
|
||||||
admin: {
|
|
||||||
group: CollectionGroups.Collections,
|
|
||||||
defaultColumns: [fields.slug, fields.startingYear, fields.endingYear, fields.translations],
|
|
||||||
useAsTitle: fields.slug,
|
|
||||||
},
|
|
||||||
access: {
|
|
||||||
create: mustBeAdmin,
|
|
||||||
delete: mustBeAdmin,
|
|
||||||
},
|
|
||||||
hooks: {
|
|
||||||
beforeValidate: [beforeValidateEndingGreaterThanStarting, beforeValidateNoIntersection],
|
|
||||||
},
|
|
||||||
endpoints: [importFromStrapi, getAllEndpoint],
|
|
||||||
fields: [
|
|
||||||
slugField({ name: fields.slug }),
|
|
||||||
rowField([
|
|
||||||
{
|
|
||||||
name: fields.startingYear,
|
|
||||||
type: "number",
|
|
||||||
min: 0,
|
|
||||||
required: true,
|
|
||||||
admin: { description: "The year the era started (year included)" },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: fields.endingYear,
|
|
||||||
type: "number",
|
|
||||||
min: 0,
|
|
||||||
required: true,
|
|
||||||
admin: { description: "The year the era ended (year included)" },
|
|
||||||
},
|
|
||||||
]),
|
|
||||||
translatedFields({
|
|
||||||
name: fields.translations,
|
|
||||||
admin: { useAsTitle: fields.translationsTitle },
|
|
||||||
fields: [
|
|
||||||
{ name: fields.translationsTitle, type: "text", required: true },
|
|
||||||
{
|
|
||||||
name: fields.translationsDescription,
|
|
||||||
type: "richText",
|
|
||||||
editor: createEditor({ inlines: true, lists: true, links: true }),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
backPropagationField({
|
|
||||||
name: fields.events,
|
|
||||||
hasMany: true,
|
|
||||||
relationTo: Collections.ChronologyItems,
|
|
||||||
where: ({ startingYear, endingYear }) => ({
|
|
||||||
and: [
|
|
||||||
{ "date.year": { greater_than_equal: startingYear } },
|
|
||||||
{ "date.year": { less_than_equal: endingYear } },
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
});
|
|
|
@ -1,99 +0,0 @@
|
||||||
import payload from "payload";
|
|
||||||
import { Collections } from "../../../constants";
|
|
||||||
import { EndpointEra } from "../../../sdk";
|
|
||||||
import { ChronologyEra, ChronologyItem } from "../../../types/collections";
|
|
||||||
import { CollectionEndpoint } from "../../../types/payload";
|
|
||||||
import { isDefined, isPayloadArrayType, isPayloadType } from "../../../utils/asserts";
|
|
||||||
import { handleRecorder } from "../../../utils/endpoints";
|
|
||||||
|
|
||||||
export const getAllEndpoint: CollectionEndpoint = {
|
|
||||||
method: "get",
|
|
||||||
path: "/all",
|
|
||||||
handler: async (req, res) => {
|
|
||||||
if (!req.user) {
|
|
||||||
return res.status(403).send({
|
|
||||||
errors: [
|
|
||||||
{
|
|
||||||
message: "You are not allowed to perform this action.",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const eras: ChronologyEra[] = (
|
|
||||||
await payload.find({
|
|
||||||
collection: Collections.ChronologyEras,
|
|
||||||
pagination: false,
|
|
||||||
})
|
|
||||||
).docs;
|
|
||||||
|
|
||||||
const result = eras.map<EndpointEra>(
|
|
||||||
({ endingYear, startingYear, slug, translations, events: items }) => ({
|
|
||||||
slug,
|
|
||||||
startingYear,
|
|
||||||
endingYear,
|
|
||||||
translations:
|
|
||||||
translations?.map(({ language, title, description }) => ({
|
|
||||||
language: isPayloadType(language) ? language.id : language,
|
|
||||||
title,
|
|
||||||
...(description ? { description } : {}),
|
|
||||||
})) ?? [],
|
|
||||||
items:
|
|
||||||
items
|
|
||||||
?.filter(isPayloadType<ChronologyItem>)
|
|
||||||
.sort((a, b) => {
|
|
||||||
const aYear = a.date.year;
|
|
||||||
const bYear = b.date.year;
|
|
||||||
if (aYear !== bYear) return aYear - bYear;
|
|
||||||
const aMonth = a.date.month ?? 0;
|
|
||||||
const bMonth = b.date.month ?? 0;
|
|
||||||
if (aMonth !== bMonth) return aMonth - bMonth;
|
|
||||||
const aDay = a.date.day ?? 0;
|
|
||||||
const bDay = b.date.day ?? 0;
|
|
||||||
if (aDay !== bDay) return aDay - bDay;
|
|
||||||
return 0;
|
|
||||||
})
|
|
||||||
.map(({ events, date: { year, day, month } }) => ({
|
|
||||||
date: {
|
|
||||||
year,
|
|
||||||
...(isDefined(day) ? { day } : {}),
|
|
||||||
...(isDefined(month) ? { month } : {}),
|
|
||||||
},
|
|
||||||
events: events.map(({ translations }) => ({
|
|
||||||
translations: translations.map(
|
|
||||||
({
|
|
||||||
language,
|
|
||||||
sourceLanguage,
|
|
||||||
description,
|
|
||||||
notes,
|
|
||||||
proofreaders,
|
|
||||||
transcribers,
|
|
||||||
translators,
|
|
||||||
title,
|
|
||||||
}) => ({
|
|
||||||
language: isPayloadType(language) ? language.id : language,
|
|
||||||
sourceLanguage: isPayloadType(sourceLanguage)
|
|
||||||
? sourceLanguage.id
|
|
||||||
: sourceLanguage,
|
|
||||||
...(title ? { title } : {}),
|
|
||||||
...(description ? { description } : {}),
|
|
||||||
...(notes ? { notes } : {}),
|
|
||||||
proofreaders: isPayloadArrayType(proofreaders)
|
|
||||||
? proofreaders.map(handleRecorder)
|
|
||||||
: [],
|
|
||||||
transcribers: isPayloadArrayType(transcribers)
|
|
||||||
? transcribers.map(handleRecorder)
|
|
||||||
: [],
|
|
||||||
translators: isPayloadArrayType(translators)
|
|
||||||
? translators.map(handleRecorder)
|
|
||||||
: [],
|
|
||||||
})
|
|
||||||
),
|
|
||||||
})),
|
|
||||||
})) ?? [],
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
res.status(200).json(result);
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -1,38 +0,0 @@
|
||||||
import { Collections } from "../../../constants";
|
|
||||||
import { createStrapiImportEndpoint } from "../../../endpoints/createStrapiImportEndpoint";
|
|
||||||
import { StrapiLanguage } from "../../../types/strapi";
|
|
||||||
import { isDefined, isUndefined } from "../../../utils/asserts";
|
|
||||||
import { plainTextToLexical } from "../../../utils/string";
|
|
||||||
|
|
||||||
type StrapiChronologyEra = {
|
|
||||||
slug: string;
|
|
||||||
starting_year: number;
|
|
||||||
ending_year: number;
|
|
||||||
title: { title: string; language: StrapiLanguage; description?: string }[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export const importFromStrapi = createStrapiImportEndpoint<StrapiChronologyEra>({
|
|
||||||
strapi: {
|
|
||||||
collection: "chronology-eras",
|
|
||||||
params: {
|
|
||||||
populate: { title: { populate: "language" } },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
payload: {
|
|
||||||
collection: Collections.ChronologyEras,
|
|
||||||
convert: ({ slug, starting_year, ending_year, title: titles }) => ({
|
|
||||||
slug,
|
|
||||||
startingYear: starting_year,
|
|
||||||
endingYear: ending_year,
|
|
||||||
translations: titles.map(({ language, title, description }) => {
|
|
||||||
if (isUndefined(language.data))
|
|
||||||
throw new Error("Language is undefined for one of the translations");
|
|
||||||
return {
|
|
||||||
language: language.data?.attributes.code,
|
|
||||||
title,
|
|
||||||
...(isDefined(description) ? { description: plainTextToLexical(description) } : {}),
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
});
|
|
|
@ -1,15 +0,0 @@
|
||||||
import { CollectionBeforeValidateHook } from "payload/types";
|
|
||||||
import { ChronologyEra } from "../../../types/collections";
|
|
||||||
import { isUndefined } from "../../../utils/asserts";
|
|
||||||
|
|
||||||
export const beforeValidateEndingGreaterThanStarting: CollectionBeforeValidateHook<
|
|
||||||
ChronologyEra
|
|
||||||
> = async ({ data }) => {
|
|
||||||
if (isUndefined(data)) throw new Error("The data is undefined");
|
|
||||||
const { startingYear, endingYear } = data;
|
|
||||||
if (isUndefined(endingYear)) throw new Error("Ending year is undefined");
|
|
||||||
if (isUndefined(startingYear)) throw new Error("Starting year is undefined");
|
|
||||||
if (endingYear < startingYear) {
|
|
||||||
throw new Error("The ending year cannot be before the starting year.");
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,28 +0,0 @@
|
||||||
import payload from "payload";
|
|
||||||
import { CollectionBeforeValidateHook } from "payload/types";
|
|
||||||
import { Collections } from "../../../constants";
|
|
||||||
import { ChronologyEra } from "../../../types/collections";
|
|
||||||
import { hasIntersection, isUndefined } from "../../../utils/asserts";
|
|
||||||
|
|
||||||
export const beforeValidateNoIntersection: CollectionBeforeValidateHook<ChronologyEra> = async ({
|
|
||||||
data,
|
|
||||||
}) => {
|
|
||||||
if (isUndefined(data)) throw new Error("The data is undefined");
|
|
||||||
const { startingYear, endingYear } = data;
|
|
||||||
if (isUndefined(endingYear)) throw new Error("Ending year is undefined");
|
|
||||||
if (isUndefined(startingYear)) throw new Error("Starting year is undefined");
|
|
||||||
|
|
||||||
const otherEras = await payload.find({
|
|
||||||
collection: Collections.ChronologyEras,
|
|
||||||
limit: 100,
|
|
||||||
});
|
|
||||||
|
|
||||||
otherEras.docs.forEach((otherEra: ChronologyEra) => {
|
|
||||||
if (hasIntersection([startingYear, endingYear], [otherEra.startingYear, otherEra.endingYear])) {
|
|
||||||
throw new Error(
|
|
||||||
`This era (${startingYear} -> ${endingYear}) is intersecting with the era\
|
|
||||||
"${otherEra.slug}" (${otherEra.startingYear} -> ${otherEra.endingYear})`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -9,6 +9,11 @@ import { rowField } from "../../fields/rowField/rowField";
|
||||||
import { translatedFields } from "../../fields/translatedFields/translatedFields";
|
import { translatedFields } from "../../fields/translatedFields/translatedFields";
|
||||||
import { createEditor } from "../../utils/editor";
|
import { createEditor } from "../../utils/editor";
|
||||||
import { buildVersionedCollectionConfig } from "../../utils/versionedCollectionConfig";
|
import { buildVersionedCollectionConfig } from "../../utils/versionedCollectionConfig";
|
||||||
|
import { collectibleBlock } from "./blocks/collectibleBlock";
|
||||||
|
import { pageBlock } from "./blocks/contentBlock";
|
||||||
|
import { urlBlock } from "./blocks/urlBlock";
|
||||||
|
import { getAllEndpoint } from "./endpoints/getAllEndpoint";
|
||||||
|
import { getByID } from "./endpoints/getByID";
|
||||||
import { importFromStrapi } from "./endpoints/importFromStrapi";
|
import { importFromStrapi } from "./endpoints/importFromStrapi";
|
||||||
import { beforeValidatePopulateNameField } from "./hooks/beforeValidatePopulateNameField";
|
import { beforeValidatePopulateNameField } from "./hooks/beforeValidatePopulateNameField";
|
||||||
import { validateDate } from "./validations/validateDate";
|
import { validateDate } from "./validations/validateDate";
|
||||||
|
@ -18,6 +23,7 @@ import { validateEventsTranslationsTitle } from "./validations/validateEventsTra
|
||||||
const fields = {
|
const fields = {
|
||||||
name: "name",
|
name: "name",
|
||||||
events: "events",
|
events: "events",
|
||||||
|
eventsSources: "sources",
|
||||||
eventsTranslations: "translations",
|
eventsTranslations: "translations",
|
||||||
eventsTranslationsTitle: "title",
|
eventsTranslationsTitle: "title",
|
||||||
eventsTranslationsDescription: "description",
|
eventsTranslationsDescription: "description",
|
||||||
|
@ -26,15 +32,14 @@ const fields = {
|
||||||
dateYear: "year",
|
dateYear: "year",
|
||||||
dateMonth: "month",
|
dateMonth: "month",
|
||||||
dateDay: "day",
|
dateDay: "day",
|
||||||
era: "era",
|
|
||||||
status: "_status",
|
status: "_status",
|
||||||
} as const satisfies Record<string, string>;
|
} as const satisfies Record<string, string>;
|
||||||
|
|
||||||
export const ChronologyItems: CollectionConfig = buildVersionedCollectionConfig({
|
export const ChronologyEvents: CollectionConfig = buildVersionedCollectionConfig({
|
||||||
slug: Collections.ChronologyItems,
|
slug: Collections.ChronologyEvents,
|
||||||
labels: {
|
labels: {
|
||||||
singular: "Chronology Item",
|
singular: "Chronology Event",
|
||||||
plural: "Chronology Items",
|
plural: "Chronology Events",
|
||||||
},
|
},
|
||||||
defaultSort: fields.name,
|
defaultSort: fields.name,
|
||||||
admin: {
|
admin: {
|
||||||
|
@ -45,7 +50,7 @@ export const ChronologyItems: CollectionConfig = buildVersionedCollectionConfig(
|
||||||
BeforeListTable: [
|
BeforeListTable: [
|
||||||
() =>
|
() =>
|
||||||
QuickFilters({
|
QuickFilters({
|
||||||
slug: Collections.ChronologyItems,
|
slug: Collections.ChronologyEvents,
|
||||||
filterGroups: [
|
filterGroups: [
|
||||||
languageBasedFilters("events.translations.language"),
|
languageBasedFilters("events.translations.language"),
|
||||||
publishStatusFilters,
|
publishStatusFilters,
|
||||||
|
@ -54,7 +59,7 @@ export const ChronologyItems: CollectionConfig = buildVersionedCollectionConfig(
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
endpoints: [importFromStrapi],
|
endpoints: [importFromStrapi, getAllEndpoint, getByID],
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: fields.name,
|
name: fields.name,
|
||||||
|
@ -67,6 +72,11 @@ export const ChronologyItems: CollectionConfig = buildVersionedCollectionConfig(
|
||||||
{
|
{
|
||||||
type: "group",
|
type: "group",
|
||||||
name: fields.date,
|
name: fields.date,
|
||||||
|
admin: {
|
||||||
|
description:
|
||||||
|
"Make sure there isn't already an entry in the Chronology Events with the same date.\
|
||||||
|
If you try to create another entry with the same date, it will refuse to publish.",
|
||||||
|
},
|
||||||
validate: validateDate,
|
validate: validateDate,
|
||||||
fields: [
|
fields: [
|
||||||
rowField([
|
rowField([
|
||||||
|
@ -97,6 +107,12 @@ export const ChronologyItems: CollectionConfig = buildVersionedCollectionConfig(
|
||||||
required: true,
|
required: true,
|
||||||
minRows: 1,
|
minRows: 1,
|
||||||
fields: [
|
fields: [
|
||||||
|
{
|
||||||
|
name: fields.eventsSources,
|
||||||
|
type: "blocks",
|
||||||
|
maxRows: 1,
|
||||||
|
blocks: [urlBlock, collectibleBlock, pageBlock],
|
||||||
|
},
|
||||||
translatedFields({
|
translatedFields({
|
||||||
name: fields.eventsTranslations,
|
name: fields.eventsTranslations,
|
||||||
required: true,
|
required: true,
|
|
@ -0,0 +1,81 @@
|
||||||
|
import { Block } from "payload/types";
|
||||||
|
import { Collections } from "../../../constants";
|
||||||
|
import { translatedFields } from "../../../fields/translatedFields/translatedFields";
|
||||||
|
|
||||||
|
export const collectibleBlock: Block = {
|
||||||
|
slug: "collectibleBlock",
|
||||||
|
interfaceName: "CollectibleBlock",
|
||||||
|
labels: { singular: "Collectible", plural: "Collectibles" },
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: "collectible",
|
||||||
|
type: "relationship",
|
||||||
|
hasMany: false,
|
||||||
|
required: true,
|
||||||
|
relationTo: Collections.Collectibles,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "range",
|
||||||
|
type: "blocks",
|
||||||
|
maxRows: 1,
|
||||||
|
admin: { className: "no-label" },
|
||||||
|
blocks: [
|
||||||
|
{
|
||||||
|
slug: "page",
|
||||||
|
labels: { singular: "Page", plural: "Pages" },
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: "page",
|
||||||
|
type: "number",
|
||||||
|
required: true,
|
||||||
|
admin: {
|
||||||
|
description:
|
||||||
|
"Make sure the page range corresponds to the pages as written\
|
||||||
|
on the collectible. You can use negative page numbers if necessary.",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
slug: "timestamp",
|
||||||
|
labels: { singular: "Timestamp", plural: "Timestamps" },
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: "timestamp",
|
||||||
|
type: "text",
|
||||||
|
required: true,
|
||||||
|
defaultValue: "00:00:00",
|
||||||
|
validate: (value) =>
|
||||||
|
/\d{2}:\d{2}:\d{2}/g.test(value)
|
||||||
|
? true
|
||||||
|
: "The format should be hh:mm:ss\
|
||||||
|
(e.g: 01:23:45 for 1 hour, 23 minutes, and 45 seconds)",
|
||||||
|
admin: {
|
||||||
|
description: "hh:mm:ss (e.g: 01:23:45 for 1 hour, 23 minutes, and 45 seconds)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
slug: "other",
|
||||||
|
labels: { singular: "Other", plural: "Others" },
|
||||||
|
fields: [
|
||||||
|
translatedFields({
|
||||||
|
admin: { className: "no-label" },
|
||||||
|
name: "translations",
|
||||||
|
required: true,
|
||||||
|
minRows: 1,
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: "note",
|
||||||
|
type: "textarea",
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
|
@ -0,0 +1,17 @@
|
||||||
|
import { Block } from "payload/types";
|
||||||
|
import { Collections } from "../../../constants";
|
||||||
|
|
||||||
|
export const pageBlock: Block = {
|
||||||
|
slug: "pageBlock",
|
||||||
|
interfaceName: "PageBlock",
|
||||||
|
labels: { singular: "Page", plural: "Pages" },
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: "page",
|
||||||
|
type: "relationship",
|
||||||
|
hasMany: false,
|
||||||
|
required: true,
|
||||||
|
relationTo: Collections.Pages,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
|
@ -0,0 +1,8 @@
|
||||||
|
import { Block } from "payload/types";
|
||||||
|
|
||||||
|
export const urlBlock: Block = {
|
||||||
|
slug: "urlBlock",
|
||||||
|
interfaceName: "UrlBlock",
|
||||||
|
labels: { singular: "URL", plural: "URLs" },
|
||||||
|
fields: [{ name: "url", type: "text", required: true }],
|
||||||
|
};
|
|
@ -0,0 +1,150 @@
|
||||||
|
import payload from "payload";
|
||||||
|
import { Collections } from "../../../constants";
|
||||||
|
import { EndpointChronologyEvent, EndpointSource } from "../../../sdk";
|
||||||
|
import { ChronologyEvent, CollectibleBlock } from "../../../types/collections";
|
||||||
|
import { CollectionEndpoint } from "../../../types/payload";
|
||||||
|
import { isDefined, isNotEmpty, isPayloadArrayType, isPayloadType } from "../../../utils/asserts";
|
||||||
|
import { getDomainFromUrl, handleRecorder } from "../../../utils/endpoints";
|
||||||
|
import { convertCollectibleToPreview } from "../../Collectibles/endpoints/getBySlugEndpoint";
|
||||||
|
import { convertPageToPreview } from "../../Pages/endpoints/getBySlugEndpoint";
|
||||||
|
|
||||||
|
export const getAllEndpoint: CollectionEndpoint = {
|
||||||
|
method: "get",
|
||||||
|
path: "/all",
|
||||||
|
handler: async (req, res) => {
|
||||||
|
if (!req.user) {
|
||||||
|
return res.status(403).send({
|
||||||
|
errors: [
|
||||||
|
{
|
||||||
|
message: "You are not allowed to perform this action.",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = (
|
||||||
|
await payload.find({
|
||||||
|
collection: Collections.ChronologyEvents,
|
||||||
|
pagination: false,
|
||||||
|
draft: false,
|
||||||
|
where: {
|
||||||
|
_status: {
|
||||||
|
equals: "published",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
).docs;
|
||||||
|
|
||||||
|
const events = result
|
||||||
|
.sort((a, b) => {
|
||||||
|
const aYear = a.date.year;
|
||||||
|
const bYear = b.date.year;
|
||||||
|
if (aYear !== bYear) return aYear - bYear;
|
||||||
|
const aMonth = a.date.month ?? 13;
|
||||||
|
const bMonth = b.date.month ?? 13;
|
||||||
|
if (aMonth !== bMonth) return aMonth - bMonth;
|
||||||
|
const aDay = a.date.day ?? 32;
|
||||||
|
const bDay = b.date.day ?? 32;
|
||||||
|
if (aDay !== bDay) return aDay - bDay;
|
||||||
|
return 0;
|
||||||
|
})
|
||||||
|
.map<EndpointChronologyEvent>(eventToEndpointEvent);
|
||||||
|
|
||||||
|
res.status(200).json(events);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const eventToEndpointEvent = ({
|
||||||
|
date: { year, day, month },
|
||||||
|
events,
|
||||||
|
id,
|
||||||
|
}: ChronologyEvent): EndpointChronologyEvent => ({
|
||||||
|
id,
|
||||||
|
date: {
|
||||||
|
year,
|
||||||
|
...(isDefined(month) ? { month } : {}),
|
||||||
|
...(isDefined(day) ? { day } : {}),
|
||||||
|
},
|
||||||
|
events: events.map<EndpointChronologyEvent["events"][number]>(({ sources, translations }) => ({
|
||||||
|
translations: translations.map(
|
||||||
|
({
|
||||||
|
language,
|
||||||
|
sourceLanguage,
|
||||||
|
description,
|
||||||
|
notes,
|
||||||
|
proofreaders,
|
||||||
|
title,
|
||||||
|
transcribers,
|
||||||
|
translators,
|
||||||
|
}) => ({
|
||||||
|
language: isPayloadType(language) ? language.id : language,
|
||||||
|
sourceLanguage: isPayloadType(sourceLanguage) ? sourceLanguage.id : sourceLanguage,
|
||||||
|
...(isNotEmpty(title) ? { title } : {}),
|
||||||
|
...(isDefined(description) ? { description } : {}),
|
||||||
|
...(isDefined(notes) ? { notes } : {}),
|
||||||
|
proofreaders: isPayloadArrayType(proofreaders) ? proofreaders.map(handleRecorder) : [],
|
||||||
|
transcribers: isPayloadArrayType(transcribers) ? transcribers.map(handleRecorder) : [],
|
||||||
|
translators: isPayloadArrayType(translators) ? translators.map(handleRecorder) : [],
|
||||||
|
})
|
||||||
|
),
|
||||||
|
sources: handleSources(sources),
|
||||||
|
})),
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleSources = (sources: ChronologyEvent["events"][number]["sources"]): EndpointSource[] => {
|
||||||
|
return (
|
||||||
|
sources?.flatMap<EndpointSource>((source) => {
|
||||||
|
switch (source.blockType) {
|
||||||
|
case "collectibleBlock":
|
||||||
|
const range = handleRange(source.range);
|
||||||
|
if (!isPayloadType(source.collectible)) return [];
|
||||||
|
return {
|
||||||
|
type: "collectible",
|
||||||
|
collectible: convertCollectibleToPreview(source.collectible),
|
||||||
|
...(range ? { range } : {}),
|
||||||
|
};
|
||||||
|
|
||||||
|
case "pageBlock":
|
||||||
|
if (!isPayloadType(source.page)) return [];
|
||||||
|
return {
|
||||||
|
type: "page",
|
||||||
|
page: convertPageToPreview(source.page),
|
||||||
|
};
|
||||||
|
|
||||||
|
case "urlBlock":
|
||||||
|
return {
|
||||||
|
type: "url",
|
||||||
|
url: source.url,
|
||||||
|
label: getDomainFromUrl(source.url),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}) ?? []
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleRange = (
|
||||||
|
rawRange: CollectibleBlock["range"]
|
||||||
|
): Extract<EndpointSource, { type: "collectible" }>["range"] => {
|
||||||
|
const range = rawRange?.[0];
|
||||||
|
|
||||||
|
switch (range?.blockType) {
|
||||||
|
case "page":
|
||||||
|
return { type: "page", page: range.page };
|
||||||
|
|
||||||
|
case "timestamp":
|
||||||
|
return { type: "timestamp", timestamp: range.timestamp };
|
||||||
|
|
||||||
|
case "other":
|
||||||
|
return {
|
||||||
|
type: "custom",
|
||||||
|
translations: range.translations.map(({ language, note }) => ({
|
||||||
|
language: isPayloadType(language) ? language.id : language,
|
||||||
|
note,
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
|
||||||
|
case undefined:
|
||||||
|
default:
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,35 @@
|
||||||
|
import payload from "payload";
|
||||||
|
import { Collections } from "../../../constants";
|
||||||
|
import { CollectionEndpoint } from "../../../types/payload";
|
||||||
|
import { eventToEndpointEvent } from "./getAllEndpoint";
|
||||||
|
|
||||||
|
export const getByID: CollectionEndpoint = {
|
||||||
|
method: "get",
|
||||||
|
path: "/:id",
|
||||||
|
handler: async (req, res) => {
|
||||||
|
if (!req.user) {
|
||||||
|
return res.status(403).send({
|
||||||
|
errors: [
|
||||||
|
{
|
||||||
|
message: "You are not allowed to perform this action.",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!req.params.id) {
|
||||||
|
return res.status(400).send({ errors: [{ message: "Missing 'id' query params" }] });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await payload.findByID({
|
||||||
|
collection: Collections.ChronologyEvents,
|
||||||
|
id: req.params.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.status(200).json(eventToEndpointEvent(result));
|
||||||
|
} catch {
|
||||||
|
return res.sendStatus(404);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
|
@ -1,7 +1,8 @@
|
||||||
import { Collections } from "../../../constants";
|
import { Collections } from "../../../constants";
|
||||||
import { createStrapiImportEndpoint } from "../../../endpoints/createStrapiImportEndpoint";
|
import { createStrapiImportEndpoint } from "../../../endpoints/createStrapiImportEndpoint";
|
||||||
import { StrapiLanguage } from "../../../types/strapi";
|
import { StrapiLanguage } from "../../../types/strapi";
|
||||||
import { isUndefined } from "../../../utils/asserts";
|
import { isDefined, isUndefined } from "../../../utils/asserts";
|
||||||
|
import { plainTextToLexical } from "../../../utils/string";
|
||||||
|
|
||||||
type StrapiChronologyItem = {
|
type StrapiChronologyItem = {
|
||||||
year: number;
|
year: number;
|
||||||
|
@ -25,20 +26,25 @@ export const importFromStrapi = createStrapiImportEndpoint<StrapiChronologyItem>
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
payload: {
|
payload: {
|
||||||
collection: Collections.ChronologyItems,
|
collection: Collections.ChronologyEvents,
|
||||||
convert: ({ year, month, day, events }, user) => ({
|
convert: ({ year, month, day, events }, user) => ({
|
||||||
date: { year, month, day },
|
date: { year, month, day },
|
||||||
events: events.map((event) => ({
|
events: events.map((event) => ({
|
||||||
translations: event.translations.map(({ title, description, note, language }) => {
|
translations: event.translations.map(({ title, description, note, language }) => {
|
||||||
if (isUndefined(language.data))
|
if (isUndefined(language.data))
|
||||||
throw new Error("A language is required for a chronology item event translation");
|
throw new Error("A language is required for a chronology item event translation");
|
||||||
|
|
||||||
|
const newLanguage =
|
||||||
|
language.data.attributes.code === "pt-br" ? "pt" : language.data.attributes.code;
|
||||||
|
const sourceLanguage = language.data.attributes.code === "ja" ? "ja" : "en";
|
||||||
|
|
||||||
return {
|
return {
|
||||||
title,
|
...(isDefined(title) ? { title } : {}),
|
||||||
description,
|
...(isDefined(note) ? { notes: plainTextToLexical(note) } : {}),
|
||||||
note,
|
...(isDefined(description) ? { description: plainTextToLexical(description) } : {}),
|
||||||
language: language.data.attributes.code,
|
language: newLanguage,
|
||||||
sourceLanguage: "en",
|
sourceLanguage,
|
||||||
...(language.data.attributes.code === "en"
|
...(newLanguage === sourceLanguage
|
||||||
? { transcribers: [user.id] }
|
? { transcribers: [user.id] }
|
||||||
: { translators: [user.id] }),
|
: { translators: [user.id] }),
|
||||||
};
|
};
|
|
@ -1,11 +1,11 @@
|
||||||
import { FieldHook } from "payload/dist/fields/config/types";
|
import { FieldHook } from "payload/dist/fields/config/types";
|
||||||
import { ChronologyItem } from "../../../types/collections";
|
import { ChronologyEvent } from "../../../types/collections";
|
||||||
import { isDefined, isUndefined } from "../../../utils/asserts";
|
import { isDefined, isUndefined } from "../../../utils/asserts";
|
||||||
|
|
||||||
export const beforeValidatePopulateNameField: FieldHook<
|
export const beforeValidatePopulateNameField: FieldHook<
|
||||||
ChronologyItem,
|
ChronologyEvent,
|
||||||
ChronologyItem["name"],
|
ChronologyEvent["name"],
|
||||||
ChronologyItem
|
ChronologyEvent
|
||||||
> = ({ data }) => {
|
> = ({ data }) => {
|
||||||
if (isUndefined(data) || isUndefined(data.date) || isUndefined(data.date.year))
|
if (isUndefined(data) || isUndefined(data.date) || isUndefined(data.date.year))
|
||||||
return "????-??-??";
|
return "????-??-??";
|
|
@ -1,9 +1,9 @@
|
||||||
import { DateTime } from "luxon";
|
import { DateTime } from "luxon";
|
||||||
import { Validate } from "payload/types";
|
import { Validate } from "payload/types";
|
||||||
import { ChronologyItem } from "../../../types/collections";
|
import { ChronologyEvent } from "../../../types/collections";
|
||||||
import { isUndefined } from "../../../utils/asserts";
|
import { isUndefined } from "../../../utils/asserts";
|
||||||
|
|
||||||
export const validateDate: Validate<ChronologyItem["date"] | undefined> = (date) => {
|
export const validateDate: Validate<ChronologyEvent["date"] | undefined> = (date) => {
|
||||||
if (isUndefined(date)) return "This field is required.";
|
if (isUndefined(date)) return "This field is required.";
|
||||||
const { year, month, day } = date;
|
const { year, month, day } = date;
|
||||||
if (isUndefined(day)) return true;
|
if (isUndefined(day)) return true;
|
|
@ -1,11 +1,11 @@
|
||||||
import { Validate } from "payload/types";
|
import { Validate } from "payload/types";
|
||||||
import { ChronologyItem } from "../../../types/collections";
|
import { ChronologyEvent } from "../../../types/collections";
|
||||||
import { isEmpty } from "../../../utils/asserts";
|
import { isEmpty } from "../../../utils/asserts";
|
||||||
|
|
||||||
export const validateEventsTranslationsDescription: Validate<
|
export const validateEventsTranslationsDescription: Validate<
|
||||||
string | undefined,
|
string | undefined,
|
||||||
ChronologyItem,
|
ChronologyEvent,
|
||||||
ChronologyItem["events"][number]["translations"][number],
|
ChronologyEvent["events"][number]["translations"][number],
|
||||||
unknown
|
unknown
|
||||||
> = (_, { siblingData: { description, title } }) => {
|
> = (_, { siblingData: { description, title } }) => {
|
||||||
if (!description && isEmpty(title)) {
|
if (!description && isEmpty(title)) {
|
|
@ -1,11 +1,11 @@
|
||||||
import { Validate } from "payload/types";
|
import { Validate } from "payload/types";
|
||||||
import { ChronologyItem } from "../../../types/collections";
|
import { ChronologyEvent } from "../../../types/collections";
|
||||||
import { isEmpty } from "../../../utils/asserts";
|
import { isEmpty } from "../../../utils/asserts";
|
||||||
|
|
||||||
export const validateEventsTranslationsTitle: Validate<
|
export const validateEventsTranslationsTitle: Validate<
|
||||||
string | undefined,
|
string | undefined,
|
||||||
ChronologyItem,
|
ChronologyEvent,
|
||||||
ChronologyItem["events"][number]["translations"][number],
|
ChronologyEvent["events"][number]["translations"][number],
|
||||||
unknown
|
unknown
|
||||||
> = (_, { siblingData: { description, title } }) => {
|
> = (_, { siblingData: { description, title } }) => {
|
||||||
if (!description && isEmpty(title)) {
|
if (!description && isEmpty(title)) {
|
|
@ -8,7 +8,7 @@ import {
|
||||||
isPayloadType,
|
isPayloadType,
|
||||||
isValidPayloadImage,
|
isValidPayloadImage,
|
||||||
} from "../../../utils/asserts";
|
} from "../../../utils/asserts";
|
||||||
import { convertTagsToGroups, handleParentPages } from "../../../utils/endpoints";
|
import { convertTagsToGroups, getDomainFromUrl, handleParentPages } from "../../../utils/endpoints";
|
||||||
import { convertPageToPreview } from "../../Pages/endpoints/getBySlugEndpoint";
|
import { convertPageToPreview } from "../../Pages/endpoints/getBySlugEndpoint";
|
||||||
|
|
||||||
export const getBySlugEndpoint = createGetByEndpoint(
|
export const getBySlugEndpoint = createGetByEndpoint(
|
||||||
|
@ -41,9 +41,9 @@ export const getBySlugEndpoint = createGetByEndpoint(
|
||||||
gallery: handleGallery(gallery),
|
gallery: handleGallery(gallery),
|
||||||
scans: handleScans(collectible.scans),
|
scans: handleScans(collectible.scans),
|
||||||
nature: nature === "Physical" ? CollectibleNature.Physical : CollectibleNature.Digital,
|
nature: nature === "Physical" ? CollectibleNature.Physical : CollectibleNature.Digital,
|
||||||
parentPages: handleParentPages({collectibles: parentItems, folders}),
|
parentPages: handleParentPages({ collectibles: parentItems, folders }),
|
||||||
subitems: isPayloadArrayType(subitems) ? subitems.map(convertCollectibleToPreview) : [],
|
subitems: isPayloadArrayType(subitems) ? subitems.map(convertCollectibleToPreview) : [],
|
||||||
urls: urls?.map(({ url }) => ({ url, label: getLabelFromUrl(url) })) ?? [],
|
urls: urls?.map(({ url }) => ({ url, label: getDomainFromUrl(url) })) ?? [],
|
||||||
...(weightEnabled && weight ? { weight: weight.amount } : {}),
|
...(weightEnabled && weight ? { weight: weight.amount } : {}),
|
||||||
...handleSize(size, sizeEnabled),
|
...handleSize(size, sizeEnabled),
|
||||||
...handlePageInfo(pageInfo, pageInfoEnabled),
|
...handlePageInfo(pageInfo, pageInfoEnabled),
|
||||||
|
@ -53,7 +53,7 @@ export const getBySlugEndpoint = createGetByEndpoint(
|
||||||
3
|
3
|
||||||
);
|
);
|
||||||
|
|
||||||
export const handlePrice = (
|
const handlePrice = (
|
||||||
price: Collectible["price"],
|
price: Collectible["price"],
|
||||||
enabled: Collectible["priceEnabled"]
|
enabled: Collectible["priceEnabled"]
|
||||||
): { price: NonNullable<EndpointCollectible["price"]> } | {} => {
|
): { price: NonNullable<EndpointCollectible["price"]> } | {} => {
|
||||||
|
@ -63,7 +63,7 @@ export const handlePrice = (
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const handleSize = (
|
const handleSize = (
|
||||||
size: Collectible["size"],
|
size: Collectible["size"],
|
||||||
enabled: Collectible["sizeEnabled"]
|
enabled: Collectible["sizeEnabled"]
|
||||||
): { size: NonNullable<EndpointCollectible["size"]> } | {} => {
|
): { size: NonNullable<EndpointCollectible["size"]> } | {} => {
|
||||||
|
@ -77,7 +77,7 @@ export const handleSize = (
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const handlePageInfo = (
|
const handlePageInfo = (
|
||||||
pageInfo: Collectible["pageInfo"],
|
pageInfo: Collectible["pageInfo"],
|
||||||
enabled: Collectible["pageInfoEnabled"]
|
enabled: Collectible["pageInfoEnabled"]
|
||||||
): { pageInfo: NonNullable<EndpointCollectible["pageInfo"]> } | {} => {
|
): { pageInfo: NonNullable<EndpointCollectible["pageInfo"]> } | {} => {
|
||||||
|
@ -91,7 +91,7 @@ export const handlePageInfo = (
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const handleGallery = (gallery: Collectible["gallery"]): EndpointCollectible["gallery"] => {
|
const handleGallery = (gallery: Collectible["gallery"]): EndpointCollectible["gallery"] => {
|
||||||
const result: PayloadImage[] = [];
|
const result: PayloadImage[] = [];
|
||||||
if (!gallery) return result;
|
if (!gallery) return result;
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ export const handleGallery = (gallery: Collectible["gallery"]): EndpointCollecti
|
||||||
return result.slice(0, 10);
|
return result.slice(0, 10);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const handleScans = (scans: Collectible["scans"]): EndpointCollectible["scans"] => {
|
const handleScans = (scans: Collectible["scans"]): EndpointCollectible["scans"] => {
|
||||||
const result: PayloadImage[] = [];
|
const result: PayloadImage[] = [];
|
||||||
if (!scans) return result;
|
if (!scans) return result;
|
||||||
|
|
||||||
|
@ -133,9 +133,7 @@ export const handleScans = (scans: Collectible["scans"]): EndpointCollectible["s
|
||||||
return result.slice(0, 10);
|
return result.slice(0, 10);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const handleContents = (
|
const handleContents = (contents: Collectible["contents"]): EndpointCollectible["contents"] => {
|
||||||
contents: Collectible["contents"]
|
|
||||||
): EndpointCollectible["contents"] => {
|
|
||||||
if (!contents) return [];
|
if (!contents) return [];
|
||||||
|
|
||||||
return contents.flatMap(({ content, range: rangeArray }) => {
|
return contents.flatMap(({ content, range: rangeArray }) => {
|
||||||
|
@ -229,12 +227,3 @@ export const convertCollectibleToPreview = ({
|
||||||
})) ?? [],
|
})) ?? [],
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const getLabelFromUrl = (url: string): string => {
|
|
||||||
const urlObject = new URL(url);
|
|
||||||
let domain = urlObject.hostname;
|
|
||||||
if (domain.startsWith("www.")) {
|
|
||||||
domain = domain.substring("www.".length);
|
|
||||||
}
|
|
||||||
return domain;
|
|
||||||
};
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ import { translatedFields } from "../../fields/translatedFields/translatedFields
|
||||||
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
||||||
import { createEditor } from "../../utils/editor";
|
import { createEditor } from "../../utils/editor";
|
||||||
import { getBySlugEndpoint } from "./endpoints/getBySlugEndpoint";
|
import { getBySlugEndpoint } from "./endpoints/getBySlugEndpoint";
|
||||||
import { getRootFoldersEndpoint } from "./endpoints/rootEndpoint";
|
|
||||||
|
|
||||||
const fields = {
|
const fields = {
|
||||||
slug: "slug",
|
slug: "slug",
|
||||||
|
@ -34,7 +33,7 @@ export const Folders = buildCollectionConfig({
|
||||||
"Folders provide a way to structure our content. A folder can contain subfolders and/or files.",
|
"Folders provide a way to structure our content. A folder can contain subfolders and/or files.",
|
||||||
preview: ({ slug }) => `https://v3.accords-library.com/en/folders/${slug}`,
|
preview: ({ slug }) => `https://v3.accords-library.com/en/folders/${slug}`,
|
||||||
},
|
},
|
||||||
endpoints: [getRootFoldersEndpoint, getBySlugEndpoint],
|
endpoints: [getBySlugEndpoint],
|
||||||
fields: [
|
fields: [
|
||||||
rowField([
|
rowField([
|
||||||
slugField({ name: fields.slug }),
|
slugField({ name: fields.slug }),
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
import payload from "payload";
|
|
||||||
import { Collections } from "../../../constants";
|
|
||||||
import { Folder } from "../../../types/collections";
|
|
||||||
import { CollectionEndpoint } from "../../../types/payload";
|
|
||||||
import { isPayloadType } from "../../../utils/asserts";
|
|
||||||
import { convertFolderToPreview } from "./getBySlugEndpoint";
|
|
||||||
|
|
||||||
export const getRootFoldersEndpoint: CollectionEndpoint = {
|
|
||||||
method: "get",
|
|
||||||
path: "/root",
|
|
||||||
handler: async (req, res) => {
|
|
||||||
if (!req.user) {
|
|
||||||
return res.status(403).send({
|
|
||||||
errors: [
|
|
||||||
{
|
|
||||||
message: "You are not allowed to perform this action.",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const homeFolder = (
|
|
||||||
await payload.find({
|
|
||||||
collection: Collections.Folders,
|
|
||||||
limit: 100,
|
|
||||||
where: { slug: { equals: "home" } },
|
|
||||||
})
|
|
||||||
).docs[0];
|
|
||||||
|
|
||||||
if (!homeFolder) {
|
|
||||||
res.status(404);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const folders = homeFolder.sections?.[0]?.subfolders;
|
|
||||||
|
|
||||||
if (!folders) {
|
|
||||||
res.status(404);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = folders.filter(isPayloadType).filter(isEmptyFolder).map(convertFolderToPreview);
|
|
||||||
|
|
||||||
res.status(200).json(result);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const isEmptyFolder = ({ sections, files }: Folder): boolean => {
|
|
||||||
if (sections && sections.length > 0) return true;
|
|
||||||
if (files && files.length > 0) return true;
|
|
||||||
return false;
|
|
||||||
};
|
|
|
@ -3,8 +3,7 @@ import type { BreakBlock, Image, SectionBlock, TranscriptBlock } from "./types/c
|
||||||
// END MOCKING SECTION
|
// END MOCKING SECTION
|
||||||
|
|
||||||
export enum Collections {
|
export enum Collections {
|
||||||
ChronologyEras = "chronology-eras",
|
ChronologyEvents = "chronology-events",
|
||||||
ChronologyItems = "chronology-items",
|
|
||||||
Currencies = "currencies",
|
Currencies = "currencies",
|
||||||
Files = "files",
|
Files = "files",
|
||||||
Languages = "languages",
|
Languages = "languages",
|
||||||
|
|
|
@ -3,8 +3,7 @@ import { mongooseAdapter } from "@payloadcms/db-mongodb";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { buildConfig } from "payload/config";
|
import { buildConfig } from "payload/config";
|
||||||
import { BackgroundImages } from "./collections/BackgroundImages/BackgroundImages";
|
import { BackgroundImages } from "./collections/BackgroundImages/BackgroundImages";
|
||||||
import { ChronologyEras } from "./collections/ChronologyEras/ChronologyEras";
|
import { ChronologyEvents } from "./collections/ChronologyEvents/ChronologyEvents";
|
||||||
import { ChronologyItems } from "./collections/ChronologyItems/ChronologyItems";
|
|
||||||
import { Collectibles } from "./collections/Collectibles/Collectibles";
|
import { Collectibles } from "./collections/Collectibles/Collectibles";
|
||||||
import { Currencies } from "./collections/Currencies/Currencies";
|
import { Currencies } from "./collections/Currencies/Currencies";
|
||||||
import { Folders } from "./collections/Folders/Folders";
|
import { Folders } from "./collections/Folders/Folders";
|
||||||
|
@ -44,8 +43,7 @@ export default buildConfig({
|
||||||
Pages,
|
Pages,
|
||||||
Collectibles,
|
Collectibles,
|
||||||
Folders,
|
Folders,
|
||||||
ChronologyItems,
|
ChronologyEvents,
|
||||||
ChronologyEras,
|
|
||||||
Notes,
|
Notes,
|
||||||
|
|
||||||
Images,
|
Images,
|
||||||
|
|
40
src/sdk.ts
40
src/sdk.ts
|
@ -320,6 +320,40 @@ export type TableOfContentEntry = {
|
||||||
children: TableOfContentEntry[];
|
children: TableOfContentEntry[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type EndpointChronologyEvent = {
|
||||||
|
id: string;
|
||||||
|
date: {
|
||||||
|
year: number;
|
||||||
|
month?: number;
|
||||||
|
day?: number;
|
||||||
|
};
|
||||||
|
events: {
|
||||||
|
sources: EndpointSource[];
|
||||||
|
translations: {
|
||||||
|
language: string;
|
||||||
|
sourceLanguage: string;
|
||||||
|
title?: string;
|
||||||
|
description?: RichTextContent;
|
||||||
|
notes?: RichTextContent;
|
||||||
|
transcribers: EndpointRecorder[];
|
||||||
|
translators: EndpointRecorder[];
|
||||||
|
proofreaders: EndpointRecorder[];
|
||||||
|
}[];
|
||||||
|
}[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type EndpointSource =
|
||||||
|
| { type: "url"; url: string; label: string }
|
||||||
|
| {
|
||||||
|
type: "collectible";
|
||||||
|
collectible: EndpointCollectiblePreview;
|
||||||
|
range?:
|
||||||
|
| { type: "page"; page: number }
|
||||||
|
| { type: "timestamp"; timestamp: string }
|
||||||
|
| { type: "custom"; translations: { language: string; note: string }[] };
|
||||||
|
}
|
||||||
|
| { type: "page"; page: EndpointPagePreview };
|
||||||
|
|
||||||
export type PayloadImage = {
|
export type PayloadImage = {
|
||||||
url: string;
|
url: string;
|
||||||
width: number;
|
width: number;
|
||||||
|
@ -329,8 +363,6 @@ export type PayloadImage = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const payload = {
|
export const payload = {
|
||||||
getEras: async (): Promise<EndpointEra[]> =>
|
|
||||||
await (await request(payloadApiUrl(Collections.ChronologyEras, `all`))).json(),
|
|
||||||
getHomeFolders: async (): Promise<EndpointHomeFolder[]> =>
|
getHomeFolders: async (): Promise<EndpointHomeFolder[]> =>
|
||||||
await (await request(payloadApiUrl(Collections.HomeFolders, `all`, true))).json(),
|
await (await request(payloadApiUrl(Collections.HomeFolders, `all`, true))).json(),
|
||||||
getFolder: async (slug: string): Promise<EndpointFolder> =>
|
getFolder: async (slug: string): Promise<EndpointFolder> =>
|
||||||
|
@ -347,4 +379,8 @@ export const payload = {
|
||||||
await (await request(payloadApiUrl(Collections.Pages, `slug/${slug}`))).json(),
|
await (await request(payloadApiUrl(Collections.Pages, `slug/${slug}`))).json(),
|
||||||
getCollectible: async (slug: string): Promise<EndpointCollectible> =>
|
getCollectible: async (slug: string): Promise<EndpointCollectible> =>
|
||||||
await (await request(payloadApiUrl(Collections.Collectibles, `slug/${slug}`))).json(),
|
await (await request(payloadApiUrl(Collections.Collectibles, `slug/${slug}`))).json(),
|
||||||
|
getChronologyEvents: async (): Promise<EndpointChronologyEvent[]> =>
|
||||||
|
await (await request(payloadApiUrl(Collections.ChronologyEvents, `all`))).json(),
|
||||||
|
getChronologyEventByID: async (id: string): Promise<EndpointChronologyEvent> =>
|
||||||
|
await (await request(payloadApiUrl(Collections.ChronologyEvents, id))).json(),
|
||||||
};
|
};
|
||||||
|
|
|
@ -77,10 +77,28 @@ html[data-theme="light"] {
|
||||||
.blocks-field__block-pill-cueBlock + .section-title,
|
.blocks-field__block-pill-cueBlock + .section-title,
|
||||||
.blocks-field__block-pill-pageRange + .section-title,
|
.blocks-field__block-pill-pageRange + .section-title,
|
||||||
.blocks-field__block-pill-timeRange + .section-title,
|
.blocks-field__block-pill-timeRange + .section-title,
|
||||||
|
.blocks-field__block-pill-urlBlock + .section-title,
|
||||||
|
.blocks-field__block-pill-pageBlock + .section-title,
|
||||||
|
.blocks-field__block-pill-collectibleBlock + .section-title,
|
||||||
|
.blocks-field__block-pill-page + .section-title,
|
||||||
|
.blocks-field__block-pill-timestamp + .section-title,
|
||||||
|
.blocks-field__block-pill-other + .section-title,
|
||||||
.blocks-field__block-pill-other + .section-title {
|
.blocks-field__block-pill-other + .section-title {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.collapsible__toggle-wrap:has(
|
||||||
|
.blocks-field__block-pill-collectibleBlock,
|
||||||
|
.blocks-field__block-pill-page,
|
||||||
|
.blocks-field__block-pill-timestamp,
|
||||||
|
.blocks-field__block-pill-other,
|
||||||
|
.blocks-field__block-pill-pageRange,
|
||||||
|
.blocks-field__block-pill-timeRange
|
||||||
|
)
|
||||||
|
.blocks-field__block-number {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
// Reduce margin on Lexical blocks with the classname "reduced-margins"
|
// Reduce margin on Lexical blocks with the classname "reduced-margins"
|
||||||
|
|
||||||
.rich-text-lexical.field-type.reduced-margins {
|
.rich-text-lexical.field-type.reduced-margins {
|
||||||
|
|
|
@ -100,3 +100,12 @@ export const handleRecorder = ({
|
||||||
username: anonymize ? `Recorder#${id.substring(0, 5)}` : username,
|
username: anonymize ? `Recorder#${id.substring(0, 5)}` : username,
|
||||||
...(isValidPayloadImage(avatar) ? { avatar } : {}),
|
...(isValidPayloadImage(avatar) ? { avatar } : {}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const getDomainFromUrl = (url: string): string => {
|
||||||
|
const urlObject = new URL(url);
|
||||||
|
let domain = urlObject.hostname;
|
||||||
|
if (domain.startsWith("www.")) {
|
||||||
|
domain = domain.substring("www.".length);
|
||||||
|
}
|
||||||
|
return domain;
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in New Issue