Improve editor + added imports
This commit is contained in:
parent
509cbdba9b
commit
4f807c410b
|
@ -4,6 +4,7 @@ MONGODB_PORT=27017
|
||||||
PAYLOAD_URI=https://payload.domain.com
|
PAYLOAD_URI=https://payload.domain.com
|
||||||
PAYLOAD_SECRET=payloadsecreta5e6ea45ef4e66eaa151612bdcb599df
|
PAYLOAD_SECRET=payloadsecreta5e6ea45ef4e66eaa151612bdcb599df
|
||||||
PAYLOAD_PORT=3000
|
PAYLOAD_PORT=3000
|
||||||
|
RECORDER_DEFAULT_PASSWORD=somepassword
|
||||||
|
|
||||||
STRAPI_URI=https://strapi.domain.com
|
STRAPI_URI=https://strapi.domain.com
|
||||||
STRAPI_TOKEN=strapisecreta5e6ea45ef4e66eaa151612bdcb599df
|
STRAPI_TOKEN=strapisecreta5e6ea45ef4e66eaa151612bdcb599df
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
23
package.json
23
package.json
|
@ -22,27 +22,28 @@
|
||||||
"start": "sudo docker compose up"
|
"start": "sudo docker compose up"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fontsource/vollkorn": "^5.0.14",
|
"@fontsource/vollkorn": "^5.0.17",
|
||||||
"@payloadcms/bundler-webpack": "^1.0.3",
|
"@payloadcms/bundler-webpack": "^1.0.4",
|
||||||
"@payloadcms/db-mongodb": "^1.0.3",
|
"@payloadcms/db-mongodb": "^1.0.4",
|
||||||
"@payloadcms/richtext-lexical": "^0.1.8",
|
"@payloadcms/richtext-lexical": "^0.1.15",
|
||||||
"clean-deep": "^3.4.0",
|
"clean-deep": "^3.4.0",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"language-tags": "^1.0.9",
|
"language-tags": "^1.0.9",
|
||||||
"luxon": "^3.4.3",
|
"luxon": "^3.4.3",
|
||||||
"payload": "^2.0.5",
|
"payload": "^2.0.12",
|
||||||
"styled-components": "^6.0.9"
|
"styled-components": "^6.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/dotenv": "^8.2.0",
|
"@types/dotenv": "^8.2.0",
|
||||||
"@types/express": "^4.17.18",
|
"@types/express": "^4.17.20",
|
||||||
"@types/language-tags": "^1.0.2",
|
"@types/language-tags": "^1.0.3",
|
||||||
"@types/luxon": "^3.3.2",
|
"@types/luxon": "^3.3.3",
|
||||||
"@types/qs": "^6.9.8",
|
"@types/qs": "^6.9.9",
|
||||||
"@types/react-router-dom": "^5.3.3",
|
"@types/react-router-dom": "^5.3.3",
|
||||||
"@types/styled-components": "^5.1.28",
|
"@types/styled-components": "^5.1.29",
|
||||||
"copyfiles": "^2.4.1",
|
"copyfiles": "^2.4.1",
|
||||||
"nodemon": "^3.0.1",
|
"nodemon": "^3.0.1",
|
||||||
|
"npm-check-updates": "^16.14.6",
|
||||||
"prettier": "^3.0.3",
|
"prettier": "^3.0.3",
|
||||||
"ts-node": "^10.9.1",
|
"ts-node": "^10.9.1",
|
||||||
"ts-unused-exports": "^10.0.1",
|
"ts-unused-exports": "^10.0.1",
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { Block } from "payload/types";
|
import { Block } from "payload/types";
|
||||||
|
import { createEditor } from "../utils/editor";
|
||||||
|
|
||||||
export const cueBlock: Block = {
|
export const cueBlock: Block = {
|
||||||
slug: "cueBlock",
|
slug: "cueBlock",
|
||||||
|
@ -8,12 +9,12 @@ export const cueBlock: Block = {
|
||||||
{
|
{
|
||||||
name: "content",
|
name: "content",
|
||||||
label: false,
|
label: false,
|
||||||
type: "textarea",
|
type: "richText",
|
||||||
required: true,
|
required: true,
|
||||||
admin: {
|
admin: {
|
||||||
description:
|
className: "reduced-margins",
|
||||||
"Parenthesis will automatically be added around cues. You don't have to include them here.",
|
|
||||||
},
|
},
|
||||||
|
editor: createEditor({ inlines: true, lists: true, links: true }),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
|
@ -1,4 +1,5 @@
|
||||||
import { Block } from "payload/types";
|
import { Block } from "payload/types";
|
||||||
|
import { createEditor } from "../utils/editor";
|
||||||
|
|
||||||
export const lineBlock: Block = {
|
export const lineBlock: Block = {
|
||||||
slug: "lineBlock",
|
slug: "lineBlock",
|
||||||
|
@ -10,6 +11,10 @@ export const lineBlock: Block = {
|
||||||
label: false,
|
label: false,
|
||||||
type: "richText",
|
type: "richText",
|
||||||
required: true,
|
required: true,
|
||||||
|
admin: {
|
||||||
|
className: "reduced-margins",
|
||||||
|
},
|
||||||
|
editor: createEditor({ inlines: true, lists: true, links: true }),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
|
@ -0,0 +1,31 @@
|
||||||
|
import { Block } from "payload/types";
|
||||||
|
import { createEditor } from "../utils/editor";
|
||||||
|
import { transcriptBlock } from "./transcriptBlock";
|
||||||
|
|
||||||
|
const generateRecursiveSectionBlock = (depth = 1, maxDepth = 5): Block => ({
|
||||||
|
slug: "sectionBlock",
|
||||||
|
interfaceName: "SectionBlock",
|
||||||
|
labels: { singular: "Section", plural: "Sections" },
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: "lines",
|
||||||
|
type: "richText",
|
||||||
|
label: false,
|
||||||
|
required: true,
|
||||||
|
editor: createEditor({
|
||||||
|
images: true,
|
||||||
|
inlines: true,
|
||||||
|
lists: true,
|
||||||
|
links: true,
|
||||||
|
relations: true,
|
||||||
|
alignment: true,
|
||||||
|
blocks: [
|
||||||
|
transcriptBlock,
|
||||||
|
...(depth < maxDepth ? [generateRecursiveSectionBlock(depth + 1, maxDepth)] : []),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
export const sectionBlock: Block = generateRecursiveSectionBlock();
|
|
@ -1,6 +1,6 @@
|
||||||
import { Block } from "payload/types";
|
import { Block } from "payload/types";
|
||||||
import { lineBlock } from "./lineBlock";
|
|
||||||
import { cueBlock } from "./cueBlock";
|
import { cueBlock } from "./cueBlock";
|
||||||
|
import { lineBlock } from "./lineBlock";
|
||||||
|
|
||||||
export const transcriptBlock: Block = {
|
export const transcriptBlock: Block = {
|
||||||
slug: "transcriptBlock",
|
slug: "transcriptBlock",
|
||||||
|
@ -12,7 +12,7 @@ export const transcriptBlock: Block = {
|
||||||
type: "blocks",
|
type: "blocks",
|
||||||
required: true,
|
required: true,
|
||||||
minRows: 1,
|
minRows: 1,
|
||||||
admin: { initCollapsed: true },
|
admin: { initCollapsed: true, className: "no-label" },
|
||||||
blocks: [lineBlock, cueBlock],
|
blocks: [lineBlock, cueBlock],
|
||||||
},
|
},
|
||||||
],
|
],
|
|
@ -5,6 +5,7 @@ import { backPropagationField } from "../../fields/backPropagationField/backProp
|
||||||
import { slugField } from "../../fields/slugField/slugField";
|
import { slugField } from "../../fields/slugField/slugField";
|
||||||
import { translatedFields } from "../../fields/translatedFields/translatedFields";
|
import { translatedFields } from "../../fields/translatedFields/translatedFields";
|
||||||
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
||||||
|
import { createEditor } from "../../utils/editor";
|
||||||
import { getAllEndpoint } from "./endpoints/getAllEndpoint";
|
import { getAllEndpoint } from "./endpoints/getAllEndpoint";
|
||||||
import { importFromStrapi } from "./endpoints/importFromStrapi";
|
import { importFromStrapi } from "./endpoints/importFromStrapi";
|
||||||
import { beforeValidateEndingGreaterThanStarting } from "./hooks/beforeValidateEndingGreaterThanStarting";
|
import { beforeValidateEndingGreaterThanStarting } from "./hooks/beforeValidateEndingGreaterThanStarting";
|
||||||
|
@ -68,7 +69,8 @@ export const ChronologyEras: CollectionConfig = buildCollectionConfig({
|
||||||
{ name: fields.translationsTitle, type: "text", required: true },
|
{ name: fields.translationsTitle, type: "text", required: true },
|
||||||
{
|
{
|
||||||
name: fields.translationsDescription,
|
name: fields.translationsDescription,
|
||||||
type: "textarea",
|
type: "richText",
|
||||||
|
editor: createEditor({ inlines: true, lists: true, links: true }),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -6,6 +6,7 @@ import {
|
||||||
} from "../../components/QuickFilters";
|
} from "../../components/QuickFilters";
|
||||||
import { CollectionGroups, Collections } from "../../constants";
|
import { CollectionGroups, Collections } from "../../constants";
|
||||||
import { translatedFields } from "../../fields/translatedFields/translatedFields";
|
import { translatedFields } from "../../fields/translatedFields/translatedFields";
|
||||||
|
import { createEditor } from "../../utils/editor";
|
||||||
import { buildVersionedCollectionConfig } from "../../utils/versionedCollectionConfig";
|
import { buildVersionedCollectionConfig } from "../../utils/versionedCollectionConfig";
|
||||||
import { importFromStrapi } from "./endpoints/importFromStrapi";
|
import { importFromStrapi } from "./endpoints/importFromStrapi";
|
||||||
import { beforeValidatePopulateNameField } from "./hooks/beforeValidatePopulateNameField";
|
import { beforeValidatePopulateNameField } from "./hooks/beforeValidatePopulateNameField";
|
||||||
|
@ -127,9 +128,14 @@ export const ChronologyItems: CollectionConfig = buildVersionedCollectionConfig(
|
||||||
{
|
{
|
||||||
name: fields.eventsTranslationsDescription,
|
name: fields.eventsTranslationsDescription,
|
||||||
validate: validateEventsTranslationsDescription,
|
validate: validateEventsTranslationsDescription,
|
||||||
type: "textarea",
|
type: "richText",
|
||||||
|
editor: createEditor({ inlines: true, lists: true, links: true }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: fields.eventsTranslationsNotes,
|
||||||
|
type: "richText",
|
||||||
|
editor: createEditor({ inlines: true, lists: true, links: true }),
|
||||||
},
|
},
|
||||||
{ name: fields.eventsTranslationsNotes, type: "textarea" },
|
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { sectionBlock } from "../../blocks/sectionBlock";
|
||||||
|
import { transcriptBlock } from "../../blocks/transcriptBlock";
|
||||||
import { CollectionGroups, Collections, FileTypes, KeysTypes } from "../../constants";
|
import { CollectionGroups, Collections, FileTypes, KeysTypes } from "../../constants";
|
||||||
import { fileField } from "../../fields/fileField/fileField";
|
import { fileField } from "../../fields/fileField/fileField";
|
||||||
import { imageField } from "../../fields/imageField/imageField";
|
import { imageField } from "../../fields/imageField/imageField";
|
||||||
|
@ -8,7 +10,9 @@ import { beforeDuplicateAddCopyTo } from "../../hooks/beforeDuplicateAddCopyTo";
|
||||||
import { beforeDuplicatePiping } from "../../hooks/beforeDuplicatePiping";
|
import { beforeDuplicatePiping } from "../../hooks/beforeDuplicatePiping";
|
||||||
import { beforeDuplicateUnpublish } from "../../hooks/beforeDuplicateUnpublish";
|
import { beforeDuplicateUnpublish } from "../../hooks/beforeDuplicateUnpublish";
|
||||||
import { isDefined } from "../../utils/asserts";
|
import { isDefined } from "../../utils/asserts";
|
||||||
|
import { createEditor } from "../../utils/editor";
|
||||||
import { buildVersionedCollectionConfig } from "../../utils/versionedCollectionConfig";
|
import { buildVersionedCollectionConfig } from "../../utils/versionedCollectionConfig";
|
||||||
|
import { importFromStrapi } from "./endpoints/importFromStrapi";
|
||||||
|
|
||||||
const fields = {
|
const fields = {
|
||||||
slug: "slug",
|
slug: "slug",
|
||||||
|
@ -61,6 +65,7 @@ export const Contents = buildVersionedCollectionConfig({
|
||||||
},
|
},
|
||||||
preview: (doc) => `https://accords-library.com/contents/${doc.slug}`,
|
preview: (doc) => `https://accords-library.com/contents/${doc.slug}`,
|
||||||
},
|
},
|
||||||
|
endpoints: [importFromStrapi],
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
type: "row",
|
type: "row",
|
||||||
|
@ -103,7 +108,11 @@ export const Contents = buildVersionedCollectionConfig({
|
||||||
{ name: fields.subtitle, type: "text" },
|
{ name: fields.subtitle, type: "text" },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{ name: fields.summary, type: "textarea" },
|
{
|
||||||
|
name: fields.summary,
|
||||||
|
type: "richText",
|
||||||
|
editor: createEditor({ inlines: true, lists: true, links: true }),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: "tabs",
|
type: "tabs",
|
||||||
admin: {
|
admin: {
|
||||||
|
@ -114,7 +123,20 @@ export const Contents = buildVersionedCollectionConfig({
|
||||||
{
|
{
|
||||||
label: "Text",
|
label: "Text",
|
||||||
fields: [
|
fields: [
|
||||||
{ name: fields.textContent, type: "richText" },
|
{
|
||||||
|
name: fields.textContent,
|
||||||
|
type: "richText",
|
||||||
|
label: false,
|
||||||
|
editor: createEditor({
|
||||||
|
blocks: [sectionBlock, transcriptBlock],
|
||||||
|
images: true,
|
||||||
|
inlines: true,
|
||||||
|
lists: true,
|
||||||
|
links: true,
|
||||||
|
relations: true,
|
||||||
|
alignment: true,
|
||||||
|
}),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: "row",
|
type: "row",
|
||||||
fields: [
|
fields: [
|
||||||
|
@ -155,7 +177,8 @@ export const Contents = buildVersionedCollectionConfig({
|
||||||
{
|
{
|
||||||
name: fields.textNotes,
|
name: fields.textNotes,
|
||||||
label: "Notes",
|
label: "Notes",
|
||||||
type: "textarea",
|
type: "richText",
|
||||||
|
editor: createEditor({ inlines: true, lists: true, links: true }),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -173,7 +196,8 @@ export const Contents = buildVersionedCollectionConfig({
|
||||||
{
|
{
|
||||||
name: fields.videoNotes,
|
name: fields.videoNotes,
|
||||||
label: "Notes",
|
label: "Notes",
|
||||||
type: "textarea",
|
type: "richText",
|
||||||
|
editor: createEditor({ inlines: true, lists: true, links: true }),
|
||||||
admin: { width: "0%" },
|
admin: { width: "0%" },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -194,7 +218,8 @@ export const Contents = buildVersionedCollectionConfig({
|
||||||
{
|
{
|
||||||
name: fields.audioNotes,
|
name: fields.audioNotes,
|
||||||
label: "Notes",
|
label: "Notes",
|
||||||
type: "textarea",
|
type: "richText",
|
||||||
|
editor: createEditor({ inlines: true, lists: true, links: true }),
|
||||||
admin: { width: "0%" },
|
admin: { width: "0%" },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -0,0 +1,121 @@
|
||||||
|
import type { MarkOptional } from "ts-essentials";
|
||||||
|
import { Collections } from "../../../constants";
|
||||||
|
import { createStrapiImportEndpoint } from "../../../endpoints/createStrapiImportEndpoint";
|
||||||
|
import { Content } from "../../../types/collections";
|
||||||
|
import { StrapiImage, StrapiLanguage, StrapiRecorders } from "../../../types/strapi";
|
||||||
|
import { isNotEmpty, isUndefined } from "../../../utils/asserts";
|
||||||
|
import {
|
||||||
|
findCategory,
|
||||||
|
findContentType,
|
||||||
|
findRecorder,
|
||||||
|
uploadStrapiImage,
|
||||||
|
} from "../../../utils/localApi";
|
||||||
|
import { plainTextToLexical } from "../../../utils/string";
|
||||||
|
|
||||||
|
type StrapiContent = {
|
||||||
|
slug: string;
|
||||||
|
categories: { data?: { attributes: { slug: string } }[] };
|
||||||
|
type: { data?: { attributes: { slug: string } } };
|
||||||
|
thumbnail: StrapiImage;
|
||||||
|
translations: {
|
||||||
|
title: string;
|
||||||
|
subtitle?: string;
|
||||||
|
pre_title?: string;
|
||||||
|
description?: string;
|
||||||
|
language: StrapiLanguage;
|
||||||
|
text_set?: {
|
||||||
|
text: string;
|
||||||
|
notes?: string;
|
||||||
|
source_language: StrapiLanguage;
|
||||||
|
transcribers: StrapiRecorders;
|
||||||
|
translators: StrapiRecorders;
|
||||||
|
proofreaders: StrapiRecorders;
|
||||||
|
};
|
||||||
|
}[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const importFromStrapi = createStrapiImportEndpoint<StrapiContent>({
|
||||||
|
strapi: {
|
||||||
|
collection: "contents",
|
||||||
|
params: {
|
||||||
|
populate: [
|
||||||
|
"type",
|
||||||
|
"categories",
|
||||||
|
"thumbnail",
|
||||||
|
"translations",
|
||||||
|
"translations.language",
|
||||||
|
"translations.text_set",
|
||||||
|
"translations.text_set.source_language",
|
||||||
|
"translations.text_set.transcribers",
|
||||||
|
"translations.text_set.translators",
|
||||||
|
"translations.text_set.proofreaders",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
payload: {
|
||||||
|
collection: Collections.Contents,
|
||||||
|
convert: async ({ slug, categories, type, thumbnail, translations }) => {
|
||||||
|
const thumbnailId = await uploadStrapiImage({
|
||||||
|
collection: Collections.ContentsThumbnails,
|
||||||
|
image: thumbnail,
|
||||||
|
});
|
||||||
|
|
||||||
|
const data: MarkOptional<Content, "createdAt" | "id" | "updatedAt" | "updatedBy"> = {
|
||||||
|
slug,
|
||||||
|
categories:
|
||||||
|
categories.data &&
|
||||||
|
(await Promise.all(
|
||||||
|
categories.data.map(async (category) => await findCategory(category.attributes.slug))
|
||||||
|
)),
|
||||||
|
type: type.data && (await findContentType(type.data?.attributes.slug)),
|
||||||
|
thumbnail: thumbnailId,
|
||||||
|
translations: await Promise.all(
|
||||||
|
translations.map(
|
||||||
|
async ({ language, title, description, pre_title, subtitle, text_set }) => {
|
||||||
|
if (isUndefined(language.data))
|
||||||
|
throw new Error("A language is required for a content translation");
|
||||||
|
if (isUndefined(text_set))
|
||||||
|
throw new Error("Only content with text_set are supported");
|
||||||
|
if (isUndefined(text_set.source_language.data))
|
||||||
|
throw new Error("A language is required for a content translation text_set");
|
||||||
|
return {
|
||||||
|
language: language.data.attributes.code,
|
||||||
|
sourceLanguage: text_set.source_language.data.attributes.code,
|
||||||
|
title,
|
||||||
|
pretitle: pre_title,
|
||||||
|
subtitle,
|
||||||
|
summary: isNotEmpty(description) ? plainTextToLexical(description) : undefined,
|
||||||
|
textContent: plainTextToLexical(text_set.text),
|
||||||
|
textNotes: isNotEmpty(text_set.notes)
|
||||||
|
? plainTextToLexical(text_set.notes)
|
||||||
|
: undefined,
|
||||||
|
textTranscribers:
|
||||||
|
text_set.transcribers.data &&
|
||||||
|
(await Promise.all(
|
||||||
|
text_set.transcribers.data?.map(async (recorder) =>
|
||||||
|
findRecorder(recorder.attributes.username)
|
||||||
|
)
|
||||||
|
)),
|
||||||
|
textTranslators:
|
||||||
|
text_set.translators.data &&
|
||||||
|
(await Promise.all(
|
||||||
|
text_set.translators.data?.map(async (recorder) =>
|
||||||
|
findRecorder(recorder.attributes.username)
|
||||||
|
)
|
||||||
|
)),
|
||||||
|
textProofreaders:
|
||||||
|
text_set.proofreaders.data &&
|
||||||
|
(await Promise.all(
|
||||||
|
text_set.proofreaders.data?.map(async (recorder) =>
|
||||||
|
findRecorder(recorder.attributes.username)
|
||||||
|
)
|
||||||
|
)),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
)
|
||||||
|
),
|
||||||
|
};
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
|
@ -2,6 +2,7 @@ import { CollectionGroups, Collections } from "../../constants";
|
||||||
import { slugField } from "../../fields/slugField/slugField";
|
import { slugField } from "../../fields/slugField/slugField";
|
||||||
import { translatedFields } from "../../fields/translatedFields/translatedFields";
|
import { translatedFields } from "../../fields/translatedFields/translatedFields";
|
||||||
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
||||||
|
import { importFromStrapi } from "./endpoints/importFromStrapi";
|
||||||
|
|
||||||
const fields = {
|
const fields = {
|
||||||
slug: "slug",
|
slug: "slug",
|
||||||
|
@ -24,13 +25,13 @@ export const ContentsFolders = buildCollectionConfig({
|
||||||
disableDuplicate: true,
|
disableDuplicate: true,
|
||||||
group: CollectionGroups.Collections,
|
group: CollectionGroups.Collections,
|
||||||
},
|
},
|
||||||
|
endpoints: [importFromStrapi],
|
||||||
timestamps: false,
|
timestamps: false,
|
||||||
versions: false,
|
versions: false,
|
||||||
fields: [
|
fields: [
|
||||||
slugField({ name: fields.slug }),
|
slugField({ name: fields.slug }),
|
||||||
translatedFields({
|
translatedFields({
|
||||||
name: fields.translations,
|
name: fields.translations,
|
||||||
interfaceName: "ContentFoldersTranslation",
|
|
||||||
admin: {
|
admin: {
|
||||||
useAsTitle: fields.name,
|
useAsTitle: fields.name,
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,107 @@
|
||||||
|
import payload from "payload";
|
||||||
|
import QueryString from "qs";
|
||||||
|
import { Collections } from "../../../constants";
|
||||||
|
import { CollectionEndpoint } from "../../../types/payload";
|
||||||
|
import { StrapiLanguage } from "../../../types/strapi";
|
||||||
|
import { isUndefined } from "../../../utils/asserts";
|
||||||
|
|
||||||
|
type StrapiContentsFolder = {
|
||||||
|
id: string;
|
||||||
|
attributes: {
|
||||||
|
slug: string;
|
||||||
|
titles?: { title: string; language: StrapiLanguage }[];
|
||||||
|
subfolders: { data: StrapiContentsFolder[] };
|
||||||
|
contents: { data: { id: number }[] };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const getStrapiContentFolder = async (id: number): Promise<StrapiContentsFolder> => {
|
||||||
|
const paramsWithPagination = QueryString.stringify({
|
||||||
|
populate: [
|
||||||
|
"subfolders",
|
||||||
|
"subfolders.contents",
|
||||||
|
"subfolders.titles",
|
||||||
|
"subfolders.titles.language",
|
||||||
|
"subfolders.subfolders",
|
||||||
|
"subfolders.subfolders.contents",
|
||||||
|
"subfolders.subfolders.titles",
|
||||||
|
"subfolders.subfolders.titles.language",
|
||||||
|
"subfolders.subfolders.subfolders",
|
||||||
|
"subfolders.subfolders.subfolders.contents",
|
||||||
|
"subfolders.subfolders.subfolders.titles",
|
||||||
|
"subfolders.subfolders.subfolders.titles.language",
|
||||||
|
"subfolders.subfolders.subfolders.subfolders",
|
||||||
|
"subfolders.subfolders.subfolders.subfolders.contents",
|
||||||
|
"subfolders.subfolders.subfolders.subfolders.titles",
|
||||||
|
"subfolders.subfolders.subfolders.subfolders.titles.language",
|
||||||
|
"subfolders.subfolders.subfolders.subfolders.subfolders",
|
||||||
|
"subfolders.subfolders.subfolders.subfolders.subfolders.contents",
|
||||||
|
"subfolders.subfolders.subfolders.subfolders.subfolders.titles",
|
||||||
|
"subfolders.subfolders.subfolders.subfolders.subfolders.titles.language",
|
||||||
|
"subfolders.subfolders.subfolders.subfolders.subfolders.subfolders",
|
||||||
|
"subfolders.subfolders.subfolders.subfolders.subfolders.subfolders.contents",
|
||||||
|
"subfolders.subfolders.subfolders.subfolders.subfolders.subfolders.titles",
|
||||||
|
"subfolders.subfolders.subfolders.subfolders.subfolders.subfolders.titles.language",
|
||||||
|
"subfolders.subfolders.subfolders.subfolders.subfolders.subfolders.subfolders",
|
||||||
|
"subfolders.subfolders.subfolders.subfolders.subfolders.subfolders.subfolders.contents",
|
||||||
|
"subfolders.subfolders.subfolders.subfolders.subfolders.subfolders.subfolders.titles",
|
||||||
|
"subfolders.subfolders.subfolders.subfolders.subfolders.subfolders.subfolders.titles.language",
|
||||||
|
],
|
||||||
|
});
|
||||||
|
const uri = `${process.env.STRAPI_URI}/api/contents-folders/${id}?${paramsWithPagination}`;
|
||||||
|
const fetchResult = await fetch(uri, {
|
||||||
|
method: "get",
|
||||||
|
headers: { authorization: `Bearer ${process.env.STRAPI_TOKEN}` },
|
||||||
|
});
|
||||||
|
const { data } = await fetchResult.json();
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const importFromStrapi: CollectionEndpoint = {
|
||||||
|
method: "post",
|
||||||
|
path: "/strapi",
|
||||||
|
handler: async (req, res) => {
|
||||||
|
if (!req.user) {
|
||||||
|
return res.status(403).send({
|
||||||
|
errors: [
|
||||||
|
{
|
||||||
|
message: "You are not allowed to perform this action.",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let foldersCreated = 0;
|
||||||
|
|
||||||
|
const createContentFolder = async (data: StrapiContentsFolder): Promise<string> => {
|
||||||
|
const subfolders = await Promise.all(
|
||||||
|
data.attributes.subfolders.data.map(createContentFolder)
|
||||||
|
);
|
||||||
|
const { slug, titles } = data.attributes;
|
||||||
|
const result = await payload.create({
|
||||||
|
collection: Collections.ContentsFolders,
|
||||||
|
data: {
|
||||||
|
slug,
|
||||||
|
subfolders,
|
||||||
|
translations: titles?.map(({ title, language }) => {
|
||||||
|
if (isUndefined(language.data))
|
||||||
|
throw new Error("A language is required for a content folder translation");
|
||||||
|
return { language: language.data.attributes.code, name: title };
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
user: req.user,
|
||||||
|
});
|
||||||
|
foldersCreated++;
|
||||||
|
return result.id;
|
||||||
|
};
|
||||||
|
|
||||||
|
const rootFolder = await getStrapiContentFolder(72);
|
||||||
|
try {
|
||||||
|
await createContentFolder(rootFolder);
|
||||||
|
} catch (e) {
|
||||||
|
res.status(500).json({ message: "Something went wrong", error: e });
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(200).json({ message: `${foldersCreated} entries have been added successfully.` });
|
||||||
|
},
|
||||||
|
};
|
|
@ -0,0 +1,67 @@
|
||||||
|
import { CollectionGroups, Collections } from "../../constants";
|
||||||
|
import { slugField } from "../../fields/slugField/slugField";
|
||||||
|
import { translatedFields } from "../../fields/translatedFields/translatedFields";
|
||||||
|
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
||||||
|
import { createEditor } from "../../utils/editor";
|
||||||
|
|
||||||
|
const fields = {
|
||||||
|
slug: "slug",
|
||||||
|
translations: "translations",
|
||||||
|
name: "name",
|
||||||
|
description: "description",
|
||||||
|
subfolders: "subfolders",
|
||||||
|
items: "items",
|
||||||
|
} as const satisfies Record<string, string>;
|
||||||
|
|
||||||
|
export const LibraryFolders = buildCollectionConfig({
|
||||||
|
slug: Collections.LibraryFolders,
|
||||||
|
labels: {
|
||||||
|
singular: "Library Folder",
|
||||||
|
plural: "Library Folders",
|
||||||
|
},
|
||||||
|
defaultSort: fields.slug,
|
||||||
|
admin: {
|
||||||
|
useAsTitle: fields.slug,
|
||||||
|
defaultColumns: [fields.slug, fields.translations],
|
||||||
|
disableDuplicate: true,
|
||||||
|
group: CollectionGroups.Collections,
|
||||||
|
},
|
||||||
|
timestamps: false,
|
||||||
|
versions: false,
|
||||||
|
fields: [
|
||||||
|
slugField({ name: fields.slug }),
|
||||||
|
translatedFields({
|
||||||
|
name: fields.translations,
|
||||||
|
admin: {
|
||||||
|
useAsTitle: fields.name,
|
||||||
|
},
|
||||||
|
fields: [
|
||||||
|
{ name: fields.name, type: "text", required: true },
|
||||||
|
{
|
||||||
|
name: fields.description,
|
||||||
|
type: "richText",
|
||||||
|
editor: createEditor({ inlines: true, lists: true, links: true }),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
type: "row",
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
type: "relationship",
|
||||||
|
name: fields.subfolders,
|
||||||
|
relationTo: Collections.LibraryFolders,
|
||||||
|
hasMany: true,
|
||||||
|
admin: { width: "0%" },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "relationship",
|
||||||
|
name: fields.items,
|
||||||
|
relationTo: Collections.LibraryItems,
|
||||||
|
hasMany: true,
|
||||||
|
admin: { width: "0%" },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
|
@ -19,6 +19,7 @@ import { beforeDuplicatePiping } from "../../hooks/beforeDuplicatePiping";
|
||||||
import { beforeDuplicateUnpublish } from "../../hooks/beforeDuplicateUnpublish";
|
import { beforeDuplicateUnpublish } from "../../hooks/beforeDuplicateUnpublish";
|
||||||
import { LibraryItem } from "../../types/collections";
|
import { LibraryItem } from "../../types/collections";
|
||||||
import { isDefined } from "../../utils/asserts";
|
import { isDefined } from "../../utils/asserts";
|
||||||
|
import { createEditor } from "../../utils/editor";
|
||||||
import { buildVersionedCollectionConfig } from "../../utils/versionedCollectionConfig";
|
import { buildVersionedCollectionConfig } from "../../utils/versionedCollectionConfig";
|
||||||
import { RowLabel } from "./components/RowLabel";
|
import { RowLabel } from "./components/RowLabel";
|
||||||
|
|
||||||
|
@ -146,15 +147,32 @@ export const LibraryItems = buildVersionedCollectionConfig({
|
||||||
},
|
},
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: fields.itemType,
|
type: "row",
|
||||||
type: "radio",
|
fields: [
|
||||||
options: Object.entries(LibraryItemsTypes).map(([value, label]) => ({
|
{
|
||||||
label,
|
name: fields.itemType,
|
||||||
value,
|
type: "radio",
|
||||||
})),
|
options: Object.entries(LibraryItemsTypes).map(([value, label]) => ({
|
||||||
admin: {
|
label,
|
||||||
layout: "horizontal",
|
value,
|
||||||
},
|
})),
|
||||||
|
admin: {
|
||||||
|
layout: "horizontal",
|
||||||
|
width: "0%",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: fields.digital,
|
||||||
|
type: "checkbox",
|
||||||
|
required: true,
|
||||||
|
defaultValue: false,
|
||||||
|
admin: {
|
||||||
|
description:
|
||||||
|
"The item is the digital version of another item, or the item is sold only digitally.",
|
||||||
|
width: "0%",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "tabs",
|
type: "tabs",
|
||||||
|
@ -209,27 +227,6 @@ export const LibraryItems = buildVersionedCollectionConfig({
|
||||||
width: "0%",
|
width: "0%",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: fields.digital,
|
|
||||||
type: "checkbox",
|
|
||||||
required: true,
|
|
||||||
defaultValue: false,
|
|
||||||
admin: {
|
|
||||||
description:
|
|
||||||
"The item is the digital version of another item, or the item is sold only digitally.",
|
|
||||||
width: "0%",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: fields.downloadable,
|
|
||||||
type: "checkbox",
|
|
||||||
required: true,
|
|
||||||
defaultValue: false,
|
|
||||||
admin: {
|
|
||||||
description: "Are the scans available for download?",
|
|
||||||
width: "0%",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -505,6 +502,16 @@ export const LibraryItems = buildVersionedCollectionConfig({
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: fields.downloadable,
|
||||||
|
type: "checkbox",
|
||||||
|
required: true,
|
||||||
|
defaultValue: false,
|
||||||
|
admin: {
|
||||||
|
description: "Are the scans available for download?",
|
||||||
|
width: "0%",
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
@ -559,6 +566,7 @@ export const LibraryItems = buildVersionedCollectionConfig({
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
admin: {
|
admin: {
|
||||||
|
condition: (data: Partial<LibraryItem>) => !data.digital,
|
||||||
layout: "horizontal",
|
layout: "horizontal",
|
||||||
width: "0%",
|
width: "0%",
|
||||||
},
|
},
|
||||||
|
@ -654,11 +662,18 @@ export const LibraryItems = buildVersionedCollectionConfig({
|
||||||
name: fields.translations,
|
name: fields.translations,
|
||||||
label: "Descriptions",
|
label: "Descriptions",
|
||||||
admin: { initCollapsed: true, useAsTitle: fields.translationsDescription },
|
admin: { initCollapsed: true, useAsTitle: fields.translationsDescription },
|
||||||
fields: [{ name: fields.translationsDescription, type: "textarea", required: true }],
|
fields: [
|
||||||
|
{
|
||||||
|
name: fields.translationsDescription,
|
||||||
|
required: true,
|
||||||
|
type: "richText",
|
||||||
|
editor: createEditor({ inlines: true, lists: true, links: true }),
|
||||||
|
},
|
||||||
|
],
|
||||||
}),
|
}),
|
||||||
optionalGroupField({
|
optionalGroupField({
|
||||||
name: fields.size,
|
name: fields.size,
|
||||||
admin: { condition: (data) => !data.digital },
|
admin: { condition: (data: Partial<LibraryItem>) => !data.digital },
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
type: "row",
|
type: "row",
|
||||||
|
@ -763,7 +778,8 @@ export const LibraryItems = buildVersionedCollectionConfig({
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: fields.contentsNote,
|
name: fields.contentsNote,
|
||||||
type: "textarea",
|
type: "richText",
|
||||||
|
editor: createEditor({ inlines: true, lists: true, links: true }),
|
||||||
admin: {
|
admin: {
|
||||||
condition: ({ itemType }) =>
|
condition: ({ itemType }) =>
|
||||||
itemType === LibraryItemsTypes.Game || itemType === LibraryItemsTypes.Other,
|
itemType === LibraryItemsTypes.Game || itemType === LibraryItemsTypes.Other,
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
import { CollectionConfig } from "payload/types";
|
||||||
|
import { Collections } from "../../constants";
|
||||||
|
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
||||||
|
import { createEditor } from "../../utils/editor";
|
||||||
|
|
||||||
|
export const Notes: CollectionConfig = buildCollectionConfig({
|
||||||
|
slug: Collections.Notes,
|
||||||
|
labels: { singular: "Note", plural: "Notes" },
|
||||||
|
admin: {
|
||||||
|
// TODO: Reenable when we can use rich text as titles useAsTitle: fields.biography,
|
||||||
|
},
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: "note",
|
||||||
|
type: "richText",
|
||||||
|
required: true,
|
||||||
|
editor: createEditor({ inlines: true, lists: true, links: true }),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
|
@ -7,6 +7,7 @@ import { beforeDuplicateAddCopyTo } from "../../hooks/beforeDuplicateAddCopyTo";
|
||||||
import { beforeDuplicatePiping } from "../../hooks/beforeDuplicatePiping";
|
import { beforeDuplicatePiping } from "../../hooks/beforeDuplicatePiping";
|
||||||
import { beforeDuplicateUnpublish } from "../../hooks/beforeDuplicateUnpublish";
|
import { beforeDuplicateUnpublish } from "../../hooks/beforeDuplicateUnpublish";
|
||||||
import { isDefined, isUndefined } from "../../utils/asserts";
|
import { isDefined, isUndefined } from "../../utils/asserts";
|
||||||
|
import { createEditor } from "../../utils/editor";
|
||||||
import { buildVersionedCollectionConfig } from "../../utils/versionedCollectionConfig";
|
import { buildVersionedCollectionConfig } from "../../utils/versionedCollectionConfig";
|
||||||
|
|
||||||
const fields = {
|
const fields = {
|
||||||
|
@ -97,7 +98,11 @@ export const Posts = buildVersionedCollectionConfig({
|
||||||
minRows: 1,
|
minRows: 1,
|
||||||
fields: [
|
fields: [
|
||||||
{ name: fields.title, type: "text", required: true },
|
{ name: fields.title, type: "text", required: true },
|
||||||
{ name: fields.summary, type: "textarea" },
|
{
|
||||||
|
name: fields.summary,
|
||||||
|
type: "richText",
|
||||||
|
editor: createEditor({ inlines: true, lists: true, links: true }),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: "row",
|
type: "row",
|
||||||
fields: [
|
fields: [
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { CollectionGroups, Collections, RecordersRoles } from "../../constants";
|
||||||
import { imageField } from "../../fields/imageField/imageField";
|
import { imageField } from "../../fields/imageField/imageField";
|
||||||
import { translatedFields } from "../../fields/translatedFields/translatedFields";
|
import { translatedFields } from "../../fields/translatedFields/translatedFields";
|
||||||
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
||||||
|
import { createEditor } from "../../utils/editor";
|
||||||
import { importFromStrapi } from "./endpoints/importFromStrapi";
|
import { importFromStrapi } from "./endpoints/importFromStrapi";
|
||||||
import { beforeLoginMustHaveAtLeastOneRole } from "./hooks/beforeLoginMustHaveAtLeastOneRole";
|
import { beforeLoginMustHaveAtLeastOneRole } from "./hooks/beforeLoginMustHaveAtLeastOneRole";
|
||||||
|
|
||||||
|
@ -107,11 +108,18 @@ export const Recorders = buildCollectionConfig({
|
||||||
name: fields.biographies,
|
name: fields.biographies,
|
||||||
interfaceName: "RecorderBiographies",
|
interfaceName: "RecorderBiographies",
|
||||||
admin: {
|
admin: {
|
||||||
useAsTitle: fields.biography,
|
// TODO: Reenable when we can use rich text as titles useAsTitle: fields.biography,
|
||||||
description:
|
description:
|
||||||
"A short personal description about you or your involvement with this project or the franchise",
|
"A short personal description about you or your involvement with this project or the franchise",
|
||||||
},
|
},
|
||||||
fields: [{ name: fields.biography, required: true, type: "textarea" }],
|
fields: [
|
||||||
|
{
|
||||||
|
name: fields.biography,
|
||||||
|
required: true,
|
||||||
|
type: "richText",
|
||||||
|
editor: createEditor({ inlines: true, lists: true, links: true }),
|
||||||
|
},
|
||||||
|
],
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
name: fields.role,
|
name: fields.role,
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { Recorder } from "../../../types/collections";
|
||||||
import { StrapiImage, StrapiLanguage } from "../../../types/strapi";
|
import { StrapiImage, StrapiLanguage } from "../../../types/strapi";
|
||||||
import { isDefined, isUndefined } from "../../../utils/asserts";
|
import { isDefined, isUndefined } from "../../../utils/asserts";
|
||||||
import { uploadStrapiImage } from "../../../utils/localApi";
|
import { uploadStrapiImage } from "../../../utils/localApi";
|
||||||
|
import { plainTextToLexical } from "../../../utils/string";
|
||||||
|
|
||||||
type StrapiRecorder = {
|
type StrapiRecorder = {
|
||||||
username: string;
|
username: string;
|
||||||
|
@ -19,7 +20,7 @@ export const importFromStrapi = createStrapiImportEndpoint<StrapiRecorder>({
|
||||||
strapi: {
|
strapi: {
|
||||||
collection: "recorders",
|
collection: "recorders",
|
||||||
params: {
|
params: {
|
||||||
populate: "bio.language,languages,avatar",
|
populate: ["bio.language", "languages", "avatar"],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
payload: {
|
payload: {
|
||||||
|
@ -52,7 +53,7 @@ export const importFromStrapi = createStrapiImportEndpoint<StrapiRecorder>({
|
||||||
if (isUndefined(bio)) throw new Error("A bio is required for a Recorder biography");
|
if (isUndefined(bio)) throw new Error("A bio is required for a Recorder biography");
|
||||||
return {
|
return {
|
||||||
language: language.data.attributes.code,
|
language: language.data.attributes.code,
|
||||||
biography: bio,
|
biography: plainTextToLexical(bio),
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
@ -72,10 +73,9 @@ export const importFromStrapi = createStrapiImportEndpoint<StrapiRecorder>({
|
||||||
if (isUndefined(bio)) throw new Error("A bio is required for a Recorder biography");
|
if (isUndefined(bio)) throw new Error("A bio is required for a Recorder biography");
|
||||||
return {
|
return {
|
||||||
language: language.data.attributes.code,
|
language: language.data.attributes.code,
|
||||||
biography: bio,
|
biography: plainTextToLexical(bio),
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
|
|
||||||
email: `${anonymous_code}@accords-library.com`,
|
email: `${anonymous_code}@accords-library.com`,
|
||||||
password: process.env.RECORDER_DEFAULT_PASSWORD,
|
password: process.env.RECORDER_DEFAULT_PASSWORD,
|
||||||
},
|
},
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { imageField } from "../../fields/imageField/imageField";
|
||||||
import { keysField } from "../../fields/keysField/keysField";
|
import { keysField } from "../../fields/keysField/keysField";
|
||||||
import { slugField } from "../../fields/slugField/slugField";
|
import { slugField } from "../../fields/slugField/slugField";
|
||||||
import { translatedFields } from "../../fields/translatedFields/translatedFields";
|
import { translatedFields } from "../../fields/translatedFields/translatedFields";
|
||||||
|
import { createEditor } from "../../utils/editor";
|
||||||
import { buildVersionedCollectionConfig } from "../../utils/versionedCollectionConfig";
|
import { buildVersionedCollectionConfig } from "../../utils/versionedCollectionConfig";
|
||||||
import { AppearanceRowLabel } from "./components/AppearanceRowLabel";
|
import { AppearanceRowLabel } from "./components/AppearanceRowLabel";
|
||||||
import { getBySlugEndpoint } from "./endpoints/getBySlugEndpoint";
|
import { getBySlugEndpoint } from "./endpoints/getBySlugEndpoint";
|
||||||
|
@ -113,7 +114,8 @@ export const Weapons = buildVersionedCollectionConfig({
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: fields.appearancesTranslationsDescription,
|
name: fields.appearancesTranslationsDescription,
|
||||||
type: "textarea",
|
type: "richText",
|
||||||
|
editor: createEditor({ inlines: true }),
|
||||||
admin: { width: "0%" },
|
admin: { width: "0%" },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -124,13 +126,15 @@ export const Weapons = buildVersionedCollectionConfig({
|
||||||
{
|
{
|
||||||
name: fields.appearancesTranslationsLevel1,
|
name: fields.appearancesTranslationsLevel1,
|
||||||
label: "Level 1",
|
label: "Level 1",
|
||||||
type: "textarea",
|
type: "richText",
|
||||||
|
editor: createEditor({ inlines: true }),
|
||||||
admin: { width: "0%" },
|
admin: { width: "0%" },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: fields.appearancesTranslationsLevel2,
|
name: fields.appearancesTranslationsLevel2,
|
||||||
label: "Level 2",
|
label: "Level 2",
|
||||||
type: "textarea",
|
type: "richText",
|
||||||
|
editor: createEditor({ inlines: true }),
|
||||||
admin: { width: "0%" },
|
admin: { width: "0%" },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -141,13 +145,15 @@ export const Weapons = buildVersionedCollectionConfig({
|
||||||
{
|
{
|
||||||
name: fields.appearancesTranslationsLevel3,
|
name: fields.appearancesTranslationsLevel3,
|
||||||
label: "Level 3",
|
label: "Level 3",
|
||||||
type: "textarea",
|
type: "richText",
|
||||||
|
editor: createEditor({ inlines: true }),
|
||||||
admin: { width: "0%" },
|
admin: { width: "0%" },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: fields.appearancesTranslationsLevel4,
|
name: fields.appearancesTranslationsLevel4,
|
||||||
label: "Level 4",
|
label: "Level 4",
|
||||||
type: "textarea",
|
type: "richText",
|
||||||
|
editor: createEditor({ inlines: true }),
|
||||||
admin: { width: "0%" },
|
admin: { width: "0%" },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -8,10 +8,12 @@ export enum Collections {
|
||||||
Files = "files",
|
Files = "files",
|
||||||
Keys = "keys",
|
Keys = "keys",
|
||||||
Languages = "languages",
|
Languages = "languages",
|
||||||
|
LibraryFolders = "library-folders",
|
||||||
LibraryItems = "library-items",
|
LibraryItems = "library-items",
|
||||||
LibraryItemsThumbnails = "library-items-thumbnails",
|
LibraryItemsThumbnails = "library-items-thumbnails",
|
||||||
LibraryItemsScans = "library-items-scans",
|
LibraryItemsScans = "library-items-scans",
|
||||||
LibraryItemsGallery = "library-items-gallery",
|
LibraryItemsGallery = "library-items-gallery",
|
||||||
|
Notes = "Notes",
|
||||||
Posts = "posts",
|
Posts = "posts",
|
||||||
PostsThumbnails = "posts-thumbnails",
|
PostsThumbnails = "posts-thumbnails",
|
||||||
Recorders = "recorders",
|
Recorders = "recorders",
|
||||||
|
|
|
@ -43,7 +43,7 @@ type Params<S> = {
|
||||||
convert?: (
|
convert?: (
|
||||||
strapiObject: S,
|
strapiObject: S,
|
||||||
user: any
|
user: any
|
||||||
) => Parameters<BasePayload<GeneratedTypes>["create"]>[0]["data"];
|
) => Promise<Parameters<BasePayload<GeneratedTypes>["create"]>[0]["data"]>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ export const importStrapiEntries = async <S>({
|
||||||
} else if (isDefined(payloadParams.convert)) {
|
} else if (isDefined(payloadParams.convert)) {
|
||||||
await payload.create({
|
await payload.create({
|
||||||
collection: payloadParams.collection,
|
collection: payloadParams.collection,
|
||||||
data: payloadParams.convert(attributes, user),
|
data: await payloadParams.convert(attributes, user),
|
||||||
user,
|
user,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -28,7 +28,7 @@ const languageField: Field = {
|
||||||
type: "relationship",
|
type: "relationship",
|
||||||
relationTo: Collections.Languages,
|
relationTo: Collections.Languages,
|
||||||
required: true,
|
required: true,
|
||||||
admin: { allowCreate: false, width: "0%" },
|
admin: { allowCreate: false },
|
||||||
};
|
};
|
||||||
|
|
||||||
const sourceLanguageField: Field = {
|
const sourceLanguageField: Field = {
|
||||||
|
@ -36,7 +36,7 @@ const sourceLanguageField: Field = {
|
||||||
type: "relationship",
|
type: "relationship",
|
||||||
relationTo: Collections.Languages,
|
relationTo: Collections.Languages,
|
||||||
required: true,
|
required: true,
|
||||||
admin: { allowCreate: false, width: "0%" },
|
admin: { allowCreate: false },
|
||||||
};
|
};
|
||||||
|
|
||||||
const creditFields: Field = {
|
const creditFields: Field = {
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
import { webpackBundler } from "@payloadcms/bundler-webpack";
|
import { webpackBundler } from "@payloadcms/bundler-webpack";
|
||||||
import { mongooseAdapter } from "@payloadcms/db-mongodb";
|
import { mongooseAdapter } from "@payloadcms/db-mongodb";
|
||||||
import { BlocksFeature, lexicalEditor } from "@payloadcms/richtext-lexical";
|
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { buildConfig } from "payload/config";
|
import { buildConfig } from "payload/config";
|
||||||
import { ChronologyEras } from "./collections/ChronologyEras/ChronologyEras";
|
import { ChronologyEras } from "./collections/ChronologyEras/ChronologyEras";
|
||||||
import { ChronologyItems } from "./collections/ChronologyItems/ChronologyItems";
|
import { ChronologyItems } from "./collections/ChronologyItems/ChronologyItems";
|
||||||
import { transcriptBlock } from "./collections/Contents/Blocks/transcriptBlock";
|
|
||||||
import { Contents } from "./collections/Contents/Contents";
|
import { Contents } from "./collections/Contents/Contents";
|
||||||
import { ContentsFolders } from "./collections/ContentsFolders/ContentsFolders";
|
import { ContentsFolders } from "./collections/ContentsFolders/ContentsFolders";
|
||||||
import { ContentsThumbnails } from "./collections/ContentsThumbnails/ContentsThumbnails";
|
import { ContentsThumbnails } from "./collections/ContentsThumbnails/ContentsThumbnails";
|
||||||
|
@ -13,10 +11,12 @@ import { Currencies } from "./collections/Currencies/Currencies";
|
||||||
import { Files } from "./collections/Files/Files";
|
import { Files } from "./collections/Files/Files";
|
||||||
import { Keys } from "./collections/Keys/Keys";
|
import { Keys } from "./collections/Keys/Keys";
|
||||||
import { Languages } from "./collections/Languages/Languages";
|
import { Languages } from "./collections/Languages/Languages";
|
||||||
|
import { LibraryFolders } from "./collections/LibraryFolders/LibraryFolders";
|
||||||
import { LibraryItems } from "./collections/LibraryItems/LibraryItems";
|
import { LibraryItems } from "./collections/LibraryItems/LibraryItems";
|
||||||
import { LibraryItemsGallery } from "./collections/LibraryItemsGallery/LibraryItemsGallery";
|
import { LibraryItemsGallery } from "./collections/LibraryItemsGallery/LibraryItemsGallery";
|
||||||
import { LibraryItemsScans } from "./collections/LibraryItemsScans/LibraryItemsScans";
|
import { LibraryItemsScans } from "./collections/LibraryItemsScans/LibraryItemsScans";
|
||||||
import { LibraryItemsThumbnails } from "./collections/LibraryItemsThumbnails/LibraryItemsThumbnails";
|
import { LibraryItemsThumbnails } from "./collections/LibraryItemsThumbnails/LibraryItemsThumbnails";
|
||||||
|
import { Notes } from "./collections/Notes/Notes";
|
||||||
import { Posts } from "./collections/Posts/Posts";
|
import { Posts } from "./collections/Posts/Posts";
|
||||||
import { PostsThumbnails } from "./collections/PostsThumbnails/PostsThumbnails";
|
import { PostsThumbnails } from "./collections/PostsThumbnails/PostsThumbnails";
|
||||||
import { Recorders } from "./collections/Recorders/Recorders";
|
import { Recorders } from "./collections/Recorders/Recorders";
|
||||||
|
@ -29,6 +29,7 @@ import { WeaponsThumbnails } from "./collections/WeaponsThumbnails/WeaponsThumbn
|
||||||
import { Icon } from "./components/Icon";
|
import { Icon } from "./components/Icon";
|
||||||
import { Logo } from "./components/Logo";
|
import { Logo } from "./components/Logo";
|
||||||
import { Collections } from "./constants";
|
import { Collections } from "./constants";
|
||||||
|
import { createEditor } from "./utils/editor";
|
||||||
|
|
||||||
export default buildConfig({
|
export default buildConfig({
|
||||||
serverURL: process.env.PAYLOAD_URI,
|
serverURL: process.env.PAYLOAD_URI,
|
||||||
|
@ -43,13 +44,9 @@ export default buildConfig({
|
||||||
css: path.resolve(__dirname, "styles.scss"),
|
css: path.resolve(__dirname, "styles.scss"),
|
||||||
bundler: webpackBundler(),
|
bundler: webpackBundler(),
|
||||||
},
|
},
|
||||||
editor: lexicalEditor({
|
editor: createEditor({}),
|
||||||
features: ({ defaultFeatures }) => [
|
|
||||||
...defaultFeatures,
|
|
||||||
BlocksFeature({ blocks: [transcriptBlock] }),
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
collections: [
|
collections: [
|
||||||
|
LibraryFolders,
|
||||||
LibraryItems,
|
LibraryItems,
|
||||||
Contents,
|
Contents,
|
||||||
ContentsFolders,
|
ContentsFolders,
|
||||||
|
@ -66,6 +63,7 @@ export default buildConfig({
|
||||||
RecordersThumbnails,
|
RecordersThumbnails,
|
||||||
PostsThumbnails,
|
PostsThumbnails,
|
||||||
Files,
|
Files,
|
||||||
|
Notes,
|
||||||
Videos,
|
Videos,
|
||||||
VideosChannels,
|
VideosChannels,
|
||||||
Languages,
|
Languages,
|
||||||
|
|
|
@ -56,6 +56,23 @@ html[data-theme="light"] {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.field-type.no-label > header {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lexical-block__block-pill-transcriptBlock + .section-title {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blocks-field__block-pill-cueBlock + .section-title {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rich-text-lexical.field-type.reduced-margins {
|
||||||
|
margin-top: -0.75em;
|
||||||
|
margin-bottom: -2rem;
|
||||||
|
}
|
||||||
|
|
||||||
.field-type.array-field.group-array {
|
.field-type.array-field.group-array {
|
||||||
> .array-field__header {
|
> .array-field__header {
|
||||||
.array-field__header-actions {
|
.array-field__header-actions {
|
||||||
|
|
|
@ -14,17 +14,15 @@ export type CategoryTranslations = {
|
||||||
}[];
|
}[];
|
||||||
export type RecorderBiographies = {
|
export type RecorderBiographies = {
|
||||||
language: string | Language;
|
language: string | Language;
|
||||||
biography: string;
|
biography: {
|
||||||
id?: string;
|
[k: string]: unknown;
|
||||||
}[];
|
}[];
|
||||||
export type ContentFoldersTranslation = {
|
|
||||||
language: string | Language;
|
|
||||||
name: string;
|
|
||||||
id?: string;
|
id?: string;
|
||||||
}[];
|
}[];
|
||||||
|
|
||||||
export interface Config {
|
export interface Config {
|
||||||
collections: {
|
collections: {
|
||||||
|
'library-folders': LibraryFolder;
|
||||||
'library-items': LibraryItem;
|
'library-items': LibraryItem;
|
||||||
contents: Content;
|
contents: Content;
|
||||||
'contents-folders': ContentsFolder;
|
'contents-folders': ContentsFolder;
|
||||||
|
@ -41,6 +39,7 @@ export interface Config {
|
||||||
'recorders-thumbnails': RecordersThumbnail;
|
'recorders-thumbnails': RecordersThumbnail;
|
||||||
'posts-thumbnails': PostThumbnail;
|
'posts-thumbnails': PostThumbnail;
|
||||||
files: File;
|
files: File;
|
||||||
|
Notes: Note;
|
||||||
videos: Video;
|
videos: Video;
|
||||||
'videos-channels': VideosChannel;
|
'videos-channels': VideosChannel;
|
||||||
languages: Language;
|
languages: Language;
|
||||||
|
@ -52,9 +51,28 @@ export interface Config {
|
||||||
};
|
};
|
||||||
globals: {};
|
globals: {};
|
||||||
}
|
}
|
||||||
|
export interface LibraryFolder {
|
||||||
|
id: string;
|
||||||
|
slug: string;
|
||||||
|
translations?: {
|
||||||
|
language: string | Language;
|
||||||
|
name: string;
|
||||||
|
description?: {
|
||||||
|
[k: string]: unknown;
|
||||||
|
}[];
|
||||||
|
id?: string;
|
||||||
|
}[];
|
||||||
|
subfolders?: string[] | LibraryFolder[];
|
||||||
|
items?: string[] | LibraryItem[];
|
||||||
|
}
|
||||||
|
export interface Language {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
export interface LibraryItem {
|
export interface LibraryItem {
|
||||||
id: string;
|
id: string;
|
||||||
itemType?: 'Textual' | 'Audio' | 'Video' | 'Game' | 'Other';
|
itemType?: 'Textual' | 'Audio' | 'Video' | 'Game' | 'Other';
|
||||||
|
digital: boolean;
|
||||||
slug: string;
|
slug: string;
|
||||||
thumbnail?: string | LibraryItemThumbnail;
|
thumbnail?: string | LibraryItemThumbnail;
|
||||||
pretitle?: string;
|
pretitle?: string;
|
||||||
|
@ -62,8 +80,6 @@ export interface LibraryItem {
|
||||||
subtitle?: string;
|
subtitle?: string;
|
||||||
rootItem: boolean;
|
rootItem: boolean;
|
||||||
primary: boolean;
|
primary: boolean;
|
||||||
digital: boolean;
|
|
||||||
downloadable: boolean;
|
|
||||||
gallery?: {
|
gallery?: {
|
||||||
image?: string | LibraryItemGallery;
|
image?: string | LibraryItemGallery;
|
||||||
id?: string;
|
id?: string;
|
||||||
|
@ -111,6 +127,7 @@ export interface LibraryItem {
|
||||||
image: string | LibraryItemScans;
|
image: string | LibraryItemScans;
|
||||||
id?: string;
|
id?: string;
|
||||||
}[];
|
}[];
|
||||||
|
downloadable: boolean;
|
||||||
id?: string;
|
id?: string;
|
||||||
}[];
|
}[];
|
||||||
textual?: {
|
textual?: {
|
||||||
|
@ -132,7 +149,9 @@ export interface LibraryItem {
|
||||||
categories?: string[] | Key[];
|
categories?: string[] | Key[];
|
||||||
translations?: {
|
translations?: {
|
||||||
language: string | Language;
|
language: string | Language;
|
||||||
description: string;
|
description: {
|
||||||
|
[k: string]: unknown;
|
||||||
|
}[];
|
||||||
id?: string;
|
id?: string;
|
||||||
}[];
|
}[];
|
||||||
size?: {
|
size?: {
|
||||||
|
@ -156,7 +175,9 @@ export interface LibraryItem {
|
||||||
pageEnd?: number;
|
pageEnd?: number;
|
||||||
timeStart?: number;
|
timeStart?: number;
|
||||||
timeEnd?: number;
|
timeEnd?: number;
|
||||||
note?: string;
|
note?: {
|
||||||
|
[k: string]: unknown;
|
||||||
|
}[];
|
||||||
id?: string;
|
id?: string;
|
||||||
}[];
|
}[];
|
||||||
updatedBy: string | Recorder;
|
updatedBy: string | Recorder;
|
||||||
|
@ -292,10 +313,6 @@ export interface Key {
|
||||||
| 'Wordings';
|
| 'Wordings';
|
||||||
translations?: CategoryTranslations;
|
translations?: CategoryTranslations;
|
||||||
}
|
}
|
||||||
export interface Language {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
}
|
|
||||||
export interface File {
|
export interface File {
|
||||||
id: string;
|
id: string;
|
||||||
filename: string;
|
filename: string;
|
||||||
|
@ -318,16 +335,22 @@ export interface Content {
|
||||||
pretitle?: string;
|
pretitle?: string;
|
||||||
title: string;
|
title: string;
|
||||||
subtitle?: string;
|
subtitle?: string;
|
||||||
summary?: string;
|
summary?: {
|
||||||
|
[k: string]: unknown;
|
||||||
|
}[];
|
||||||
textContent?: {
|
textContent?: {
|
||||||
[k: string]: unknown;
|
[k: string]: unknown;
|
||||||
}[];
|
}[];
|
||||||
textTranscribers?: string[] | Recorder[];
|
textTranscribers?: string[] | Recorder[];
|
||||||
textTranslators?: string[] | Recorder[];
|
textTranslators?: string[] | Recorder[];
|
||||||
textProofreaders?: string[] | Recorder[];
|
textProofreaders?: string[] | Recorder[];
|
||||||
textNotes?: string;
|
textNotes?: {
|
||||||
|
[k: string]: unknown;
|
||||||
|
}[];
|
||||||
video?: string | File;
|
video?: string | File;
|
||||||
videoNotes?: string;
|
videoNotes?: {
|
||||||
|
[k: string]: unknown;
|
||||||
|
}[];
|
||||||
audio?: string | File;
|
audio?: string | File;
|
||||||
id?: string;
|
id?: string;
|
||||||
}[];
|
}[];
|
||||||
|
@ -424,7 +447,11 @@ export interface RecordersThumbnail {
|
||||||
export interface ContentsFolder {
|
export interface ContentsFolder {
|
||||||
id: string;
|
id: string;
|
||||||
slug: string;
|
slug: string;
|
||||||
translations?: ContentFoldersTranslation;
|
translations?: {
|
||||||
|
language: string | Language;
|
||||||
|
name: string;
|
||||||
|
id?: string;
|
||||||
|
}[];
|
||||||
subfolders?: string[] | ContentsFolder[];
|
subfolders?: string[] | ContentsFolder[];
|
||||||
contents?: string[] | Content[];
|
contents?: string[] | Content[];
|
||||||
}
|
}
|
||||||
|
@ -454,7 +481,9 @@ export interface Post {
|
||||||
language: string | Language;
|
language: string | Language;
|
||||||
sourceLanguage: string | Language;
|
sourceLanguage: string | Language;
|
||||||
title: string;
|
title: string;
|
||||||
summary?: string;
|
summary?: {
|
||||||
|
[k: string]: unknown;
|
||||||
|
}[];
|
||||||
translators?: string[] | Recorder[];
|
translators?: string[] | Recorder[];
|
||||||
proofreaders?: string[] | Recorder[];
|
proofreaders?: string[] | Recorder[];
|
||||||
content?: {
|
content?: {
|
||||||
|
@ -529,8 +558,12 @@ export interface ChronologyItem {
|
||||||
language: string | Language;
|
language: string | Language;
|
||||||
sourceLanguage: string | Language;
|
sourceLanguage: string | Language;
|
||||||
title?: string;
|
title?: string;
|
||||||
description?: string;
|
description?: {
|
||||||
notes?: string;
|
[k: string]: unknown;
|
||||||
|
}[];
|
||||||
|
notes?: {
|
||||||
|
[k: string]: unknown;
|
||||||
|
}[];
|
||||||
transcribers?: string[] | Recorder[];
|
transcribers?: string[] | Recorder[];
|
||||||
translators?: string[] | Recorder[];
|
translators?: string[] | Recorder[];
|
||||||
proofreaders?: string[] | Recorder[];
|
proofreaders?: string[] | Recorder[];
|
||||||
|
@ -551,7 +584,9 @@ export interface ChronologyEra {
|
||||||
translations?: {
|
translations?: {
|
||||||
language: string | Language;
|
language: string | Language;
|
||||||
title: string;
|
title: string;
|
||||||
description?: string;
|
description?: {
|
||||||
|
[k: string]: unknown;
|
||||||
|
}[];
|
||||||
id?: string;
|
id?: string;
|
||||||
}[];
|
}[];
|
||||||
events?: string[] | ChronologyItem[];
|
events?: string[] | ChronologyItem[];
|
||||||
|
@ -570,11 +605,21 @@ export interface Weapon {
|
||||||
language: string | Language;
|
language: string | Language;
|
||||||
sourceLanguage: string | Language;
|
sourceLanguage: string | Language;
|
||||||
name: string;
|
name: string;
|
||||||
description?: string;
|
description?: {
|
||||||
level1?: string;
|
[k: string]: unknown;
|
||||||
level2?: string;
|
}[];
|
||||||
level3?: string;
|
level1?: {
|
||||||
level4?: string;
|
[k: string]: unknown;
|
||||||
|
}[];
|
||||||
|
level2?: {
|
||||||
|
[k: string]: unknown;
|
||||||
|
}[];
|
||||||
|
level3?: {
|
||||||
|
[k: string]: unknown;
|
||||||
|
}[];
|
||||||
|
level4?: {
|
||||||
|
[k: string]: unknown;
|
||||||
|
}[];
|
||||||
transcribers?: string[] | Recorder[];
|
transcribers?: string[] | Recorder[];
|
||||||
translators?: string[] | Recorder[];
|
translators?: string[] | Recorder[];
|
||||||
proofreaders?: string[] | Recorder[];
|
proofreaders?: string[] | Recorder[];
|
||||||
|
@ -643,6 +688,14 @@ export interface WeaponsGroup {
|
||||||
}[];
|
}[];
|
||||||
weapons?: string[] | Weapon[];
|
weapons?: string[] | Weapon[];
|
||||||
}
|
}
|
||||||
|
export interface Note {
|
||||||
|
id: string;
|
||||||
|
note: {
|
||||||
|
[k: string]: unknown;
|
||||||
|
}[];
|
||||||
|
updatedAt: string;
|
||||||
|
createdAt: string;
|
||||||
|
}
|
||||||
export interface Video {
|
export interface Video {
|
||||||
id: string;
|
id: string;
|
||||||
uid: string;
|
uid: string;
|
||||||
|
@ -690,33 +743,5 @@ export interface PayloadMigration {
|
||||||
|
|
||||||
|
|
||||||
declare module 'payload' {
|
declare module 'payload' {
|
||||||
export interface GeneratedTypes {
|
export interface GeneratedTypes extends Config {}
|
||||||
collections: {
|
|
||||||
'library-items': LibraryItem
|
|
||||||
'contents': Content
|
|
||||||
'contents-folders': ContentsFolder
|
|
||||||
'posts': Post
|
|
||||||
'chronology-items': ChronologyItem
|
|
||||||
'chronology-eras': ChronologyEra
|
|
||||||
'weapons': Weapon
|
|
||||||
'weapons-groups': WeaponsGroup
|
|
||||||
'weapons-thumbnails': WeaponsThumbnail
|
|
||||||
'contents-thumbnails': ContentsThumbnail
|
|
||||||
'library-items-thumbnails': LibraryItemThumbnail
|
|
||||||
'library-items-scans': LibraryItemScans
|
|
||||||
'library-items-gallery': LibraryItemGallery
|
|
||||||
'recorders-thumbnails': RecordersThumbnail
|
|
||||||
'posts-thumbnails': PostThumbnail
|
|
||||||
'files': File
|
|
||||||
'videos': Video
|
|
||||||
'videos-channels': VideosChannel
|
|
||||||
'languages': Language
|
|
||||||
'currencies': Currency
|
|
||||||
'recorders': Recorder
|
|
||||||
'keys': Key
|
|
||||||
'payload-preferences': PayloadPreference
|
|
||||||
'payload-migrations': PayloadMigration
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -2,6 +2,10 @@ export type StrapiLanguage = {
|
||||||
data?: { attributes: { code: string } };
|
data?: { attributes: { code: string } };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type StrapiRecorders = {
|
||||||
|
data?: { attributes: { username: string } }[];
|
||||||
|
};
|
||||||
|
|
||||||
export type StrapiImage = {
|
export type StrapiImage = {
|
||||||
data?: {
|
data?: {
|
||||||
attributes: {
|
attributes: {
|
||||||
|
@ -9,6 +13,8 @@ export type StrapiImage = {
|
||||||
mime: string;
|
mime: string;
|
||||||
name: string;
|
name: string;
|
||||||
size: number;
|
size: number;
|
||||||
|
hash: string;
|
||||||
|
ext: string;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
import {
|
||||||
|
AdapterProps,
|
||||||
|
AlignFeature,
|
||||||
|
BlocksFeature,
|
||||||
|
BoldTextFeature,
|
||||||
|
CheckListFeature,
|
||||||
|
FeatureProvider,
|
||||||
|
// IndentFeature,
|
||||||
|
HeadingFeature,
|
||||||
|
InlineCodeTextFeature,
|
||||||
|
ItalicTextFeature,
|
||||||
|
LinkFeature,
|
||||||
|
// BlockQuoteFeature,
|
||||||
|
OrderedListFeature,
|
||||||
|
ParagraphFeature,
|
||||||
|
RelationshipFeature,
|
||||||
|
StrikethroughTextFeature,
|
||||||
|
SubscriptTextFeature,
|
||||||
|
SuperscriptTextFeature,
|
||||||
|
TreeviewFeature,
|
||||||
|
UnderlineTextFeature,
|
||||||
|
UnoderedListFeature,
|
||||||
|
UploadFeature,
|
||||||
|
lexicalEditor,
|
||||||
|
} from "@payloadcms/richtext-lexical";
|
||||||
|
import { Block, RichTextAdapter } from "payload/types";
|
||||||
|
|
||||||
|
interface EditorOptions {
|
||||||
|
debugs: boolean;
|
||||||
|
blocks: Block[];
|
||||||
|
headings: boolean;
|
||||||
|
lists: boolean;
|
||||||
|
inlines: boolean;
|
||||||
|
images: boolean;
|
||||||
|
relations: boolean;
|
||||||
|
links: boolean;
|
||||||
|
alignment: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const createEditor = ({
|
||||||
|
debugs = false,
|
||||||
|
blocks = [],
|
||||||
|
headings = false,
|
||||||
|
images = false,
|
||||||
|
inlines = false,
|
||||||
|
lists = false,
|
||||||
|
links = false,
|
||||||
|
relations = false,
|
||||||
|
alignment = false,
|
||||||
|
}: Partial<EditorOptions>): RichTextAdapter<any, AdapterProps> => {
|
||||||
|
const enabledFeatures: FeatureProvider[] = [];
|
||||||
|
|
||||||
|
if (lists) enabledFeatures.push(OrderedListFeature(), UnoderedListFeature(), CheckListFeature());
|
||||||
|
if (blocks.length > 0) enabledFeatures.push(BlocksFeature({ blocks }));
|
||||||
|
if (headings) enabledFeatures.push(ParagraphFeature(), HeadingFeature({}));
|
||||||
|
if (debugs) enabledFeatures.push(TreeviewFeature());
|
||||||
|
if (images) enabledFeatures.push(UploadFeature({ collections: [] }));
|
||||||
|
if (links) enabledFeatures.push(LinkFeature({}));
|
||||||
|
if (relations) enabledFeatures.push(RelationshipFeature());
|
||||||
|
if (alignment) enabledFeatures.push(AlignFeature());
|
||||||
|
if (inlines)
|
||||||
|
enabledFeatures.push(
|
||||||
|
BoldTextFeature(),
|
||||||
|
ItalicTextFeature(),
|
||||||
|
UnderlineTextFeature(),
|
||||||
|
StrikethroughTextFeature(),
|
||||||
|
SubscriptTextFeature(),
|
||||||
|
SuperscriptTextFeature(),
|
||||||
|
InlineCodeTextFeature()
|
||||||
|
);
|
||||||
|
|
||||||
|
return lexicalEditor({
|
||||||
|
features: enabledFeatures,
|
||||||
|
});
|
||||||
|
};
|
|
@ -21,6 +21,24 @@ export const findCategory = async (name: string): Promise<string> => {
|
||||||
return key.docs[0]?.id;
|
return key.docs[0]?.id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const findRecorder = async (name: string): Promise<string> => {
|
||||||
|
const recorder = await payload.find({
|
||||||
|
collection: Collections.Recorders,
|
||||||
|
where: { username: { equals: name } },
|
||||||
|
});
|
||||||
|
if (!recorder.docs[0]) throw new Error(`Recorder ${name} wasn't found`);
|
||||||
|
return recorder.docs[0]?.id;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const findContentType = async (name: string): Promise<string> => {
|
||||||
|
const key = await payload.find({
|
||||||
|
collection: Collections.Keys,
|
||||||
|
where: { name: { equals: name }, type: { equals: KeysTypes.Contents } },
|
||||||
|
});
|
||||||
|
if (!key.docs[0]) throw new Error(`Content type ${name} wasn't found`);
|
||||||
|
return key.docs[0]?.id;
|
||||||
|
};
|
||||||
|
|
||||||
type UploadStrapiImage = {
|
type UploadStrapiImage = {
|
||||||
image: StrapiImage;
|
image: StrapiImage;
|
||||||
collection: Collections;
|
collection: Collections;
|
||||||
|
@ -31,6 +49,16 @@ export const uploadStrapiImage = async ({
|
||||||
image,
|
image,
|
||||||
}: UploadStrapiImage): Promise<string | undefined> => {
|
}: UploadStrapiImage): Promise<string | undefined> => {
|
||||||
if (isDefined(image.data)) {
|
if (isDefined(image.data)) {
|
||||||
|
const filename = image.data.attributes.hash + image.data.attributes.ext;
|
||||||
|
|
||||||
|
const existingImage = await payload.find({
|
||||||
|
collection,
|
||||||
|
where: { filename: { equals: filename } },
|
||||||
|
});
|
||||||
|
if (existingImage.docs[0]) {
|
||||||
|
return existingImage.docs[0].id;
|
||||||
|
}
|
||||||
|
|
||||||
const url = `${process.env.STRAPI_URI}${image.data.attributes.url}`;
|
const url = `${process.env.STRAPI_URI}${image.data.attributes.url}`;
|
||||||
|
|
||||||
const blob = await (await fetch(url)).blob();
|
const blob = await (await fetch(url)).blob();
|
||||||
|
@ -41,7 +69,7 @@ export const uploadStrapiImage = async ({
|
||||||
file: {
|
file: {
|
||||||
data: buffer,
|
data: buffer,
|
||||||
mimetype: image.data.attributes.mime,
|
mimetype: image.data.attributes.mime,
|
||||||
name: image.data.attributes.name,
|
name: filename,
|
||||||
size: image.data.attributes.size,
|
size: image.data.attributes.size,
|
||||||
},
|
},
|
||||||
data: {},
|
data: {},
|
||||||
|
|
|
@ -21,3 +21,37 @@ export const formatToCamelCase = (name: string): string =>
|
||||||
.join("");
|
.join("");
|
||||||
|
|
||||||
export const formatToPascalCase = (name: string): string => capitalize(formatToCamelCase(name));
|
export const formatToPascalCase = (name: string): string => capitalize(formatToCamelCase(name));
|
||||||
|
|
||||||
|
export const plainTextToLexical = (
|
||||||
|
text: string
|
||||||
|
): {
|
||||||
|
[k: string]: unknown;
|
||||||
|
}[] => ({
|
||||||
|
root: {
|
||||||
|
type: "root",
|
||||||
|
format: "",
|
||||||
|
indent: 0,
|
||||||
|
version: 1,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
detail: 0,
|
||||||
|
format: 0,
|
||||||
|
mode: "normal",
|
||||||
|
style: "",
|
||||||
|
text,
|
||||||
|
type: "text",
|
||||||
|
version: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
direction: "ltr",
|
||||||
|
format: "",
|
||||||
|
indent: 0,
|
||||||
|
type: "paragraph",
|
||||||
|
version: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
direction: "ltr",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in New Issue