Added folders
This commit is contained in:
parent
cbd0251ad5
commit
e8d8c8e6a8
|
@ -3,7 +3,7 @@
|
|||
"editor.rulers": [100],
|
||||
"typescript.preferences.importModuleSpecifier": "non-relative",
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll": true,
|
||||
"source.organizeImports": true
|
||||
"source.fixAll": "explicit",
|
||||
"source.organizeImports": "explicit"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ version: "3"
|
|||
|
||||
services:
|
||||
payload:
|
||||
image: node:18-alpine
|
||||
image: docker.io/library/node:18-alpine
|
||||
ports:
|
||||
- "${PAYLOAD_PORT}:${PAYLOAD_PORT}"
|
||||
volumes:
|
||||
|
@ -20,7 +20,7 @@ services:
|
|||
NODE_ENV: development
|
||||
|
||||
mongo:
|
||||
image: mongo:latest
|
||||
image: docker.io/library/mongo:latest
|
||||
ports:
|
||||
- "${MONGODB_PORT}:27017"
|
||||
command:
|
||||
|
|
File diff suppressed because it is too large
Load Diff
21
package.json
21
package.json
|
@ -24,23 +24,24 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@fontsource/vollkorn": "^5.0.17",
|
||||
"@payloadcms/bundler-webpack": "^1.0.4",
|
||||
"@payloadcms/db-mongodb": "^1.0.4",
|
||||
"@payloadcms/richtext-lexical": "^0.1.15",
|
||||
"@payloadcms/bundler-webpack": "^1.0.5",
|
||||
"@payloadcms/db-mongodb": "^1.0.8",
|
||||
"@payloadcms/richtext-lexical": "^0.1.17",
|
||||
"cross-env": "^7.0.3",
|
||||
"language-tags": "^1.0.9",
|
||||
"luxon": "^3.4.3",
|
||||
"payload": "^2.0.13",
|
||||
"styled-components": "^6.1.0"
|
||||
"payload": "^2.1.1",
|
||||
"sharp": "^0.33.2",
|
||||
"styled-components": "^6.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/dotenv": "^8.2.0",
|
||||
"@types/express": "^4.17.20",
|
||||
"@types/language-tags": "^1.0.3",
|
||||
"@types/luxon": "^3.3.3",
|
||||
"@types/qs": "^6.9.9",
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/language-tags": "^1.0.4",
|
||||
"@types/luxon": "^3.3.4",
|
||||
"@types/qs": "^6.9.10",
|
||||
"@types/react-router-dom": "^5.3.3",
|
||||
"@types/styled-components": "^5.1.29",
|
||||
"@types/styled-components": "^5.1.30",
|
||||
"copyfiles": "^2.4.1",
|
||||
"nodemon": "^3.0.1",
|
||||
"npm-check-updates": "^16.14.6",
|
||||
|
|
|
@ -18,7 +18,6 @@ import { validateEventsTranslationsTitle } from "./validations/validateEventsTra
|
|||
const fields = {
|
||||
name: "name",
|
||||
events: "events",
|
||||
eventsSource: "source",
|
||||
eventsTranslations: "translations",
|
||||
eventsTranslationsTitle: "title",
|
||||
eventsTranslationsDescription: "description",
|
||||
|
@ -98,13 +97,6 @@ export const ChronologyItems: CollectionConfig = buildVersionedCollectionConfig(
|
|||
required: true,
|
||||
minRows: 1,
|
||||
fields: [
|
||||
{
|
||||
name: fields.eventsSource,
|
||||
type: "relationship",
|
||||
relationTo: [Collections.Contents, Collections.LibraryItems],
|
||||
// required: true,
|
||||
admin: { allowCreate: false },
|
||||
},
|
||||
translatedFields({
|
||||
name: fields.eventsTranslations,
|
||||
required: true,
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
import { CollectionGroups, Collections } from "../../constants";
|
||||
import { rowField } from "../../fields/rowField/rowField";
|
||||
import { slugField } from "../../fields/slugField/slugField";
|
||||
import { translatedFields } from "../../fields/translatedFields/translatedFields";
|
||||
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
||||
|
||||
const fields = {
|
||||
slug: "slug",
|
||||
translations: "translations",
|
||||
translationsName: "name",
|
||||
sections: "sections",
|
||||
sectionsSubfolders: "subfolders",
|
||||
sectionsName: "name",
|
||||
files: "files",
|
||||
} as const satisfies Record<string, string>;
|
||||
|
||||
export const Folders = buildCollectionConfig({
|
||||
slug: Collections.Folders,
|
||||
labels: { singular: "Folder", plural: "Folders" },
|
||||
admin: {
|
||||
useAsTitle: fields.slug,
|
||||
group: CollectionGroups.Collections,
|
||||
},
|
||||
fields: [
|
||||
slugField({ name: fields.slug }),
|
||||
translatedFields({
|
||||
name: fields.translations,
|
||||
fields: [
|
||||
{
|
||||
name: fields.translationsName,
|
||||
type: "text",
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
}),
|
||||
{
|
||||
name: "sections",
|
||||
type: "array",
|
||||
fields: [
|
||||
rowField([
|
||||
{
|
||||
name: fields.sectionsName,
|
||||
type: "text",
|
||||
admin: {
|
||||
condition: (data) => data[fields.sections]?.length > 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: fields.sectionsSubfolders,
|
||||
type: "relationship",
|
||||
relationTo: Collections.Folders,
|
||||
hasMany: true,
|
||||
},
|
||||
]),
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "relationship",
|
||||
name: fields.files,
|
||||
relationTo: [Collections.LibraryItems, Collections.Contents],
|
||||
hasMany: true,
|
||||
},
|
||||
],
|
||||
});
|
|
@ -1,71 +0,0 @@
|
|||
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";
|
||||
|
||||
const fields = {
|
||||
slug: "slug",
|
||||
translations: "translations",
|
||||
name: "name",
|
||||
description: "description",
|
||||
subfolders: "subfolders",
|
||||
items: "items",
|
||||
parentFolders: "parentFolders",
|
||||
} 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 }),
|
||||
},
|
||||
],
|
||||
}),
|
||||
rowField([
|
||||
backPropagationField({
|
||||
name: fields.parentFolders,
|
||||
relationTo: Collections.LibraryFolders,
|
||||
hasMany: true,
|
||||
where: ({ id }) => ({ [fields.subfolders]: { equals: id } }),
|
||||
}),
|
||||
{
|
||||
type: "relationship",
|
||||
name: fields.subfolders,
|
||||
relationTo: Collections.LibraryFolders,
|
||||
hasMany: true,
|
||||
},
|
||||
{
|
||||
type: "relationship",
|
||||
name: fields.items,
|
||||
relationTo: Collections.LibraryItems,
|
||||
hasMany: true,
|
||||
},
|
||||
]),
|
||||
],
|
||||
});
|
|
@ -704,15 +704,16 @@ export const LibraryItems = buildVersionedCollectionConfig({
|
|||
label: "Contents",
|
||||
fields: [
|
||||
rowField([
|
||||
backPropagationField({
|
||||
name: fields.parentFolders,
|
||||
relationTo: Collections.LibraryFolders,
|
||||
hasMany: true,
|
||||
where: ({ id }) => ({ items: { equals: id } }),
|
||||
admin: {
|
||||
description: `You can set the folders from the "Library Folders" collection`,
|
||||
},
|
||||
}),
|
||||
// TODO: Uncomment when the Folders are ready
|
||||
// backPropagationField({
|
||||
// name: fields.parentFolders,
|
||||
// relationTo: Collections.Folders,
|
||||
// hasMany: true,
|
||||
// where: ({ id }) => ({ files: { equals: id } }),
|
||||
// admin: {
|
||||
// description: `You can set the folders from the "Folders" collection`,
|
||||
// },
|
||||
// }),
|
||||
backPropagationField({
|
||||
name: fields.parentItems,
|
||||
relationTo: Collections.LibraryItems,
|
||||
|
|
|
@ -12,6 +12,7 @@ import { beforeDuplicateUnpublish } from "../../hooks/beforeDuplicateUnpublish";
|
|||
import { isDefined, isUndefined } from "../../utils/asserts";
|
||||
import { createEditor } from "../../utils/editor";
|
||||
import { buildVersionedCollectionConfig } from "../../utils/versionedCollectionConfig";
|
||||
import { importFromStrapi } from "./endpoints/importFromStrapi";
|
||||
|
||||
const fields = {
|
||||
slug: "slug",
|
||||
|
@ -60,6 +61,7 @@ export const Posts = buildVersionedCollectionConfig({
|
|||
},
|
||||
preview: (doc) => `https://accords-library.com/news/${doc.slug}`,
|
||||
},
|
||||
endpoints: [importFromStrapi],
|
||||
fields: [
|
||||
rowField([
|
||||
slugField({ name: fields.slug }),
|
||||
|
@ -72,7 +74,7 @@ export const Posts = buildVersionedCollectionConfig({
|
|||
{
|
||||
name: fields.authors,
|
||||
type: "relationship",
|
||||
relationTo: [Collections.Recorders],
|
||||
relationTo: Collections.Recorders,
|
||||
required: true,
|
||||
minRows: 1,
|
||||
hasMany: true,
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
import { DateTime } from "luxon";
|
||||
import type { MarkOptional } from "ts-essentials";
|
||||
import { Collections } from "../../../constants";
|
||||
import { createStrapiImportEndpoint } from "../../../endpoints/createStrapiImportEndpoint";
|
||||
import type { Post } from "../../../types/collections";
|
||||
import { StrapiImage, StrapiLanguage, StrapiRecorders } from "../../../types/strapi";
|
||||
import { isDefined, isUndefined } from "../../../utils/asserts";
|
||||
import { findCategory, findRecorder, uploadStrapiImage } from "../../../utils/localApi";
|
||||
import { plainTextToLexical } from "../../../utils/string";
|
||||
|
||||
type StrapiPost = {
|
||||
slug: string;
|
||||
categories: { data: { attributes: { slug: string } }[] };
|
||||
authors: StrapiRecorders;
|
||||
hidden: boolean;
|
||||
thumbnail: StrapiImage;
|
||||
translations: {
|
||||
title: string;
|
||||
excerpt?: string;
|
||||
body: string;
|
||||
translators: StrapiRecorders;
|
||||
proofreaders: StrapiRecorders;
|
||||
language: StrapiLanguage;
|
||||
source_language: StrapiLanguage;
|
||||
}[];
|
||||
date: {
|
||||
day: number;
|
||||
month: number;
|
||||
year: number;
|
||||
};
|
||||
};
|
||||
|
||||
export const importFromStrapi = createStrapiImportEndpoint<StrapiPost>({
|
||||
strapi: {
|
||||
collection: "posts",
|
||||
params: {
|
||||
populate: [
|
||||
"date",
|
||||
"authors",
|
||||
"thumbnail",
|
||||
"categories",
|
||||
"translations",
|
||||
"translations.language",
|
||||
"translations.translators",
|
||||
"translations.proofreaders",
|
||||
"translations.source_language",
|
||||
],
|
||||
},
|
||||
},
|
||||
payload: {
|
||||
collection: Collections.Posts,
|
||||
convert: async ({
|
||||
slug,
|
||||
date: { day, month, year },
|
||||
hidden,
|
||||
authors,
|
||||
thumbnail,
|
||||
categories,
|
||||
translations,
|
||||
}) => {
|
||||
const thumbnailId = await uploadStrapiImage({
|
||||
collection: Collections.PostsThumbnails,
|
||||
image: thumbnail,
|
||||
});
|
||||
|
||||
const handleTranslation = async ({
|
||||
language,
|
||||
title,
|
||||
body,
|
||||
excerpt,
|
||||
proofreaders,
|
||||
source_language,
|
||||
translators,
|
||||
}: StrapiPost["translations"][number]): Promise<Post["translations"][number]> => {
|
||||
if (isUndefined(language.data))
|
||||
throw new Error("A language is required for a post translation");
|
||||
if (isUndefined(source_language.data))
|
||||
throw new Error("A source_language is required for a post translation");
|
||||
return {
|
||||
language: language.data.attributes.code,
|
||||
sourceLanguage: source_language.data.attributes.code,
|
||||
title,
|
||||
content: plainTextToLexical(body),
|
||||
summary: isDefined(excerpt) ? plainTextToLexical(excerpt) : undefined,
|
||||
translators:
|
||||
translators.data &&
|
||||
(await Promise.all(
|
||||
translators.data?.map(async (recorder) => findRecorder(recorder.attributes.username))
|
||||
)),
|
||||
proofreaders:
|
||||
proofreaders.data &&
|
||||
(await Promise.all(
|
||||
proofreaders.data?.map(async (recorder) => findRecorder(recorder.attributes.username))
|
||||
)),
|
||||
};
|
||||
};
|
||||
|
||||
const data: MarkOptional<Post, "createdAt" | "id" | "updatedAt" | "updatedBy"> = {
|
||||
slug,
|
||||
publishedDate:
|
||||
DateTime.fromObject({ day, month, year }).toISO() ?? new Date().toISOString(),
|
||||
categories: await Promise.all(
|
||||
categories.data.map((category) => findCategory(category.attributes.slug))
|
||||
),
|
||||
translations: await Promise.all(translations.map(handleTranslation)),
|
||||
authors: await Promise.all(
|
||||
authors.data?.map((author) => findRecorder(author.attributes.username)) ?? []
|
||||
),
|
||||
thumbnail: thumbnailId,
|
||||
hidden,
|
||||
};
|
||||
return data;
|
||||
},
|
||||
},
|
||||
});
|
|
@ -65,7 +65,7 @@ export const Recorders = buildCollectionConfig({
|
|||
],
|
||||
},
|
||||
},
|
||||
auth: true,
|
||||
auth: { tokenExpiration: 24 * 60 * 60 },
|
||||
access: {
|
||||
unlock: mustBeAdminForCollections,
|
||||
update: mustBeAdminOrSelf,
|
||||
|
|
|
@ -8,7 +8,6 @@ export enum Collections {
|
|||
Files = "files",
|
||||
Keys = "keys",
|
||||
Languages = "languages",
|
||||
LibraryFolders = "library-folders",
|
||||
LibraryItems = "library-items",
|
||||
LibraryItemsThumbnails = "library-items-thumbnails",
|
||||
LibraryItemsScans = "library-items-scans",
|
||||
|
@ -23,6 +22,7 @@ export enum Collections {
|
|||
Weapons = "weapons",
|
||||
WeaponsGroups = "weapons-groups",
|
||||
WeaponsThumbnails = "weapons-thumbnails",
|
||||
Folders = "folders"
|
||||
}
|
||||
|
||||
export enum CollectionGroups {
|
||||
|
|
|
@ -9,9 +9,9 @@ import { ContentsFolders } from "./collections/ContentsFolders/ContentsFolders";
|
|||
import { ContentsThumbnails } from "./collections/ContentsThumbnails/ContentsThumbnails";
|
||||
import { Currencies } from "./collections/Currencies/Currencies";
|
||||
import { Files } from "./collections/Files/Files";
|
||||
import { Folders } from "./collections/Folders/Folders";
|
||||
import { Keys } from "./collections/Keys/Keys";
|
||||
import { Languages } from "./collections/Languages/Languages";
|
||||
import { LibraryFolders } from "./collections/LibraryFolders/LibraryFolders";
|
||||
import { LibraryItems } from "./collections/LibraryItems/LibraryItems";
|
||||
import { LibraryItemsGallery } from "./collections/LibraryItemsGallery/LibraryItemsGallery";
|
||||
import { LibraryItemsScans } from "./collections/LibraryItemsScans/LibraryItemsScans";
|
||||
|
@ -46,7 +46,7 @@ export default buildConfig({
|
|||
},
|
||||
editor: createEditor({}),
|
||||
collections: [
|
||||
LibraryFolders,
|
||||
Folders,
|
||||
LibraryItems,
|
||||
Contents,
|
||||
ContentsFolders,
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -26,7 +26,7 @@ export const buildVersionedCollectionConfig = ({
|
|||
}: BuildVersionedCollectionConfig): CollectionConfig => ({
|
||||
...otherParams,
|
||||
timestamps: true,
|
||||
versions: { drafts: { autosave: { interval: 2000 } } },
|
||||
versions: { drafts: { autosave: false } },
|
||||
hooks: {
|
||||
...otherHooks,
|
||||
beforeChange: [...(beforeChange ?? []), beforeChangeUpdatedBy],
|
||||
|
|
Loading…
Reference in New Issue