Streamlined collection config
This commit is contained in:
parent
0a45ebb134
commit
65286f0c66
|
@ -1,9 +1,8 @@
|
|||
import { CollectionConfig } from "payload/types";
|
||||
import { slugField } from "../../fields/slugField/slugField";
|
||||
import { CollectionGroup, KeysTypes } from "../../constants";
|
||||
import { CollectionGroup } from "../../constants";
|
||||
import { localizedFields } from "../../fields/translatedFields/translatedFields";
|
||||
import { collectionSlug } from "../../utils/string";
|
||||
import { Contents } from "../Contents/Contents";
|
||||
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
||||
|
||||
const fields = {
|
||||
slug: "slug",
|
||||
|
@ -13,17 +12,12 @@ const fields = {
|
|||
contents: "contents",
|
||||
} as const satisfies Record<string, string>;
|
||||
|
||||
const labels = {
|
||||
export const ContentFolders = buildCollectionConfig(
|
||||
{
|
||||
singular: "Content Folder",
|
||||
plural: "Content Folders",
|
||||
} as const satisfies { singular: string; plural: string };
|
||||
|
||||
const slug = collectionSlug(labels.plural);
|
||||
|
||||
export const ContentFolders: CollectionConfig = {
|
||||
slug,
|
||||
labels,
|
||||
typescript: { interface: labels.singular },
|
||||
},
|
||||
({ slug }) => ({
|
||||
defaultSort: fields.slug,
|
||||
admin: {
|
||||
useAsTitle: fields.slug,
|
||||
|
@ -62,4 +56,5 @@ export const ContentFolders: CollectionConfig = {
|
|||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
})
|
||||
);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { CollectionConfig } from "payload/types";
|
||||
import { CollectionGroup } from "../../constants";
|
||||
import { collectionSlug } from "../../utils/string";
|
||||
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
||||
|
||||
const fields = {
|
||||
filename: "filename",
|
||||
|
@ -8,21 +7,17 @@ const fields = {
|
|||
filesize: "filesize",
|
||||
} as const satisfies Record<string, string>;
|
||||
|
||||
const labels = {
|
||||
export const ContentThumbnails = buildCollectionConfig(
|
||||
{
|
||||
singular: "Content Thumbnail",
|
||||
plural: "Content Thumbnails",
|
||||
} as const satisfies { singular: string; plural: string };
|
||||
|
||||
export const ContentThumbnails: CollectionConfig = {
|
||||
slug: collectionSlug(labels.plural),
|
||||
labels,
|
||||
typescript: { interface: labels.singular },
|
||||
},
|
||||
({ labels }) => ({
|
||||
defaultSort: fields.filename,
|
||||
admin: {
|
||||
useAsTitle: fields.filename,
|
||||
group: CollectionGroup.Media,
|
||||
},
|
||||
|
||||
upload: {
|
||||
staticDir: `../uploads/${labels.plural}`,
|
||||
mimeTypes: ["image/*"],
|
||||
|
@ -47,6 +42,6 @@ export const ContentThumbnails: CollectionConfig = {
|
|||
},
|
||||
],
|
||||
},
|
||||
|
||||
fields: [],
|
||||
};
|
||||
})
|
||||
);
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import { CollectionConfig } from "payload/types";
|
||||
import { collectionSlug } from "../../utils/string";
|
||||
import { CollectionGroup, FileTypes, KeysTypes } from "../../constants";
|
||||
import { slugField } from "../../fields/slugField/slugField";
|
||||
import { imageField } from "../../fields/imageField/imageField";
|
||||
|
@ -10,6 +8,7 @@ import { isDefined } from "../../utils/asserts";
|
|||
import { fileField } from "../../fields/fileField/fileField";
|
||||
import { contentBlocks } from "./Blocks/blocks";
|
||||
import { ContentThumbnails } from "../ContentThumbnails/ContentThumbnails";
|
||||
import { buildVersionedCollectionConfig } from "../../utils/versionedCollectionConfig";
|
||||
|
||||
const fields = {
|
||||
slug: "slug",
|
||||
|
@ -31,20 +30,20 @@ const fields = {
|
|||
audio: "audio",
|
||||
audioNotes: "videoNotes",
|
||||
status: "status",
|
||||
updatedBy: "updatedBy",
|
||||
} as const satisfies Record<string, string>;
|
||||
|
||||
const labels = {
|
||||
export const Contents = buildVersionedCollectionConfig(
|
||||
{
|
||||
singular: "Content",
|
||||
plural: "Contents",
|
||||
} as const satisfies { singular: string; plural: string };
|
||||
|
||||
export const Contents: CollectionConfig = {
|
||||
slug: collectionSlug(labels.plural),
|
||||
labels,
|
||||
typescript: { interface: labels.singular },
|
||||
},
|
||||
() => ({
|
||||
defaultSort: fields.slug,
|
||||
admin: {
|
||||
useAsTitle: fields.slug,
|
||||
description:
|
||||
"All the contents (textual, audio, and video) from the Library or other online sources.",
|
||||
defaultColumns: [
|
||||
fields.slug,
|
||||
fields.thumbnail,
|
||||
|
@ -56,8 +55,6 @@ export const Contents: CollectionConfig = {
|
|||
group: CollectionGroup.Collections,
|
||||
preview: (doc) => `https://accords-library.com/contents/${doc.slug}`,
|
||||
},
|
||||
timestamps: true,
|
||||
versions: { drafts: { autosave: true } },
|
||||
fields: [
|
||||
{
|
||||
type: "row",
|
||||
|
@ -214,4 +211,5 @@ export const Contents: CollectionConfig = {
|
|||
],
|
||||
}),
|
||||
],
|
||||
};
|
||||
})
|
||||
);
|
||||
|
|
|
@ -1,27 +1,22 @@
|
|||
import { CollectionConfig } from "payload/types";
|
||||
import { CollectionGroup, FileTypes } from "../../constants";
|
||||
import { collectionSlug } from "../../utils/string";
|
||||
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
||||
|
||||
const fields = {
|
||||
filename: "filename",
|
||||
type: "type",
|
||||
} as const satisfies Record<string, string>;
|
||||
|
||||
const labels = {
|
||||
export const Files = buildCollectionConfig(
|
||||
{
|
||||
singular: "File",
|
||||
plural: "Files",
|
||||
} as const satisfies { singular: string; plural: string };
|
||||
|
||||
export const Files: CollectionConfig = {
|
||||
slug: collectionSlug(labels.plural),
|
||||
labels,
|
||||
typescript: { interface: labels.singular },
|
||||
},
|
||||
() => ({
|
||||
defaultSort: fields.filename,
|
||||
admin: {
|
||||
useAsTitle: fields.filename,
|
||||
group: CollectionGroup.Media,
|
||||
},
|
||||
|
||||
fields: [
|
||||
{
|
||||
name: fields.filename,
|
||||
|
@ -35,4 +30,5 @@ export const Files: CollectionConfig = {
|
|||
options: Object.entries(FileTypes).map(([value, label]) => ({ label, value })),
|
||||
},
|
||||
],
|
||||
};
|
||||
})
|
||||
);
|
||||
|
|
|
@ -2,9 +2,9 @@ import { CollectionConfig } from "payload/types";
|
|||
import { slugField } from "../../fields/slugField/slugField";
|
||||
import { CollectionGroup, KeysTypes } from "../../constants";
|
||||
import { localizedFields } from "../../fields/translatedFields/translatedFields";
|
||||
import { collectionSlug } from "../../utils/string";
|
||||
import { Key } from "../../types/collections";
|
||||
import { isDefined } from "../../utils/asserts";
|
||||
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
||||
|
||||
const fields = {
|
||||
slug: "slug",
|
||||
|
@ -14,17 +14,14 @@ const fields = {
|
|||
short: "short",
|
||||
} as const satisfies Record<string, string>;
|
||||
|
||||
const labels = {
|
||||
singular: "Key",
|
||||
plural: "Keys",
|
||||
} as const satisfies { singular: string; plural: string };
|
||||
|
||||
const keysTypesWithShort: (keyof typeof KeysTypes)[] = ["Categories", "GamePlatforms"];
|
||||
|
||||
export const Keys: CollectionConfig = {
|
||||
slug: collectionSlug(labels.plural),
|
||||
labels,
|
||||
typescript: { interface: labels.singular },
|
||||
export const Keys: CollectionConfig = buildCollectionConfig(
|
||||
{
|
||||
singular: "Key",
|
||||
plural: "Keys",
|
||||
},
|
||||
() => ({
|
||||
defaultSort: fields.slug,
|
||||
admin: {
|
||||
useAsTitle: fields.slug,
|
||||
|
@ -66,4 +63,5 @@ export const Keys: CollectionConfig = {
|
|||
],
|
||||
}),
|
||||
],
|
||||
};
|
||||
})
|
||||
);
|
||||
|
|
|
@ -1,21 +1,17 @@
|
|||
import { CollectionConfig } from "payload/types";
|
||||
import { CollectionGroup } from "../constants";
|
||||
import { collectionSlug } from "../utils/string";
|
||||
import { buildCollectionConfig } from "../utils/collectionConfig";
|
||||
|
||||
const fields = {
|
||||
id: "id",
|
||||
name: "name",
|
||||
} as const satisfies Record<string, string>;
|
||||
|
||||
const labels = {
|
||||
export const Languages = buildCollectionConfig(
|
||||
{
|
||||
singular: "Language",
|
||||
plural: "Languages",
|
||||
} as const satisfies { singular: string; plural: string };
|
||||
|
||||
export const Languages: CollectionConfig = {
|
||||
slug: collectionSlug(labels.plural),
|
||||
labels,
|
||||
typescript: { interface: labels.singular },
|
||||
},
|
||||
() => ({
|
||||
defaultSort: fields.name,
|
||||
admin: {
|
||||
useAsTitle: fields.name,
|
||||
|
@ -43,4 +39,5 @@ export const Languages: CollectionConfig = {
|
|||
required: true,
|
||||
},
|
||||
],
|
||||
};
|
||||
})
|
||||
);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { CollectionConfig } from "payload/types";
|
||||
import { CollectionGroup } from "../../constants";
|
||||
import { collectionSlug } from "../../utils/string";
|
||||
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
||||
|
||||
const fields = {
|
||||
filename: "filename",
|
||||
|
@ -8,21 +7,17 @@ const fields = {
|
|||
filesize: "filesize",
|
||||
} as const satisfies Record<string, string>;
|
||||
|
||||
const labels = {
|
||||
export const LibraryItemThumbnails = buildCollectionConfig(
|
||||
{
|
||||
singular: "Library Item Thumbnail",
|
||||
plural: "Library Item Thumbnails",
|
||||
} as const satisfies { singular: string; plural: string };
|
||||
|
||||
export const LibraryItemThumbnails: CollectionConfig = {
|
||||
slug: collectionSlug(labels.plural),
|
||||
labels,
|
||||
typescript: { interface: labels.singular },
|
||||
},
|
||||
({ labels }) => ({
|
||||
defaultSort: fields.filename,
|
||||
admin: {
|
||||
useAsTitle: fields.filename,
|
||||
group: CollectionGroup.Media,
|
||||
},
|
||||
|
||||
upload: {
|
||||
staticDir: `../uploads/${labels.plural}`,
|
||||
mimeTypes: ["image/*"],
|
||||
|
@ -59,6 +54,6 @@ export const LibraryItemThumbnails: CollectionConfig = {
|
|||
},
|
||||
],
|
||||
},
|
||||
|
||||
fields: [],
|
||||
};
|
||||
})
|
||||
);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { CollectionConfig } from "payload/types";
|
||||
import {
|
||||
CollectionGroup,
|
||||
KeysTypes,
|
||||
|
@ -8,12 +7,12 @@ import {
|
|||
} from "../../constants";
|
||||
import { slugField } from "../../fields/slugField/slugField";
|
||||
import { imageField } from "../../fields/imageField/imageField";
|
||||
import { collectionSlug } from "../../utils/string";
|
||||
import { isDefined, isUndefined } from "../../utils/asserts";
|
||||
import { LibraryItemThumbnails } from "../LibraryItemThumbnails/LibraryItemThumbnails";
|
||||
import { LibraryItem } from "../../types/collections";
|
||||
import { Keys } from "../Keys/Keys";
|
||||
import { Languages } from "../Languages";
|
||||
import { buildVersionedCollectionConfig } from "../../utils/versionedCollectionConfig";
|
||||
|
||||
const fields = {
|
||||
status: "status",
|
||||
|
@ -42,11 +41,6 @@ const fields = {
|
|||
audioSubtype: "audioSubtype",
|
||||
} as const satisfies Record<string, string>;
|
||||
|
||||
const labels = {
|
||||
singular: "Library Item",
|
||||
plural: "Library Items",
|
||||
} as const satisfies { singular: string; plural: string };
|
||||
|
||||
const validateSizeValue = (value?: number) => {
|
||||
if (isDefined(value) && value <= 0) return "This value must be greater than 0";
|
||||
return true;
|
||||
|
@ -58,19 +52,22 @@ const validateRequiredSizeValue = (value?: number) => {
|
|||
return true;
|
||||
};
|
||||
|
||||
export const LibraryItems: CollectionConfig = {
|
||||
slug: collectionSlug(labels.plural),
|
||||
labels,
|
||||
typescript: { interface: labels.singular },
|
||||
export const LibraryItems = buildVersionedCollectionConfig(
|
||||
{
|
||||
singular: "Library Item",
|
||||
plural: "Library Items",
|
||||
},
|
||||
() => ({
|
||||
defaultSort: fields.slug,
|
||||
admin: {
|
||||
useAsTitle: fields.slug,
|
||||
description:
|
||||
"A comprehensive list of all Yokoverse’s side materials (books, novellas, artbooks, \
|
||||
stage plays, manga, drama CDs, and comics).",
|
||||
defaultColumns: [fields.slug, fields.thumbnail, fields.status],
|
||||
group: CollectionGroup.Collections,
|
||||
preview: (doc) => `https://accords-library.com/library/${doc.slug}`,
|
||||
},
|
||||
timestamps: true,
|
||||
versions: { drafts: { autosave: true } },
|
||||
fields: [
|
||||
{
|
||||
type: "row",
|
||||
|
@ -270,4 +267,5 @@ export const LibraryItems: CollectionConfig = {
|
|||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
})
|
||||
);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { CollectionConfig } from "payload/types";
|
||||
import { CollectionGroup } from "../../constants";
|
||||
import { collectionSlug } from "../../utils/string";
|
||||
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
||||
|
||||
const fields = {
|
||||
filename: "filename",
|
||||
|
@ -8,21 +7,17 @@ const fields = {
|
|||
filesize: "filesize",
|
||||
} as const satisfies Record<string, string>;
|
||||
|
||||
const labels = {
|
||||
export const PostThumbnails = buildCollectionConfig(
|
||||
{
|
||||
singular: "Post Thumbnail",
|
||||
plural: "Post Thumbnails",
|
||||
} as const satisfies { singular: string; plural: string };
|
||||
|
||||
export const PostThumbnails: CollectionConfig = {
|
||||
slug: collectionSlug(labels.plural),
|
||||
labels,
|
||||
typescript: { interface: labels.singular },
|
||||
},
|
||||
({ labels }) => ({
|
||||
defaultSort: fields.filename,
|
||||
admin: {
|
||||
useAsTitle: fields.filename,
|
||||
group: CollectionGroup.Media,
|
||||
},
|
||||
|
||||
upload: {
|
||||
staticDir: `../uploads/${labels.plural}`,
|
||||
mimeTypes: ["image/*"],
|
||||
|
@ -47,6 +42,6 @@ export const PostThumbnails: CollectionConfig = {
|
|||
},
|
||||
],
|
||||
},
|
||||
|
||||
fields: [],
|
||||
};
|
||||
})
|
||||
);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { CollectionConfig } from "payload/types";
|
||||
import { slugField } from "../../fields/slugField/slugField";
|
||||
import { imageField } from "../../fields/imageField/imageField";
|
||||
import { CollectionGroup, KeysTypes } from "../../constants";
|
||||
|
@ -7,8 +6,8 @@ import { localizedFields } from "../../fields/translatedFields/translatedFields"
|
|||
import { isDefined, isUndefined } from "../../utils/asserts";
|
||||
import { removeTranslatorsForTranscripts } from "./hooks/beforeValidate";
|
||||
import { Keys } from "../Keys/Keys";
|
||||
import { collectionSlug } from "../../utils/string";
|
||||
import { PostThumbnails } from "../PostThumbnails/PostThumbnails";
|
||||
import { buildVersionedCollectionConfig } from "../../utils/versionedCollectionConfig";
|
||||
|
||||
const fields = {
|
||||
slug: "slug",
|
||||
|
@ -26,18 +25,18 @@ const fields = {
|
|||
proofreaders: "proofreaders",
|
||||
} as const satisfies Record<string, string>;
|
||||
|
||||
const labels = {
|
||||
export const Posts = buildVersionedCollectionConfig(
|
||||
{
|
||||
singular: "Post",
|
||||
plural: "Posts",
|
||||
} as const satisfies { singular: string; plural: string };
|
||||
|
||||
export const Posts: CollectionConfig = {
|
||||
slug: collectionSlug(labels.plural),
|
||||
labels,
|
||||
typescript: { interface: labels.singular },
|
||||
},
|
||||
() => ({
|
||||
defaultSort: fields.slug,
|
||||
admin: {
|
||||
useAsTitle: fields.slug,
|
||||
description:
|
||||
"News articles written by our Recorders! Here you will find announcements about \
|
||||
new merch/items releases, guides, theories, unboxings, showcases...",
|
||||
defaultColumns: [fields.slug, fields.thumbnail, fields.categories],
|
||||
group: CollectionGroup.Collections,
|
||||
preview: (doc) => `https://accords-library.com/news/${doc.slug}`,
|
||||
|
@ -45,8 +44,6 @@ export const Posts: CollectionConfig = {
|
|||
hooks: {
|
||||
beforeValidate: [removeTranslatorsForTranscripts],
|
||||
},
|
||||
timestamps: true,
|
||||
versions: { drafts: { autosave: true } },
|
||||
fields: [
|
||||
{
|
||||
type: "row",
|
||||
|
@ -110,7 +107,10 @@ export const Posts: CollectionConfig = {
|
|||
width: "50%",
|
||||
},
|
||||
validate: (translators, { siblingData }) => {
|
||||
if (isUndefined(siblingData.language) || isUndefined(siblingData.sourceLanguage)) {
|
||||
if (
|
||||
isUndefined(siblingData.language) ||
|
||||
isUndefined(siblingData.sourceLanguage)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
if (siblingData.language === siblingData.sourceLanguage) {
|
||||
|
@ -155,4 +155,5 @@ export const Posts: CollectionConfig = {
|
|||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
})
|
||||
);
|
||||
|
|
|
@ -5,7 +5,7 @@ export const removeTranslatorsForTranscripts: CollectionBeforeValidateHook<Post>
|
|||
data: { translations, ...data },
|
||||
}) => ({
|
||||
...data,
|
||||
translations: translations.map(({ translators, ...translation }) => {
|
||||
translations: translations?.map(({ translators, ...translation }) => {
|
||||
if (translation.language === translation.sourceLanguage) {
|
||||
return { ...translation, translators: [] };
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { CollectionConfig } from "payload/types";
|
||||
import { CollectionGroup } from "../../constants";
|
||||
import { collectionSlug } from "../../utils/string";
|
||||
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
||||
|
||||
const fields = {
|
||||
filename: "filename",
|
||||
|
@ -8,21 +7,17 @@ const fields = {
|
|||
filesize: "filesize",
|
||||
} as const satisfies Record<string, string>;
|
||||
|
||||
const labels = {
|
||||
export const RecorderThumbnails = buildCollectionConfig(
|
||||
{
|
||||
singular: "Recorder Thumbnail",
|
||||
plural: "Recorder Thumbnails",
|
||||
} as const satisfies { singular: string; plural: string };
|
||||
|
||||
export const RecorderThumbnails: CollectionConfig = {
|
||||
slug: collectionSlug(labels.plural),
|
||||
labels,
|
||||
typescript: { interface: labels.singular },
|
||||
},
|
||||
({ labels }) => ({
|
||||
defaultSort: fields.filename,
|
||||
admin: {
|
||||
useAsTitle: fields.filename,
|
||||
group: CollectionGroup.Media,
|
||||
},
|
||||
|
||||
upload: {
|
||||
staticDir: `../uploads/${labels.plural}`,
|
||||
adminThumbnail: "small",
|
||||
|
@ -48,6 +43,6 @@ export const RecorderThumbnails: CollectionConfig = {
|
|||
},
|
||||
],
|
||||
},
|
||||
|
||||
fields: [],
|
||||
};
|
||||
})
|
||||
);
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import { CollectionConfig } from "payload/types";
|
||||
import { localizedFields } from "../../fields/translatedFields/translatedFields";
|
||||
import { Languages } from "../Languages";
|
||||
import { beforeDuplicate } from "./hooks/beforeDuplicate";
|
||||
import { CollectionGroup } from "../../constants";
|
||||
import { collectionSlug } from "../../utils/string";
|
||||
import { RecorderThumbnails } from "../RecorderThumbnails/RecorderThumbnails";
|
||||
import { imageField } from "../../fields/imageField/imageField";
|
||||
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
||||
|
||||
const fields = {
|
||||
username: "username",
|
||||
|
@ -16,15 +15,12 @@ const fields = {
|
|||
avatar: "avatar",
|
||||
} as const satisfies Record<string, string>;
|
||||
|
||||
const labels = {
|
||||
export const Recorders = buildCollectionConfig(
|
||||
{
|
||||
singular: "Recorder",
|
||||
plural: "Recorders",
|
||||
} as const satisfies { singular: string; plural: string };
|
||||
|
||||
export const Recorders: CollectionConfig = {
|
||||
slug: collectionSlug(labels.plural),
|
||||
labels,
|
||||
typescript: { interface: labels.singular },
|
||||
},
|
||||
() => ({
|
||||
defaultSort: fields.username,
|
||||
admin: {
|
||||
useAsTitle: fields.username,
|
||||
|
@ -91,4 +87,5 @@ export const Recorders: CollectionConfig = {
|
|||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
})
|
||||
);
|
||||
|
|
|
@ -1,27 +1,60 @@
|
|||
import { CollectionConfig } from "payload/types";
|
||||
import { CollectionGroup } from "../constants";
|
||||
import { collectionSlug } from "../utils/string";
|
||||
import { CollectionGroup, UserRoles } from "../constants";
|
||||
import { Recorders } from "./Recorders/Recorders";
|
||||
import { buildCollectionConfig } from "../utils/collectionConfig";
|
||||
|
||||
const fields = {
|
||||
recorder: "recorder",
|
||||
name: "name",
|
||||
email: "email",
|
||||
role: "role",
|
||||
} as const satisfies Record<string, string>;
|
||||
|
||||
const labels = {
|
||||
export const Users = buildCollectionConfig(
|
||||
{
|
||||
singular: "User",
|
||||
plural: "Users",
|
||||
} as const satisfies { singular: string; plural: string };
|
||||
|
||||
export const Users: CollectionConfig = {
|
||||
slug: collectionSlug(labels.plural),
|
||||
},
|
||||
() => ({
|
||||
auth: true,
|
||||
labels,
|
||||
typescript: { interface: labels.singular },
|
||||
defaultSort: fields.email,
|
||||
defaultSort: fields.recorder,
|
||||
admin: {
|
||||
useAsTitle: fields.email,
|
||||
defaultColumns: [fields.email],
|
||||
useAsTitle: fields.name,
|
||||
defaultColumns: [fields.recorder, fields.name, fields.email, fields.role],
|
||||
group: CollectionGroup.Administration,
|
||||
},
|
||||
timestamps: false,
|
||||
fields: [],
|
||||
};
|
||||
fields: [
|
||||
{
|
||||
type: "row",
|
||||
fields: [
|
||||
{
|
||||
name: fields.recorder,
|
||||
type: "relationship",
|
||||
relationTo: Recorders.slug,
|
||||
required: true,
|
||||
admin: { width: "33%" },
|
||||
},
|
||||
{
|
||||
name: fields.name,
|
||||
type: "text",
|
||||
required: true,
|
||||
unique: true,
|
||||
admin: { width: "33%" },
|
||||
},
|
||||
{
|
||||
name: fields.role,
|
||||
required: true,
|
||||
defaultValue: [UserRoles.Recorder],
|
||||
type: "select",
|
||||
hasMany: true,
|
||||
options: Object.entries(UserRoles).map(([value, label]) => ({
|
||||
label,
|
||||
value,
|
||||
})),
|
||||
admin: { width: "33%" },
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
|
|
|
@ -42,3 +42,8 @@ export enum LibraryItemsTextualPageOrders {
|
|||
LeftToRight = "Left to right",
|
||||
RightToLeft = "Right to left",
|
||||
}
|
||||
|
||||
export enum UserRoles {
|
||||
Admin = "Admin",
|
||||
Recorder = "Recorder",
|
||||
}
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
import { Props } from "payload/components/views/Cell";
|
||||
import { useState, useEffect } from "react";
|
||||
import React from "react";
|
||||
import { isUndefined } from "../../utils/asserts";
|
||||
|
||||
export const Cell = ({ cellData, field }: Props): JSX.Element => {
|
||||
const [imageURL, setImageURL] = useState<string>();
|
||||
useEffect(() => {
|
||||
const fetchUrl = async () => {
|
||||
if (isUndefined(cellData)) return;
|
||||
if (typeof cellData !== "string") return;
|
||||
if (field.type !== "upload") return;
|
||||
const result = await (await fetch(`/api/${field.relationTo}/${cellData}`)).json();
|
||||
|
|
|
@ -44,10 +44,11 @@ export const localizedFields = ({
|
|||
components: {
|
||||
Cell: ({ cellData }) =>
|
||||
Cell({
|
||||
cellData: cellData.map((row) => ({
|
||||
cellData:
|
||||
cellData?.map((row) => ({
|
||||
language: row.language,
|
||||
title: isDefined(useAsTitle) ? row[useAsTitle] : undefined,
|
||||
})),
|
||||
})) ?? [],
|
||||
}),
|
||||
RowLabel: ({ data }) =>
|
||||
RowLabel({
|
||||
|
|
|
@ -93,6 +93,7 @@ export interface LibraryItem {
|
|||
}[];
|
||||
};
|
||||
releaseDate?: string;
|
||||
lastModifiedBy: string | User;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
_status?: "draft" | "published";
|
||||
|
@ -154,6 +155,57 @@ export interface Language {
|
|||
id: string;
|
||||
name: string;
|
||||
}
|
||||
export interface User {
|
||||
id: string;
|
||||
recorder: string | Recorder;
|
||||
name: string;
|
||||
role: ("Admin" | "Recorder")[];
|
||||
email: string;
|
||||
resetPasswordToken?: string;
|
||||
resetPasswordExpiration?: string;
|
||||
salt?: string;
|
||||
hash?: string;
|
||||
loginAttempts?: number;
|
||||
lockUntil?: string;
|
||||
password?: string;
|
||||
}
|
||||
export interface Recorder {
|
||||
id: string;
|
||||
username: string;
|
||||
avatar?: string | RecorderThumbnail;
|
||||
languages?: string[] | Language[];
|
||||
biographies?: RecorderBiographies;
|
||||
anonymize: boolean;
|
||||
}
|
||||
export interface RecorderThumbnail {
|
||||
id: string;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
url?: string;
|
||||
filename?: string;
|
||||
mimeType?: string;
|
||||
filesize?: number;
|
||||
width?: number;
|
||||
height?: number;
|
||||
sizes?: {
|
||||
og?: {
|
||||
url?: string;
|
||||
width?: number;
|
||||
height?: number;
|
||||
mimeType?: string;
|
||||
filesize?: number;
|
||||
filename?: string;
|
||||
};
|
||||
small?: {
|
||||
url?: string;
|
||||
width?: number;
|
||||
height?: number;
|
||||
mimeType?: string;
|
||||
filesize?: number;
|
||||
filename?: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
export interface Content {
|
||||
id: string;
|
||||
slug: string;
|
||||
|
@ -188,6 +240,7 @@ export interface Content {
|
|||
audio?: string | File;
|
||||
id?: string;
|
||||
}[];
|
||||
lastModifiedBy: string | User;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
_status?: "draft" | "published";
|
||||
|
@ -221,43 +274,6 @@ export interface ContentThumbnail {
|
|||
};
|
||||
};
|
||||
}
|
||||
export interface Recorder {
|
||||
id: string;
|
||||
username: string;
|
||||
avatar?: string | RecorderThumbnail;
|
||||
languages?: string[] | Language[];
|
||||
biographies?: RecorderBiographies;
|
||||
anonymize: boolean;
|
||||
}
|
||||
export interface RecorderThumbnail {
|
||||
id: string;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
url?: string;
|
||||
filename?: string;
|
||||
mimeType?: string;
|
||||
filesize?: number;
|
||||
width?: number;
|
||||
height?: number;
|
||||
sizes?: {
|
||||
og?: {
|
||||
url?: string;
|
||||
width?: number;
|
||||
height?: number;
|
||||
mimeType?: string;
|
||||
filesize?: number;
|
||||
filename?: string;
|
||||
};
|
||||
small?: {
|
||||
url?: string;
|
||||
width?: number;
|
||||
height?: number;
|
||||
mimeType?: string;
|
||||
filesize?: number;
|
||||
filename?: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
export interface TextBlock {
|
||||
content: {
|
||||
[k: string]: unknown;
|
||||
|
@ -511,6 +527,7 @@ export interface Post {
|
|||
}[];
|
||||
publishedDate: string;
|
||||
hidden?: boolean;
|
||||
lastModifiedBy: string | User;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
_status?: "draft" | "published";
|
||||
|
@ -544,14 +561,3 @@ export interface PostThumbnail {
|
|||
};
|
||||
};
|
||||
}
|
||||
export interface User {
|
||||
id: string;
|
||||
email: string;
|
||||
resetPasswordToken?: string;
|
||||
resetPasswordExpiration?: string;
|
||||
salt?: string;
|
||||
hash?: string;
|
||||
loginAttempts?: number;
|
||||
lockUntil?: string;
|
||||
password?: string;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
import { CollectionConfig } from "payload/types";
|
||||
import slugify from "slugify";
|
||||
|
||||
export type BuildCollectionConfig = Omit<CollectionConfig, "slug" | "typescript" | "labels">;
|
||||
|
||||
export type GenerationFunctionProps = {
|
||||
labels: { singular: string; plural: string };
|
||||
slug: string;
|
||||
};
|
||||
|
||||
export const buildCollectionConfig = (
|
||||
labels: { singular: string; plural: string },
|
||||
generationFunction: (props: GenerationFunctionProps) => BuildCollectionConfig
|
||||
): CollectionConfig => {
|
||||
const slug = slugify(labels.plural, { lower: true, strict: true, trim: true });
|
||||
const config = generationFunction({ labels, slug });
|
||||
return {
|
||||
...config,
|
||||
slug,
|
||||
typescript: { interface: labels.singular },
|
||||
};
|
||||
};
|
|
@ -1,11 +1,7 @@
|
|||
import ISO6391 from "iso-639-1";
|
||||
import slugify from "slugify";
|
||||
|
||||
export const shortenEllipsis = (text: string, length: number): string =>
|
||||
text.length - 3 > length ? `${text.substring(0, length)}...` : text;
|
||||
|
||||
export const formatLanguageCode = (code: string): string =>
|
||||
ISO6391.validate(code) ? ISO6391.getName(code) : code;
|
||||
|
||||
export const collectionSlug = (text: string): string =>
|
||||
slugify(text, { lower: true, strict: true, trim: true });
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
import { CollectionBeforeChangeHook, CollectionConfig, RelationshipField } from "payload/types";
|
||||
import { Users } from "../collections/Users";
|
||||
import {
|
||||
BuildCollectionConfig,
|
||||
GenerationFunctionProps,
|
||||
buildCollectionConfig,
|
||||
} from "./collectionConfig";
|
||||
|
||||
const fields = { lastModifiedBy: "lastModifiedBy" };
|
||||
|
||||
const beforeChangeLastModifiedBy: CollectionBeforeChangeHook = async ({
|
||||
data: { updatedBy, ...data },
|
||||
req,
|
||||
}) => {
|
||||
console.log(data, req.user);
|
||||
return {
|
||||
...data,
|
||||
[fields.lastModifiedBy]: req.user.id,
|
||||
};
|
||||
};
|
||||
|
||||
const lastModifiedByField = (): RelationshipField => ({
|
||||
name: fields.lastModifiedBy,
|
||||
type: "relationship",
|
||||
required: true,
|
||||
relationTo: Users.slug,
|
||||
admin: { readOnly: true, position: "sidebar" },
|
||||
});
|
||||
|
||||
type BuildVersionedCollectionConfig = Omit<BuildCollectionConfig, "timestamps" | "versions">;
|
||||
|
||||
export const buildVersionedCollectionConfig = (
|
||||
labels: { singular: string; plural: string },
|
||||
generationFunction: (props: GenerationFunctionProps) => BuildVersionedCollectionConfig
|
||||
): CollectionConfig => {
|
||||
const {
|
||||
hooks: { beforeChange, ...otherHooks } = {},
|
||||
fields,
|
||||
...otherParams
|
||||
} = buildCollectionConfig(labels, generationFunction);
|
||||
|
||||
return {
|
||||
...otherParams,
|
||||
timestamps: true,
|
||||
versions: { drafts: { autosave: { interval: 2000 } } },
|
||||
hooks: {
|
||||
...otherHooks,
|
||||
beforeChange: [...(beforeChange ?? []), beforeChangeLastModifiedBy],
|
||||
},
|
||||
fields: [...fields, lastModifiedByField()],
|
||||
};
|
||||
};
|
Loading…
Reference in New Issue