Access control
This commit is contained in:
parent
1cda674782
commit
e98fabfd0e
|
@ -21,6 +21,7 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/dotenv": "^8.2.0",
|
"@types/dotenv": "^8.2.0",
|
||||||
"@types/express": "^4.17.9",
|
"@types/express": "^4.17.9",
|
||||||
|
"@types/react-router-dom": "^5.3.3",
|
||||||
"copyfiles": "^2.4.1",
|
"copyfiles": "^2.4.1",
|
||||||
"nodemon": "^2.0.6",
|
"nodemon": "^2.0.6",
|
||||||
"prettier": "^3.0.0",
|
"prettier": "^3.0.0",
|
||||||
|
@ -2998,6 +2999,12 @@
|
||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/history": {
|
||||||
|
"version": "4.7.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz",
|
||||||
|
"integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/@types/html-minifier-terser": {
|
"node_modules/@types/html-minifier-terser": {
|
||||||
"version": "6.1.0",
|
"version": "6.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
|
||||||
|
@ -3098,6 +3105,27 @@
|
||||||
"csstype": "^3.0.2"
|
"csstype": "^3.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/react-router": {
|
||||||
|
"version": "5.1.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz",
|
||||||
|
"integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@types/history": "^4.7.11",
|
||||||
|
"@types/react": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/react-router-dom": {
|
||||||
|
"version": "5.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz",
|
||||||
|
"integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@types/history": "^4.7.11",
|
||||||
|
"@types/react": "*",
|
||||||
|
"@types/react-router": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/react-transition-group": {
|
"node_modules/@types/react-transition-group": {
|
||||||
"version": "4.4.6",
|
"version": "4.4.6",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.6.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.6.tgz",
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/dotenv": "^8.2.0",
|
"@types/dotenv": "^8.2.0",
|
||||||
"@types/express": "^4.17.9",
|
"@types/express": "^4.17.9",
|
||||||
|
"@types/react-router-dom": "^5.3.3",
|
||||||
"copyfiles": "^2.4.1",
|
"copyfiles": "^2.4.1",
|
||||||
"nodemon": "^2.0.6",
|
"nodemon": "^2.0.6",
|
||||||
"prettier": "^3.0.0",
|
"prettier": "^3.0.0",
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { Access } from "payload/config";
|
||||||
|
import { Recorder } from "../../types/collections";
|
||||||
|
import { RecordersRoles } from "../../constants";
|
||||||
|
import { isUndefined } from "../../utils/asserts";
|
||||||
|
|
||||||
|
export const mustBeAdminOrSelf: Access = ({ req }) => {
|
||||||
|
const user = req.user as Recorder | undefined;
|
||||||
|
if (isUndefined(user)) return false;
|
||||||
|
if (user.role.includes(RecordersRoles.Admin)) return true;
|
||||||
|
return { id: { equals: user.id } };
|
||||||
|
};
|
|
@ -0,0 +1,8 @@
|
||||||
|
import { Recorder } from "../../types/collections";
|
||||||
|
import { isUndefined } from "../../utils/asserts";
|
||||||
|
|
||||||
|
export const mustHaveAtLeastOneRole = ({ req }): boolean => {
|
||||||
|
const user = req.user as Recorder | undefined;
|
||||||
|
if (isUndefined(user)) return false;
|
||||||
|
return user.role.length > 0;
|
||||||
|
};
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { Recorder } from "../types/collections";
|
||||||
|
import { RecordersRoles } from "../constants";
|
||||||
|
import { isUndefined } from "../utils/asserts";
|
||||||
|
|
||||||
|
export const mustBeAdmin = ({ req }): boolean => {
|
||||||
|
const user = req.user as Recorder | undefined;
|
||||||
|
if (isUndefined(user)) return false;
|
||||||
|
return user.role.includes(RecordersRoles.Admin);
|
||||||
|
};
|
|
@ -22,6 +22,7 @@ export const ContentFolders = buildCollectionConfig(
|
||||||
admin: {
|
admin: {
|
||||||
useAsTitle: fields.slug,
|
useAsTitle: fields.slug,
|
||||||
defaultColumns: [fields.slug, fields.translations],
|
defaultColumns: [fields.slug, fields.translations],
|
||||||
|
disableDuplicate: true,
|
||||||
group: CollectionGroup.Collections,
|
group: CollectionGroup.Collections,
|
||||||
},
|
},
|
||||||
timestamps: false,
|
timestamps: false,
|
||||||
|
|
|
@ -16,6 +16,7 @@ export const ContentThumbnails = buildCollectionConfig(
|
||||||
defaultSort: fields.filename,
|
defaultSort: fields.filename,
|
||||||
admin: {
|
admin: {
|
||||||
useAsTitle: fields.filename,
|
useAsTitle: fields.filename,
|
||||||
|
disableDuplicate: true,
|
||||||
group: CollectionGroup.Media,
|
group: CollectionGroup.Media,
|
||||||
},
|
},
|
||||||
upload: {
|
upload: {
|
||||||
|
|
|
@ -9,6 +9,9 @@ import { fileField } from "../../fields/fileField/fileField";
|
||||||
import { contentBlocks } from "./Blocks/blocks";
|
import { contentBlocks } from "./Blocks/blocks";
|
||||||
import { ContentThumbnails } from "../ContentThumbnails/ContentThumbnails";
|
import { ContentThumbnails } from "../ContentThumbnails/ContentThumbnails";
|
||||||
import { buildVersionedCollectionConfig } from "../../utils/versionedCollectionConfig";
|
import { buildVersionedCollectionConfig } from "../../utils/versionedCollectionConfig";
|
||||||
|
import { beforeDuplicatePiping } from "../../hooks/beforeDuplicatePiping";
|
||||||
|
import { beforeDuplicateUnpublish } from "../../hooks/beforeDuplicateUnpublish";
|
||||||
|
import { beforeDuplicateAddCopyTo } from "../../hooks/beforeDuplicateAddCopyTo";
|
||||||
|
|
||||||
const fields = {
|
const fields = {
|
||||||
slug: "slug",
|
slug: "slug",
|
||||||
|
@ -53,6 +56,12 @@ export const Contents = buildVersionedCollectionConfig(
|
||||||
fields.status,
|
fields.status,
|
||||||
],
|
],
|
||||||
group: CollectionGroup.Collections,
|
group: CollectionGroup.Collections,
|
||||||
|
hooks: {
|
||||||
|
beforeDuplicate: beforeDuplicatePiping([
|
||||||
|
beforeDuplicateUnpublish,
|
||||||
|
beforeDuplicateAddCopyTo(fields.slug),
|
||||||
|
]),
|
||||||
|
},
|
||||||
preview: (doc) => `https://accords-library.com/contents/${doc.slug}`,
|
preview: (doc) => `https://accords-library.com/contents/${doc.slug}`,
|
||||||
},
|
},
|
||||||
fields: [
|
fields: [
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
import { mustBeAdmin } from "../../accesses/mustBeAdmin";
|
||||||
|
import { CollectionGroup } from "../../constants";
|
||||||
|
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
||||||
|
|
||||||
|
const fields = {
|
||||||
|
id: "id",
|
||||||
|
} as const satisfies Record<string, string>;
|
||||||
|
|
||||||
|
export const Currencies = buildCollectionConfig(
|
||||||
|
{
|
||||||
|
singular: "Currency",
|
||||||
|
plural: "Currencies",
|
||||||
|
},
|
||||||
|
() => ({
|
||||||
|
defaultSort: fields.id,
|
||||||
|
admin: {
|
||||||
|
useAsTitle: fields.id,
|
||||||
|
defaultColumns: [fields.id],
|
||||||
|
disableDuplicate: true,
|
||||||
|
group: CollectionGroup.Meta,
|
||||||
|
},
|
||||||
|
access: { create: mustBeAdmin, update: mustBeAdmin },
|
||||||
|
timestamps: false,
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: fields.id,
|
||||||
|
type: "text",
|
||||||
|
unique: true,
|
||||||
|
required: true,
|
||||||
|
validate: (value) => {
|
||||||
|
if (/^[A-Z]{3}$/g.test(value)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return "The code must be a valid ISO 4217 currency code (e.g: EUR, CAD...)";
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
);
|
|
@ -15,6 +15,7 @@ export const Files = buildCollectionConfig(
|
||||||
defaultSort: fields.filename,
|
defaultSort: fields.filename,
|
||||||
admin: {
|
admin: {
|
||||||
useAsTitle: fields.filename,
|
useAsTitle: fields.filename,
|
||||||
|
disableDuplicate: true,
|
||||||
group: CollectionGroup.Media,
|
group: CollectionGroup.Media,
|
||||||
},
|
},
|
||||||
fields: [
|
fields: [
|
||||||
|
|
|
@ -5,6 +5,9 @@ import { localizedFields } from "../../fields/translatedFields/translatedFields"
|
||||||
import { Key } from "../../types/collections";
|
import { Key } from "../../types/collections";
|
||||||
import { isDefined } from "../../utils/asserts";
|
import { isDefined } from "../../utils/asserts";
|
||||||
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
||||||
|
import { mustBeAdmin } from "../../accesses/mustBeAdmin";
|
||||||
|
import { beforeDuplicateAddCopyTo } from "../../hooks/beforeDuplicateAddCopyTo";
|
||||||
|
import { QuickFilters } from "../../components/QuickFilters";
|
||||||
|
|
||||||
const fields = {
|
const fields = {
|
||||||
slug: "slug",
|
slug: "slug",
|
||||||
|
@ -27,6 +30,26 @@ export const Keys: CollectionConfig = buildCollectionConfig(
|
||||||
useAsTitle: fields.slug,
|
useAsTitle: fields.slug,
|
||||||
defaultColumns: [fields.slug, fields.type, fields.translations],
|
defaultColumns: [fields.slug, fields.type, fields.translations],
|
||||||
group: CollectionGroup.Meta,
|
group: CollectionGroup.Meta,
|
||||||
|
components: {
|
||||||
|
BeforeListTable: [
|
||||||
|
() =>
|
||||||
|
QuickFilters({
|
||||||
|
route: "/admin/collections/keys",
|
||||||
|
filters: [
|
||||||
|
{ label: "Wordings", filter: "where[type][equals]=Wordings" },
|
||||||
|
{ label: "∅ English", filter: "where[translations.language][not_equals]=en" },
|
||||||
|
{ label: "∅ French", filter: "where[translations.language][not_equals]=fr" },
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
hooks: {
|
||||||
|
beforeDuplicate: beforeDuplicateAddCopyTo(fields.slug),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
access: {
|
||||||
|
create: mustBeAdmin,
|
||||||
|
delete: mustBeAdmin,
|
||||||
},
|
},
|
||||||
timestamps: false,
|
timestamps: false,
|
||||||
versions: false,
|
versions: false,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { CollectionGroup } from "../constants";
|
import { mustBeAdmin } from "../../accesses/mustBeAdmin";
|
||||||
import { buildCollectionConfig } from "../utils/collectionConfig";
|
import { CollectionGroup } from "../../constants";
|
||||||
|
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
||||||
|
|
||||||
const fields = {
|
const fields = {
|
||||||
id: "id",
|
id: "id",
|
||||||
|
@ -16,8 +17,10 @@ export const Languages = buildCollectionConfig(
|
||||||
admin: {
|
admin: {
|
||||||
useAsTitle: fields.name,
|
useAsTitle: fields.name,
|
||||||
defaultColumns: [fields.name, fields.id],
|
defaultColumns: [fields.name, fields.id],
|
||||||
|
disableDuplicate: true,
|
||||||
group: CollectionGroup.Meta,
|
group: CollectionGroup.Meta,
|
||||||
},
|
},
|
||||||
|
access: { create: mustBeAdmin, update: mustBeAdmin },
|
||||||
timestamps: false,
|
timestamps: false,
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
|
@ -16,6 +16,7 @@ export const LibraryItemThumbnails = buildCollectionConfig(
|
||||||
defaultSort: fields.filename,
|
defaultSort: fields.filename,
|
||||||
admin: {
|
admin: {
|
||||||
useAsTitle: fields.filename,
|
useAsTitle: fields.filename,
|
||||||
|
disableDuplicate: true,
|
||||||
group: CollectionGroup.Media,
|
group: CollectionGroup.Media,
|
||||||
},
|
},
|
||||||
upload: {
|
upload: {
|
||||||
|
|
|
@ -11,8 +11,13 @@ import { isDefined, isUndefined } from "../../utils/asserts";
|
||||||
import { LibraryItemThumbnails } from "../LibraryItemThumbnails/LibraryItemThumbnails";
|
import { LibraryItemThumbnails } from "../LibraryItemThumbnails/LibraryItemThumbnails";
|
||||||
import { LibraryItem } from "../../types/collections";
|
import { LibraryItem } from "../../types/collections";
|
||||||
import { Keys } from "../Keys/Keys";
|
import { Keys } from "../Keys/Keys";
|
||||||
import { Languages } from "../Languages";
|
import { Languages } from "../Languages/Languages";
|
||||||
import { buildVersionedCollectionConfig } from "../../utils/versionedCollectionConfig";
|
import { buildVersionedCollectionConfig } from "../../utils/versionedCollectionConfig";
|
||||||
|
import { beforeDuplicateAddCopyTo } from "../../hooks/beforeDuplicateAddCopyTo";
|
||||||
|
import { beforeDuplicateUnpublish } from "../../hooks/beforeDuplicateUnpublish";
|
||||||
|
import { beforeDuplicatePiping } from "../../hooks/beforeDuplicatePiping";
|
||||||
|
import { Currencies } from "../Currencies/Currencies";
|
||||||
|
import { optionalGroupField } from "../../fields/optionalGroupField/optionalGroupField";
|
||||||
|
|
||||||
const fields = {
|
const fields = {
|
||||||
status: "status",
|
status: "status",
|
||||||
|
@ -29,6 +34,9 @@ const fields = {
|
||||||
width: "width",
|
width: "width",
|
||||||
height: "height",
|
height: "height",
|
||||||
thickness: "thickness",
|
thickness: "thickness",
|
||||||
|
price: "price",
|
||||||
|
priceAmount: "amount",
|
||||||
|
priceCurrency: "currency",
|
||||||
releaseDate: "releaseDate",
|
releaseDate: "releaseDate",
|
||||||
itemType: "itemType",
|
itemType: "itemType",
|
||||||
textual: "textual",
|
textual: "textual",
|
||||||
|
@ -39,19 +47,24 @@ const fields = {
|
||||||
textualLanguages: "languages",
|
textualLanguages: "languages",
|
||||||
audio: "audio",
|
audio: "audio",
|
||||||
audioSubtype: "audioSubtype",
|
audioSubtype: "audioSubtype",
|
||||||
|
scans: "scans",
|
||||||
|
scansCover: "cover",
|
||||||
|
scansCoverFront: "front",
|
||||||
|
scansCoverSpine: "spine",
|
||||||
|
scansCoverBack: "back",
|
||||||
|
scansDustjacket: "dustjacket",
|
||||||
|
scansDustjacketFront: "front",
|
||||||
|
scansDustjacketSpine: "spine",
|
||||||
|
scansDustjacketBack: "back",
|
||||||
|
scansObibelt: "obibelt",
|
||||||
|
scansObibeltFront: "front",
|
||||||
|
scansObibeltSpine: "spine",
|
||||||
|
scansObibeltBack: "back",
|
||||||
|
scansPages: "pages",
|
||||||
|
scansPagesPage: "page",
|
||||||
|
scansPagesImage: "image",
|
||||||
} as const satisfies Record<string, string>;
|
} as const satisfies Record<string, string>;
|
||||||
|
|
||||||
const validateSizeValue = (value?: number) => {
|
|
||||||
if (isDefined(value) && value <= 0) return "This value must be greater than 0";
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
const validateRequiredSizeValue = (value?: number) => {
|
|
||||||
if (isUndefined(value)) return "This field is required.";
|
|
||||||
if (value <= 0) return "This value must be greater than 0.";
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const LibraryItems = buildVersionedCollectionConfig(
|
export const LibraryItems = buildVersionedCollectionConfig(
|
||||||
{
|
{
|
||||||
singular: "Library Item",
|
singular: "Library Item",
|
||||||
|
@ -63,9 +76,15 @@ export const LibraryItems = buildVersionedCollectionConfig(
|
||||||
useAsTitle: fields.slug,
|
useAsTitle: fields.slug,
|
||||||
description:
|
description:
|
||||||
"A comprehensive list of all Yokoverse’s side materials (books, novellas, artbooks, \
|
"A comprehensive list of all Yokoverse’s side materials (books, novellas, artbooks, \
|
||||||
stage plays, manga, drama CDs, and comics).",
|
stage plays, manga, drama CDs, and comics).",
|
||||||
defaultColumns: [fields.slug, fields.thumbnail, fields.status],
|
defaultColumns: [fields.slug, fields.thumbnail, fields.status],
|
||||||
group: CollectionGroup.Collections,
|
group: CollectionGroup.Collections,
|
||||||
|
hooks: {
|
||||||
|
beforeDuplicate: beforeDuplicatePiping([
|
||||||
|
beforeDuplicateUnpublish,
|
||||||
|
beforeDuplicateAddCopyTo(fields.slug),
|
||||||
|
]),
|
||||||
|
},
|
||||||
preview: (doc) => `https://accords-library.com/library/${doc.slug}`,
|
preview: (doc) => `https://accords-library.com/library/${doc.slug}`,
|
||||||
},
|
},
|
||||||
fields: [
|
fields: [
|
||||||
|
@ -135,9 +154,115 @@ stage plays, manga, drama CDs, and comics).",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
optionalGroupField({
|
||||||
name: "size",
|
name: fields.scans,
|
||||||
type: "group",
|
fields: [
|
||||||
|
optionalGroupField({
|
||||||
|
name: fields.scansCover,
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
type: "row",
|
||||||
|
fields: [
|
||||||
|
imageField({
|
||||||
|
name: fields.scansCoverFront,
|
||||||
|
relationTo: LibraryItemThumbnails.slug,
|
||||||
|
admin: { width: "33%" },
|
||||||
|
}),
|
||||||
|
imageField({
|
||||||
|
name: fields.scansCoverSpine,
|
||||||
|
relationTo: LibraryItemThumbnails.slug,
|
||||||
|
admin: { width: "33%" },
|
||||||
|
}),
|
||||||
|
imageField({
|
||||||
|
name: fields.scansCoverBack,
|
||||||
|
relationTo: LibraryItemThumbnails.slug,
|
||||||
|
admin: { width: "33%" },
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
optionalGroupField({
|
||||||
|
name: fields.scansDustjacket,
|
||||||
|
label: "Dust Jacket",
|
||||||
|
labels: { singular: "Dust Jacket", plural: "Dust Jackets" },
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
type: "row",
|
||||||
|
fields: [
|
||||||
|
imageField({
|
||||||
|
name: fields.scansDustjacketFront,
|
||||||
|
relationTo: LibraryItemThumbnails.slug,
|
||||||
|
admin: { width: "33%" },
|
||||||
|
}),
|
||||||
|
imageField({
|
||||||
|
name: fields.scansDustjacketSpine,
|
||||||
|
relationTo: LibraryItemThumbnails.slug,
|
||||||
|
admin: { width: "33%" },
|
||||||
|
}),
|
||||||
|
imageField({
|
||||||
|
name: fields.scansDustjacketBack,
|
||||||
|
relationTo: LibraryItemThumbnails.slug,
|
||||||
|
admin: { width: "33%" },
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
optionalGroupField({
|
||||||
|
name: fields.scansObibelt,
|
||||||
|
label: "Obi Belt",
|
||||||
|
labels: { singular: "Obi Belt", plural: "Obi Belts" },
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
type: "row",
|
||||||
|
fields: [
|
||||||
|
imageField({
|
||||||
|
name: fields.scansObibeltFront,
|
||||||
|
relationTo: LibraryItemThumbnails.slug,
|
||||||
|
admin: { width: "33%" },
|
||||||
|
}),
|
||||||
|
imageField({
|
||||||
|
name: fields.scansObibeltSpine,
|
||||||
|
relationTo: LibraryItemThumbnails.slug,
|
||||||
|
admin: { width: "33%" },
|
||||||
|
}),
|
||||||
|
imageField({
|
||||||
|
name: fields.scansObibeltBack,
|
||||||
|
relationTo: LibraryItemThumbnails.slug,
|
||||||
|
admin: { width: "33%" },
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
name: fields.scansPages,
|
||||||
|
type: "array",
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
type: "row",
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: fields.scansPagesPage,
|
||||||
|
type: "number",
|
||||||
|
required: true,
|
||||||
|
admin: { width: "33%" },
|
||||||
|
},
|
||||||
|
imageField({
|
||||||
|
name: fields.scansPagesImage,
|
||||||
|
relationTo: LibraryItemThumbnails.slug,
|
||||||
|
required: true,
|
||||||
|
admin: { width: "66%" },
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
optionalGroupField({
|
||||||
|
name: fields.size,
|
||||||
admin: { condition: (data) => !data.digital },
|
admin: { condition: (data) => !data.digital },
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
|
@ -146,25 +271,49 @@ stage plays, manga, drama CDs, and comics).",
|
||||||
{
|
{
|
||||||
name: fields.width,
|
name: fields.width,
|
||||||
type: "number",
|
type: "number",
|
||||||
validate: validateRequiredSizeValue,
|
required: true,
|
||||||
admin: { step: 1, width: "33%", description: "in mm." },
|
admin: { step: 1, width: "33%", description: "in mm." },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: fields.height,
|
name: fields.height,
|
||||||
type: "number",
|
type: "number",
|
||||||
validate: validateRequiredSizeValue,
|
required: true,
|
||||||
admin: { step: 1, width: "33%", description: "in mm." },
|
admin: { step: 1, width: "33%", description: "in mm." },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: fields.thickness,
|
name: fields.thickness,
|
||||||
type: "number",
|
type: "number",
|
||||||
validate: validateSizeValue,
|
|
||||||
admin: { step: 1, width: "33%", description: "in mm." },
|
admin: { step: 1, width: "33%", description: "in mm." },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
}),
|
||||||
|
optionalGroupField({
|
||||||
|
name: fields.price,
|
||||||
|
admin: { className: "group-array" },
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
type: "row",
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: fields.priceAmount,
|
||||||
|
type: "number",
|
||||||
|
required: true,
|
||||||
|
min: 0,
|
||||||
|
admin: { width: "50%" },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: fields.priceCurrency,
|
||||||
|
type: "relationship",
|
||||||
|
relationTo: Currencies.slug,
|
||||||
|
required: true,
|
||||||
|
admin: { allowCreate: false, width: "50%" },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
{
|
{
|
||||||
name: fields.itemType,
|
name: fields.itemType,
|
||||||
type: "radio",
|
type: "radio",
|
||||||
|
|
|
@ -16,6 +16,7 @@ export const PostThumbnails = buildCollectionConfig(
|
||||||
defaultSort: fields.filename,
|
defaultSort: fields.filename,
|
||||||
admin: {
|
admin: {
|
||||||
useAsTitle: fields.filename,
|
useAsTitle: fields.filename,
|
||||||
|
disableDuplicate: true,
|
||||||
group: CollectionGroup.Media,
|
group: CollectionGroup.Media,
|
||||||
},
|
},
|
||||||
upload: {
|
upload: {
|
||||||
|
|
|
@ -8,6 +8,9 @@ import { removeTranslatorsForTranscripts } from "./hooks/beforeValidate";
|
||||||
import { Keys } from "../Keys/Keys";
|
import { Keys } from "../Keys/Keys";
|
||||||
import { PostThumbnails } from "../PostThumbnails/PostThumbnails";
|
import { PostThumbnails } from "../PostThumbnails/PostThumbnails";
|
||||||
import { buildVersionedCollectionConfig } from "../../utils/versionedCollectionConfig";
|
import { buildVersionedCollectionConfig } from "../../utils/versionedCollectionConfig";
|
||||||
|
import { beforeDuplicatePiping } from "../../hooks/beforeDuplicatePiping";
|
||||||
|
import { beforeDuplicateUnpublish } from "../../hooks/beforeDuplicateUnpublish";
|
||||||
|
import { beforeDuplicateAddCopyTo } from "../../hooks/beforeDuplicateAddCopyTo";
|
||||||
|
|
||||||
const fields = {
|
const fields = {
|
||||||
slug: "slug",
|
slug: "slug",
|
||||||
|
@ -36,9 +39,15 @@ export const Posts = buildVersionedCollectionConfig(
|
||||||
useAsTitle: fields.slug,
|
useAsTitle: fields.slug,
|
||||||
description:
|
description:
|
||||||
"News articles written by our Recorders! Here you will find announcements about \
|
"News articles written by our Recorders! Here you will find announcements about \
|
||||||
new merch/items releases, guides, theories, unboxings, showcases...",
|
new merch/items releases, guides, theories, unboxings, showcases...",
|
||||||
defaultColumns: [fields.slug, fields.thumbnail, fields.categories],
|
defaultColumns: [fields.slug, fields.thumbnail, fields.categories],
|
||||||
group: CollectionGroup.Collections,
|
group: CollectionGroup.Collections,
|
||||||
|
hooks: {
|
||||||
|
beforeDuplicate: beforeDuplicatePiping([
|
||||||
|
beforeDuplicateUnpublish,
|
||||||
|
beforeDuplicateAddCopyTo(fields.slug),
|
||||||
|
]),
|
||||||
|
},
|
||||||
preview: (doc) => `https://accords-library.com/news/${doc.slug}`,
|
preview: (doc) => `https://accords-library.com/news/${doc.slug}`,
|
||||||
},
|
},
|
||||||
hooks: {
|
hooks: {
|
||||||
|
|
|
@ -16,6 +16,7 @@ export const RecorderThumbnails = buildCollectionConfig(
|
||||||
defaultSort: fields.filename,
|
defaultSort: fields.filename,
|
||||||
admin: {
|
admin: {
|
||||||
useAsTitle: fields.filename,
|
useAsTitle: fields.filename,
|
||||||
|
disableDuplicate: true,
|
||||||
group: CollectionGroup.Media,
|
group: CollectionGroup.Media,
|
||||||
},
|
},
|
||||||
upload: {
|
upload: {
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
import { localizedFields } from "../../fields/translatedFields/translatedFields";
|
import { localizedFields } from "../../fields/translatedFields/translatedFields";
|
||||||
import { Languages } from "../Languages";
|
import { Languages } from "../Languages/Languages";
|
||||||
import { beforeDuplicate } from "./hooks/beforeDuplicate";
|
import { CollectionGroup, RecordersRoles } from "../../constants";
|
||||||
import { CollectionGroup } from "../../constants";
|
|
||||||
import { RecorderThumbnails } from "../RecorderThumbnails/RecorderThumbnails";
|
import { RecorderThumbnails } from "../RecorderThumbnails/RecorderThumbnails";
|
||||||
import { imageField } from "../../fields/imageField/imageField";
|
import { imageField } from "../../fields/imageField/imageField";
|
||||||
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
||||||
|
import { mustBeAdmin } from "../../accesses/mustBeAdmin";
|
||||||
|
import { mustBeAdminOrSelf } from "../../accesses/collections/mustBeAdminOrSelf";
|
||||||
|
import { beforeLoginMustHaveAtLeastOneRole } from "./hooks/beforeLoginMustHaveAtLeastOneRole";
|
||||||
|
import { QuickFilters } from "../../components/QuickFilters";
|
||||||
|
|
||||||
const fields = {
|
const fields = {
|
||||||
username: "username",
|
username: "username",
|
||||||
|
@ -13,6 +16,7 @@ const fields = {
|
||||||
biographies: "biographies",
|
biographies: "biographies",
|
||||||
biography: "biography",
|
biography: "biography",
|
||||||
avatar: "avatar",
|
avatar: "avatar",
|
||||||
|
role: "role",
|
||||||
} as const satisfies Record<string, string>;
|
} as const satisfies Record<string, string>;
|
||||||
|
|
||||||
export const Recorders = buildCollectionConfig(
|
export const Recorders = buildCollectionConfig(
|
||||||
|
@ -24,17 +28,43 @@ export const Recorders = buildCollectionConfig(
|
||||||
defaultSort: fields.username,
|
defaultSort: fields.username,
|
||||||
admin: {
|
admin: {
|
||||||
useAsTitle: fields.username,
|
useAsTitle: fields.username,
|
||||||
hooks: { beforeDuplicate },
|
|
||||||
description:
|
description:
|
||||||
"Recorders are contributors of the Accord's Library project. Create a Recorder here to be able to credit them in other collections",
|
"Recorders are contributors of the Accord's Library project. Ask an admin to create a \
|
||||||
|
Recorder here to be able to credit them in other collections.",
|
||||||
defaultColumns: [
|
defaultColumns: [
|
||||||
fields.username,
|
fields.username,
|
||||||
fields.avatar,
|
fields.avatar,
|
||||||
fields.anonymize,
|
fields.anonymize,
|
||||||
fields.biographies,
|
fields.biographies,
|
||||||
fields.languages,
|
fields.languages,
|
||||||
|
fields.role,
|
||||||
],
|
],
|
||||||
|
disableDuplicate: true,
|
||||||
group: CollectionGroup.Meta,
|
group: CollectionGroup.Meta,
|
||||||
|
components: {
|
||||||
|
BeforeListTable: [
|
||||||
|
() =>
|
||||||
|
QuickFilters({
|
||||||
|
route: "/admin/collections/recorders",
|
||||||
|
filters: [
|
||||||
|
{ label: "Admins", filter: "where[role][equals]=Admin" },
|
||||||
|
{ label: "Recorders", filter: "where[role][equals]=Recorder" },
|
||||||
|
{ label: "∅ Role", filter: "where[role][not_in]=Admin,Recorder" },
|
||||||
|
{ label: "Anonymized", filter: "where[anonymize][equals]=true" },
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
auth: true,
|
||||||
|
access: {
|
||||||
|
unlock: mustBeAdmin,
|
||||||
|
update: mustBeAdminOrSelf,
|
||||||
|
delete: mustBeAdmin,
|
||||||
|
create: mustBeAdmin,
|
||||||
|
},
|
||||||
|
hooks: {
|
||||||
|
beforeLogin: [beforeLoginMustHaveAtLeastOneRole],
|
||||||
},
|
},
|
||||||
timestamps: false,
|
timestamps: false,
|
||||||
fields: [
|
fields: [
|
||||||
|
@ -75,6 +105,20 @@ export const Recorders = buildCollectionConfig(
|
||||||
},
|
},
|
||||||
fields: [{ name: fields.biography, type: "textarea" }],
|
fields: [{ name: fields.biography, type: "textarea" }],
|
||||||
}),
|
}),
|
||||||
|
{
|
||||||
|
name: fields.role,
|
||||||
|
type: "select",
|
||||||
|
access: {
|
||||||
|
update: mustBeAdmin,
|
||||||
|
create: mustBeAdmin,
|
||||||
|
},
|
||||||
|
hasMany: true,
|
||||||
|
options: Object.entries(RecordersRoles).map(([value, label]) => ({
|
||||||
|
label,
|
||||||
|
value,
|
||||||
|
})),
|
||||||
|
admin: { position: "sidebar" },
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: fields.anonymize,
|
name: fields.anonymize,
|
||||||
type: "checkbox",
|
type: "checkbox",
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
import { BeforeDuplicate } from "payload/types";
|
|
||||||
import { Recorder } from "../../../types/collections";
|
|
||||||
|
|
||||||
export const beforeDuplicate: BeforeDuplicate<Recorder> = ({ data }) => {
|
|
||||||
return {
|
|
||||||
...data,
|
|
||||||
id: `${data.id}-copy`,
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { BeforeLoginHook } from "payload/dist/collections/config/types";
|
||||||
|
|
||||||
|
export const beforeLoginMustHaveAtLeastOneRole: BeforeLoginHook = ({ user }) => {
|
||||||
|
if (user.role.length === 0) {
|
||||||
|
throw new Error("User is not authorized to log-in.");
|
||||||
|
}
|
||||||
|
};
|
|
@ -1,59 +0,0 @@
|
||||||
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>;
|
|
||||||
|
|
||||||
export const Users = buildCollectionConfig(
|
|
||||||
{
|
|
||||||
singular: "User",
|
|
||||||
plural: "Users",
|
|
||||||
},
|
|
||||||
() => ({
|
|
||||||
auth: true,
|
|
||||||
defaultSort: fields.recorder,
|
|
||||||
admin: {
|
|
||||||
useAsTitle: fields.name,
|
|
||||||
defaultColumns: [fields.recorder, fields.name, fields.email, fields.role],
|
|
||||||
group: CollectionGroup.Administration,
|
|
||||||
},
|
|
||||||
timestamps: false,
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
type: "row",
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
name: fields.recorder,
|
|
||||||
type: "relationship",
|
|
||||||
relationTo: Recorders.slug,
|
|
||||||
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%" },
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
);
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
import React from "react";
|
||||||
|
import { styled } from "styled-components";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
route: string;
|
||||||
|
filters: { label: string; filter: string }[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const QuickFilters = ({ route, filters }: Props) => {
|
||||||
|
return (
|
||||||
|
<Container>
|
||||||
|
<div>Quick Filters:</div>
|
||||||
|
<FilterContainer>
|
||||||
|
<FilterCell label="None" to={route} />
|
||||||
|
{filters.map(({ label, filter }, index) => (
|
||||||
|
<FilterCell key={index} label={label} to={`${route}?${filter}`} />
|
||||||
|
))}
|
||||||
|
</FilterContainer>
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
type FilterProps = {
|
||||||
|
label: string;
|
||||||
|
to: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const FilterCell = ({ label, to }: FilterProps) => (
|
||||||
|
<Link className="pill pill--has-action" to={to}>
|
||||||
|
{label}
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
|
||||||
|
const Container = styled.div`
|
||||||
|
display: flex;
|
||||||
|
place-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
margin-top: -1rem;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const FilterContainer = styled.div`
|
||||||
|
display: flex;
|
||||||
|
place-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
`;
|
|
@ -2,7 +2,6 @@ export enum CollectionGroup {
|
||||||
Collections = "Collections",
|
Collections = "Collections",
|
||||||
Media = "Media",
|
Media = "Media",
|
||||||
Meta = "Meta",
|
Meta = "Meta",
|
||||||
Administration = "Administration",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum KeysTypes {
|
export enum KeysTypes {
|
||||||
|
@ -43,7 +42,12 @@ export enum LibraryItemsTextualPageOrders {
|
||||||
RightToLeft = "Right to left",
|
RightToLeft = "Right to left",
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum UserRoles {
|
export enum RecordersRoles {
|
||||||
Admin = "Admin",
|
Admin = "Admin",
|
||||||
Recorder = "Recorder",
|
Recorder = "Recorder",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum CollectionStatus {
|
||||||
|
Draft = "draft",
|
||||||
|
Published = "published",
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { ArrayField } from "payload/types";
|
||||||
|
|
||||||
|
type Props = Omit<ArrayField, "type" | "maxRows" | "minRows">;
|
||||||
|
|
||||||
|
export const optionalGroupField = ({
|
||||||
|
admin: { className = "", ...otherAdmin } = {},
|
||||||
|
...otherProps
|
||||||
|
}: Props): ArrayField => ({
|
||||||
|
...otherProps,
|
||||||
|
type: "array",
|
||||||
|
minRows: 0,
|
||||||
|
maxRows: 1,
|
||||||
|
admin: { ...otherAdmin, className: `${className} group-array` },
|
||||||
|
});
|
|
@ -1,7 +1,7 @@
|
||||||
import { ArrayField, Field } from "payload/types";
|
import { ArrayField, Field } from "payload/types";
|
||||||
import { hasDuplicates } from "../../utils/validation";
|
import { hasDuplicates } from "../../utils/validation";
|
||||||
import { isDefined, isUndefined } from "../../utils/asserts";
|
import { isDefined, isUndefined } from "../../utils/asserts";
|
||||||
import { Languages } from "../../collections/Languages";
|
import { Languages } from "../../collections/Languages/Languages";
|
||||||
import { RowLabel } from "./RowLabel";
|
import { RowLabel } from "./RowLabel";
|
||||||
import { Cell } from "./Cell";
|
import { Cell } from "./Cell";
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { BeforeDuplicate } from "payload/types";
|
||||||
|
|
||||||
|
export const beforeDuplicateAddCopyTo =
|
||||||
|
(fieldName: string): BeforeDuplicate =>
|
||||||
|
({ data }) => ({ ...data, [fieldName]: `${data[fieldName]}-copy` });
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { BeforeDuplicate } from "payload/types";
|
||||||
|
|
||||||
|
export const beforeDuplicatePiping = (hooks: BeforeDuplicate[]): BeforeDuplicate => {
|
||||||
|
return ({ data: initialData }) => hooks.reduce((data, hook) => hook({ data }), initialData);
|
||||||
|
};
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { BeforeDuplicate } from "payload/types";
|
||||||
|
import { CollectionStatus } from "../constants";
|
||||||
|
|
||||||
|
export const beforeDuplicateUnpublish: BeforeDuplicate = ({ data }) => ({
|
||||||
|
...data,
|
||||||
|
_status: CollectionStatus.Draft,
|
||||||
|
});
|
|
@ -1,7 +1,6 @@
|
||||||
import { buildConfig } from "payload/config";
|
import { buildConfig } from "payload/config";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { Users } from "./collections/Users";
|
import { Languages } from "./collections/Languages/Languages";
|
||||||
import { Languages } from "./collections/Languages";
|
|
||||||
import { Recorders } from "./collections/Recorders/Recorders";
|
import { Recorders } from "./collections/Recorders/Recorders";
|
||||||
import { Posts } from "./collections/Posts/Posts";
|
import { Posts } from "./collections/Posts/Posts";
|
||||||
import { Keys } from "./collections/Keys/Keys";
|
import { Keys } from "./collections/Keys/Keys";
|
||||||
|
@ -15,11 +14,12 @@ import { ContentThumbnails } from "./collections/ContentThumbnails/ContentThumbn
|
||||||
import { ContentFolders } from "./collections/ContentFolders/ContentFolders";
|
import { ContentFolders } from "./collections/ContentFolders/ContentFolders";
|
||||||
import { Logo } from "./components/Logo";
|
import { Logo } from "./components/Logo";
|
||||||
import { Icon } from "./components/Icon";
|
import { Icon } from "./components/Icon";
|
||||||
|
import { Currencies } from "./collections/Currencies/Currencies";
|
||||||
|
|
||||||
export default buildConfig({
|
export default buildConfig({
|
||||||
serverURL: "https://dashboard.accords-library.com",
|
serverURL: "https://dashboard.accords-library.com",
|
||||||
admin: {
|
admin: {
|
||||||
user: Users.slug,
|
user: Recorders.slug,
|
||||||
components: { graphics: { Logo, Icon } },
|
components: { graphics: { Logo, Icon } },
|
||||||
meta: {
|
meta: {
|
||||||
favicon: "/public/favicon.ico",
|
favicon: "/public/favicon.ico",
|
||||||
|
@ -39,9 +39,9 @@ export default buildConfig({
|
||||||
PostThumbnails,
|
PostThumbnails,
|
||||||
Files,
|
Files,
|
||||||
Languages,
|
Languages,
|
||||||
|
Currencies,
|
||||||
Recorders,
|
Recorders,
|
||||||
Keys,
|
Keys,
|
||||||
Users,
|
|
||||||
],
|
],
|
||||||
globals: [],
|
globals: [],
|
||||||
telemetry: false,
|
telemetry: false,
|
||||||
|
|
|
@ -45,3 +45,18 @@ html[data-theme="light"] {
|
||||||
--color-base-950: #11100b;
|
--color-base-950: #11100b;
|
||||||
--color-base-1000: #000000;
|
--color-base-1000: #000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.field-type.array-field.group-array {
|
||||||
|
.array-field__header-actions,
|
||||||
|
.collapsible__drag,
|
||||||
|
.collapsible__toggle,
|
||||||
|
.collapsible__header-wrap,
|
||||||
|
.collapsible__indicator,
|
||||||
|
.array-actions__add,
|
||||||
|
.array-actions__duplicate {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.collapsible__actions-wrap {
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -25,19 +25,18 @@ export type ContentFoldersTranslation = {
|
||||||
|
|
||||||
export interface Config {
|
export interface Config {
|
||||||
collections: {
|
collections: {
|
||||||
"library-items": LibraryItem;
|
'library-items': LibraryItem;
|
||||||
contents: Content;
|
contents: Content;
|
||||||
"content-folders": ContentFolder;
|
'content-folders': ContentFolder;
|
||||||
posts: Post;
|
posts: Post;
|
||||||
"content-thumbnails": ContentThumbnail;
|
'content-thumbnails': ContentThumbnail;
|
||||||
"library-item-thumbnails": LibraryItemThumbnail;
|
'library-item-thumbnails': LibraryItemThumbnail;
|
||||||
"recorder-thumbnails": RecorderThumbnail;
|
'recorder-thumbnails': RecorderThumbnail;
|
||||||
"post-thumbnails": PostThumbnail;
|
'post-thumbnails': PostThumbnail;
|
||||||
files: File;
|
files: File;
|
||||||
languages: Language;
|
languages: Language;
|
||||||
recorders: Recorder;
|
recorders: Recorder;
|
||||||
keys: Key;
|
keys: Key;
|
||||||
users: User;
|
|
||||||
};
|
};
|
||||||
globals: {};
|
globals: {};
|
||||||
}
|
}
|
||||||
|
@ -53,50 +52,55 @@ export interface LibraryItem {
|
||||||
digital: boolean;
|
digital: boolean;
|
||||||
downloadable: boolean;
|
downloadable: boolean;
|
||||||
size?: {
|
size?: {
|
||||||
width?: number;
|
width: number;
|
||||||
height?: number;
|
height: number;
|
||||||
thickness?: number;
|
thickness?: number;
|
||||||
};
|
id?: string;
|
||||||
itemType?: "Textual" | "Audio" | "Video" | "Game" | "Other";
|
}[];
|
||||||
|
price?: {
|
||||||
|
priceAmount: number;
|
||||||
|
id?: string;
|
||||||
|
}[];
|
||||||
|
itemType?: 'Textual' | 'Audio' | 'Video' | 'Game' | 'Other';
|
||||||
textual?: {
|
textual?: {
|
||||||
subtype?:
|
subtype?:
|
||||||
| {
|
| {
|
||||||
value: string;
|
value: string;
|
||||||
relationTo: "keys";
|
relationTo: 'keys';
|
||||||
}[]
|
}[]
|
||||||
| {
|
| {
|
||||||
value: Key;
|
value: Key;
|
||||||
relationTo: "keys";
|
relationTo: 'keys';
|
||||||
}[];
|
}[];
|
||||||
languages?:
|
languages?:
|
||||||
| {
|
| {
|
||||||
value: string;
|
value: string;
|
||||||
relationTo: "languages";
|
relationTo: 'languages';
|
||||||
}[]
|
}[]
|
||||||
| {
|
| {
|
||||||
value: Language;
|
value: Language;
|
||||||
relationTo: "languages";
|
relationTo: 'languages';
|
||||||
}[];
|
}[];
|
||||||
pageCount?: number;
|
pageCount?: number;
|
||||||
bindingType?: "Paperback" | "Hardcover";
|
bindingType?: 'Paperback' | 'Hardcover';
|
||||||
pageOrder?: "LeftToRight" | "RightToLeft";
|
pageOrder?: 'LeftToRight' | 'RightToLeft';
|
||||||
};
|
};
|
||||||
audio?: {
|
audio?: {
|
||||||
audioSubtype?:
|
audioSubtype?:
|
||||||
| {
|
| {
|
||||||
value: string;
|
value: string;
|
||||||
relationTo: "keys";
|
relationTo: 'keys';
|
||||||
}[]
|
}[]
|
||||||
| {
|
| {
|
||||||
value: Key;
|
value: Key;
|
||||||
relationTo: "keys";
|
relationTo: 'keys';
|
||||||
}[];
|
}[];
|
||||||
};
|
};
|
||||||
releaseDate?: string;
|
releaseDate?: string;
|
||||||
lastModifiedBy: string | User;
|
lastModifiedBy: string | Recorder;
|
||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
_status?: "draft" | "published";
|
_status?: 'draft' | 'published';
|
||||||
}
|
}
|
||||||
export interface LibraryItemThumbnail {
|
export interface LibraryItemThumbnail {
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -139,27 +143,30 @@ export interface Key {
|
||||||
id: string;
|
id: string;
|
||||||
slug: string;
|
slug: string;
|
||||||
type:
|
type:
|
||||||
| "Contents"
|
| 'Contents'
|
||||||
| "LibraryAudio"
|
| 'LibraryAudio'
|
||||||
| "LibraryVideo"
|
| 'LibraryVideo'
|
||||||
| "LibraryTextual"
|
| 'LibraryTextual'
|
||||||
| "LibraryGroup"
|
| 'LibraryGroup'
|
||||||
| "Library"
|
| 'Library'
|
||||||
| "Weapons"
|
| 'Weapons'
|
||||||
| "GamePlatforms"
|
| 'GamePlatforms'
|
||||||
| "Categories"
|
| 'Categories'
|
||||||
| "Wordings";
|
| 'Wordings';
|
||||||
translations?: CategoryTranslations;
|
translations?: CategoryTranslations;
|
||||||
}
|
}
|
||||||
export interface Language {
|
export interface Language {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
export interface User {
|
export interface Recorder {
|
||||||
id: string;
|
id: string;
|
||||||
recorder: string | Recorder;
|
username: string;
|
||||||
name: string;
|
avatar?: string | RecorderThumbnail;
|
||||||
role: ("Admin" | "Recorder")[];
|
languages?: string[] | Language[];
|
||||||
|
biographies?: RecorderBiographies;
|
||||||
|
role?: ('Admin' | 'Recorder')[];
|
||||||
|
anonymize: boolean;
|
||||||
email: string;
|
email: string;
|
||||||
resetPasswordToken?: string;
|
resetPasswordToken?: string;
|
||||||
resetPasswordExpiration?: string;
|
resetPasswordExpiration?: string;
|
||||||
|
@ -169,14 +176,6 @@ export interface User {
|
||||||
lockUntil?: string;
|
lockUntil?: string;
|
||||||
password?: string;
|
password?: string;
|
||||||
}
|
}
|
||||||
export interface Recorder {
|
|
||||||
id: string;
|
|
||||||
username: string;
|
|
||||||
avatar?: string | RecorderThumbnail;
|
|
||||||
languages?: string[] | Language[];
|
|
||||||
biographies?: RecorderBiographies;
|
|
||||||
anonymize: boolean;
|
|
||||||
}
|
|
||||||
export interface RecorderThumbnail {
|
export interface RecorderThumbnail {
|
||||||
id: string;
|
id: string;
|
||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
|
@ -213,15 +212,15 @@ export interface Content {
|
||||||
categories?:
|
categories?:
|
||||||
| {
|
| {
|
||||||
value: string;
|
value: string;
|
||||||
relationTo: "keys";
|
relationTo: 'keys';
|
||||||
}[]
|
}[]
|
||||||
| {
|
| {
|
||||||
value: Key;
|
value: Key;
|
||||||
relationTo: "keys";
|
relationTo: 'keys';
|
||||||
}[];
|
}[];
|
||||||
type?: {
|
type?: {
|
||||||
value: string | Key;
|
value: string | Key;
|
||||||
relationTo: "keys";
|
relationTo: 'keys';
|
||||||
};
|
};
|
||||||
translations: {
|
translations: {
|
||||||
language: string | Language;
|
language: string | Language;
|
||||||
|
@ -240,10 +239,10 @@ export interface Content {
|
||||||
audio?: string | File;
|
audio?: string | File;
|
||||||
id?: string;
|
id?: string;
|
||||||
}[];
|
}[];
|
||||||
lastModifiedBy: string | User;
|
lastModifiedBy: string | Recorder;
|
||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
_status?: "draft" | "published";
|
_status?: 'draft' | 'published';
|
||||||
}
|
}
|
||||||
export interface ContentThumbnail {
|
export interface ContentThumbnail {
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -280,25 +279,19 @@ export interface TextBlock {
|
||||||
}[];
|
}[];
|
||||||
id?: string;
|
id?: string;
|
||||||
blockName?: string;
|
blockName?: string;
|
||||||
blockType: "textBlock";
|
blockType: 'textBlock';
|
||||||
}
|
}
|
||||||
export interface Section {
|
export interface Section {
|
||||||
content?: (Section_Section | Section_Tabs | TranscriptBlock | QuoteBlock | TextBlock)[];
|
content?: (Section_Section | Section_Tabs | TranscriptBlock | QuoteBlock | TextBlock)[];
|
||||||
id?: string;
|
id?: string;
|
||||||
blockName?: string;
|
blockName?: string;
|
||||||
blockType: "section";
|
blockType: 'section';
|
||||||
}
|
}
|
||||||
export interface Section_Section {
|
export interface Section_Section {
|
||||||
content?: (
|
content?: (Section_Section_Section | Section_Section_Tabs | TranscriptBlock | QuoteBlock | TextBlock)[];
|
||||||
| Section_Section_Section
|
|
||||||
| Section_Section_Tabs
|
|
||||||
| TranscriptBlock
|
|
||||||
| QuoteBlock
|
|
||||||
| TextBlock
|
|
||||||
)[];
|
|
||||||
id?: string;
|
id?: string;
|
||||||
blockName?: string;
|
blockName?: string;
|
||||||
blockType: "section";
|
blockType: 'section';
|
||||||
}
|
}
|
||||||
export interface Section_Section_Section {
|
export interface Section_Section_Section {
|
||||||
content?: (
|
content?: (
|
||||||
|
@ -310,25 +303,25 @@ export interface Section_Section_Section {
|
||||||
)[];
|
)[];
|
||||||
id?: string;
|
id?: string;
|
||||||
blockName?: string;
|
blockName?: string;
|
||||||
blockType: "section";
|
blockType: 'section';
|
||||||
}
|
}
|
||||||
export interface Section_Section_Section_Section {
|
export interface Section_Section_Section_Section {
|
||||||
content?: (Section_Section_Section_Section_Section | TranscriptBlock | QuoteBlock | TextBlock)[];
|
content?: (Section_Section_Section_Section_Section | TranscriptBlock | QuoteBlock | TextBlock)[];
|
||||||
id?: string;
|
id?: string;
|
||||||
blockName?: string;
|
blockName?: string;
|
||||||
blockType: "section";
|
blockType: 'section';
|
||||||
}
|
}
|
||||||
export interface Section_Section_Section_Section_Section {
|
export interface Section_Section_Section_Section_Section {
|
||||||
content?: (TranscriptBlock | QuoteBlock | TextBlock)[];
|
content?: (TranscriptBlock | QuoteBlock | TextBlock)[];
|
||||||
id?: string;
|
id?: string;
|
||||||
blockName?: string;
|
blockName?: string;
|
||||||
blockType: "section";
|
blockType: 'section';
|
||||||
}
|
}
|
||||||
export interface TranscriptBlock {
|
export interface TranscriptBlock {
|
||||||
lines: (LineBlock | CueBlock)[];
|
lines: (LineBlock | CueBlock)[];
|
||||||
id?: string;
|
id?: string;
|
||||||
blockName?: string;
|
blockName?: string;
|
||||||
blockType: "transcriptBlock";
|
blockType: 'transcriptBlock';
|
||||||
}
|
}
|
||||||
export interface LineBlock {
|
export interface LineBlock {
|
||||||
content: {
|
content: {
|
||||||
|
@ -336,13 +329,13 @@ export interface LineBlock {
|
||||||
}[];
|
}[];
|
||||||
id?: string;
|
id?: string;
|
||||||
blockName?: string;
|
blockName?: string;
|
||||||
blockType: "lineBlock";
|
blockType: 'lineBlock';
|
||||||
}
|
}
|
||||||
export interface CueBlock {
|
export interface CueBlock {
|
||||||
content: string;
|
content: string;
|
||||||
id?: string;
|
id?: string;
|
||||||
blockName?: string;
|
blockName?: string;
|
||||||
blockType: "cueBlock";
|
blockType: 'cueBlock';
|
||||||
}
|
}
|
||||||
export interface QuoteBlock {
|
export interface QuoteBlock {
|
||||||
from: string;
|
from: string;
|
||||||
|
@ -351,120 +344,120 @@ export interface QuoteBlock {
|
||||||
}[];
|
}[];
|
||||||
id?: string;
|
id?: string;
|
||||||
blockName?: string;
|
blockName?: string;
|
||||||
blockType: "quoteBlock";
|
blockType: 'quoteBlock';
|
||||||
}
|
}
|
||||||
export interface Section_Section_Section_Tabs {
|
export interface Section_Section_Section_Tabs {
|
||||||
tabs?: Section_Section_Section_Tabs_Tab[];
|
tabs?: Section_Section_Section_Tabs_Tab[];
|
||||||
id?: string;
|
id?: string;
|
||||||
blockName?: string;
|
blockName?: string;
|
||||||
blockType: "tabs";
|
blockType: 'tabs';
|
||||||
}
|
}
|
||||||
export interface Section_Section_Section_Tabs_Tab {
|
export interface Section_Section_Section_Tabs_Tab {
|
||||||
content?: (Section_Section_Section_Tabs_Tab_Section | TranscriptBlock | QuoteBlock | TextBlock)[];
|
content?: (Section_Section_Section_Tabs_Tab_Section | TranscriptBlock | QuoteBlock | TextBlock)[];
|
||||||
id?: string;
|
id?: string;
|
||||||
blockName?: string;
|
blockName?: string;
|
||||||
blockType: "tab";
|
blockType: 'tab';
|
||||||
}
|
}
|
||||||
export interface Section_Section_Section_Tabs_Tab_Section {
|
export interface Section_Section_Section_Tabs_Tab_Section {
|
||||||
content?: (TranscriptBlock | QuoteBlock | TextBlock)[];
|
content?: (TranscriptBlock | QuoteBlock | TextBlock)[];
|
||||||
id?: string;
|
id?: string;
|
||||||
blockName?: string;
|
blockName?: string;
|
||||||
blockType: "section";
|
blockType: 'section';
|
||||||
}
|
}
|
||||||
export interface Section_Section_Tabs {
|
export interface Section_Section_Tabs {
|
||||||
tabs?: Section_Section_Tabs_Tab[];
|
tabs?: Section_Section_Tabs_Tab[];
|
||||||
id?: string;
|
id?: string;
|
||||||
blockName?: string;
|
blockName?: string;
|
||||||
blockType: "tabs";
|
blockType: 'tabs';
|
||||||
}
|
}
|
||||||
export interface Section_Section_Tabs_Tab {
|
export interface Section_Section_Tabs_Tab {
|
||||||
content?: (Section_Section_Tabs_Tab_Section | TranscriptBlock | QuoteBlock | TextBlock)[];
|
content?: (Section_Section_Tabs_Tab_Section | TranscriptBlock | QuoteBlock | TextBlock)[];
|
||||||
id?: string;
|
id?: string;
|
||||||
blockName?: string;
|
blockName?: string;
|
||||||
blockType: "tab";
|
blockType: 'tab';
|
||||||
}
|
}
|
||||||
export interface Section_Section_Tabs_Tab_Section {
|
export interface Section_Section_Tabs_Tab_Section {
|
||||||
content?: (Section_Section_Tabs_Tab_Section_Section | TranscriptBlock | QuoteBlock | TextBlock)[];
|
content?: (Section_Section_Tabs_Tab_Section_Section | TranscriptBlock | QuoteBlock | TextBlock)[];
|
||||||
id?: string;
|
id?: string;
|
||||||
blockName?: string;
|
blockName?: string;
|
||||||
blockType: "section";
|
blockType: 'section';
|
||||||
}
|
}
|
||||||
export interface Section_Section_Tabs_Tab_Section_Section {
|
export interface Section_Section_Tabs_Tab_Section_Section {
|
||||||
content?: (TranscriptBlock | QuoteBlock | TextBlock)[];
|
content?: (TranscriptBlock | QuoteBlock | TextBlock)[];
|
||||||
id?: string;
|
id?: string;
|
||||||
blockName?: string;
|
blockName?: string;
|
||||||
blockType: "section";
|
blockType: 'section';
|
||||||
}
|
}
|
||||||
export interface Section_Tabs {
|
export interface Section_Tabs {
|
||||||
tabs?: Section_Tabs_Tab[];
|
tabs?: Section_Tabs_Tab[];
|
||||||
id?: string;
|
id?: string;
|
||||||
blockName?: string;
|
blockName?: string;
|
||||||
blockType: "tabs";
|
blockType: 'tabs';
|
||||||
}
|
}
|
||||||
export interface Section_Tabs_Tab {
|
export interface Section_Tabs_Tab {
|
||||||
content?: (Section_Tabs_Tab_Section | TranscriptBlock | QuoteBlock | TextBlock)[];
|
content?: (Section_Tabs_Tab_Section | TranscriptBlock | QuoteBlock | TextBlock)[];
|
||||||
id?: string;
|
id?: string;
|
||||||
blockName?: string;
|
blockName?: string;
|
||||||
blockType: "tab";
|
blockType: 'tab';
|
||||||
}
|
}
|
||||||
export interface Section_Tabs_Tab_Section {
|
export interface Section_Tabs_Tab_Section {
|
||||||
content?: (Section_Tabs_Tab_Section_Section | TranscriptBlock | QuoteBlock | TextBlock)[];
|
content?: (Section_Tabs_Tab_Section_Section | TranscriptBlock | QuoteBlock | TextBlock)[];
|
||||||
id?: string;
|
id?: string;
|
||||||
blockName?: string;
|
blockName?: string;
|
||||||
blockType: "section";
|
blockType: 'section';
|
||||||
}
|
}
|
||||||
export interface Section_Tabs_Tab_Section_Section {
|
export interface Section_Tabs_Tab_Section_Section {
|
||||||
content?: (Section_Tabs_Tab_Section_Section_Section | TranscriptBlock | QuoteBlock | TextBlock)[];
|
content?: (Section_Tabs_Tab_Section_Section_Section | TranscriptBlock | QuoteBlock | TextBlock)[];
|
||||||
id?: string;
|
id?: string;
|
||||||
blockName?: string;
|
blockName?: string;
|
||||||
blockType: "section";
|
blockType: 'section';
|
||||||
}
|
}
|
||||||
export interface Section_Tabs_Tab_Section_Section_Section {
|
export interface Section_Tabs_Tab_Section_Section_Section {
|
||||||
content?: (TranscriptBlock | QuoteBlock | TextBlock)[];
|
content?: (TranscriptBlock | QuoteBlock | TextBlock)[];
|
||||||
id?: string;
|
id?: string;
|
||||||
blockName?: string;
|
blockName?: string;
|
||||||
blockType: "section";
|
blockType: 'section';
|
||||||
}
|
}
|
||||||
export interface Tabs {
|
export interface Tabs {
|
||||||
tabs?: Tabs_Tab[];
|
tabs?: Tabs_Tab[];
|
||||||
id?: string;
|
id?: string;
|
||||||
blockName?: string;
|
blockName?: string;
|
||||||
blockType: "tabs";
|
blockType: 'tabs';
|
||||||
}
|
}
|
||||||
export interface Tabs_Tab {
|
export interface Tabs_Tab {
|
||||||
content?: (Tabs_Tab_Section | TranscriptBlock | QuoteBlock | TextBlock)[];
|
content?: (Tabs_Tab_Section | TranscriptBlock | QuoteBlock | TextBlock)[];
|
||||||
id?: string;
|
id?: string;
|
||||||
blockName?: string;
|
blockName?: string;
|
||||||
blockType: "tab";
|
blockType: 'tab';
|
||||||
}
|
}
|
||||||
export interface Tabs_Tab_Section {
|
export interface Tabs_Tab_Section {
|
||||||
content?: (Tabs_Tab_Section_Section | TranscriptBlock | QuoteBlock | TextBlock)[];
|
content?: (Tabs_Tab_Section_Section | TranscriptBlock | QuoteBlock | TextBlock)[];
|
||||||
id?: string;
|
id?: string;
|
||||||
blockName?: string;
|
blockName?: string;
|
||||||
blockType: "section";
|
blockType: 'section';
|
||||||
}
|
}
|
||||||
export interface Tabs_Tab_Section_Section {
|
export interface Tabs_Tab_Section_Section {
|
||||||
content?: (Tabs_Tab_Section_Section_Section | TranscriptBlock | QuoteBlock | TextBlock)[];
|
content?: (Tabs_Tab_Section_Section_Section | TranscriptBlock | QuoteBlock | TextBlock)[];
|
||||||
id?: string;
|
id?: string;
|
||||||
blockName?: string;
|
blockName?: string;
|
||||||
blockType: "section";
|
blockType: 'section';
|
||||||
}
|
}
|
||||||
export interface Tabs_Tab_Section_Section_Section {
|
export interface Tabs_Tab_Section_Section_Section {
|
||||||
content?: (Tabs_Tab_Section_Section_Section_Section | TranscriptBlock | QuoteBlock | TextBlock)[];
|
content?: (Tabs_Tab_Section_Section_Section_Section | TranscriptBlock | QuoteBlock | TextBlock)[];
|
||||||
id?: string;
|
id?: string;
|
||||||
blockName?: string;
|
blockName?: string;
|
||||||
blockType: "section";
|
blockType: 'section';
|
||||||
}
|
}
|
||||||
export interface Tabs_Tab_Section_Section_Section_Section {
|
export interface Tabs_Tab_Section_Section_Section_Section {
|
||||||
content?: (TranscriptBlock | QuoteBlock | TextBlock)[];
|
content?: (TranscriptBlock | QuoteBlock | TextBlock)[];
|
||||||
id?: string;
|
id?: string;
|
||||||
blockName?: string;
|
blockName?: string;
|
||||||
blockType: "section";
|
blockType: 'section';
|
||||||
}
|
}
|
||||||
export interface File {
|
export interface File {
|
||||||
id: string;
|
id: string;
|
||||||
filename: string;
|
filename: string;
|
||||||
type: "LibraryScans" | "LibrarySoundtracks" | "ContentVideo" | "ContentAudio";
|
type: 'LibraryScans' | 'LibrarySoundtracks' | 'ContentVideo' | 'ContentAudio';
|
||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
}
|
}
|
||||||
|
@ -475,20 +468,20 @@ export interface ContentFolder {
|
||||||
subfolders?:
|
subfolders?:
|
||||||
| {
|
| {
|
||||||
value: string;
|
value: string;
|
||||||
relationTo: "content-folders";
|
relationTo: 'content-folders';
|
||||||
}[]
|
}[]
|
||||||
| {
|
| {
|
||||||
value: ContentFolder;
|
value: ContentFolder;
|
||||||
relationTo: "content-folders";
|
relationTo: 'content-folders';
|
||||||
}[];
|
}[];
|
||||||
contents?:
|
contents?:
|
||||||
| {
|
| {
|
||||||
value: string;
|
value: string;
|
||||||
relationTo: "contents";
|
relationTo: 'contents';
|
||||||
}[]
|
}[]
|
||||||
| {
|
| {
|
||||||
value: Content;
|
value: Content;
|
||||||
relationTo: "contents";
|
relationTo: 'contents';
|
||||||
}[];
|
}[];
|
||||||
}
|
}
|
||||||
export interface Post {
|
export interface Post {
|
||||||
|
@ -498,20 +491,20 @@ export interface Post {
|
||||||
authors:
|
authors:
|
||||||
| {
|
| {
|
||||||
value: string;
|
value: string;
|
||||||
relationTo: "recorders";
|
relationTo: 'recorders';
|
||||||
}[]
|
}[]
|
||||||
| {
|
| {
|
||||||
value: Recorder;
|
value: Recorder;
|
||||||
relationTo: "recorders";
|
relationTo: 'recorders';
|
||||||
}[];
|
}[];
|
||||||
categories?:
|
categories?:
|
||||||
| {
|
| {
|
||||||
value: string;
|
value: string;
|
||||||
relationTo: "keys";
|
relationTo: 'keys';
|
||||||
}[]
|
}[]
|
||||||
| {
|
| {
|
||||||
value: Key;
|
value: Key;
|
||||||
relationTo: "keys";
|
relationTo: 'keys';
|
||||||
}[];
|
}[];
|
||||||
translations: {
|
translations: {
|
||||||
language: string | Language;
|
language: string | Language;
|
||||||
|
@ -527,10 +520,10 @@ export interface Post {
|
||||||
}[];
|
}[];
|
||||||
publishedDate: string;
|
publishedDate: string;
|
||||||
hidden?: boolean;
|
hidden?: boolean;
|
||||||
lastModifiedBy: string | User;
|
lastModifiedBy: string | Recorder;
|
||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
_status?: "draft" | "published";
|
_status?: 'draft' | 'published';
|
||||||
}
|
}
|
||||||
export interface PostThumbnail {
|
export interface PostThumbnail {
|
||||||
id: string;
|
id: string;
|
||||||
|
|
|
@ -1,29 +1,26 @@
|
||||||
import { CollectionBeforeChangeHook, CollectionConfig, RelationshipField } from "payload/types";
|
import { CollectionBeforeChangeHook, CollectionConfig, RelationshipField } from "payload/types";
|
||||||
import { Users } from "../collections/Users";
|
|
||||||
import {
|
import {
|
||||||
BuildCollectionConfig,
|
BuildCollectionConfig,
|
||||||
GenerationFunctionProps,
|
GenerationFunctionProps,
|
||||||
buildCollectionConfig,
|
buildCollectionConfig,
|
||||||
} from "./collectionConfig";
|
} from "./collectionConfig";
|
||||||
|
import { Recorders } from "../collections/Recorders/Recorders";
|
||||||
|
|
||||||
const fields = { lastModifiedBy: "lastModifiedBy" };
|
const fields = { lastModifiedBy: "lastModifiedBy" };
|
||||||
|
|
||||||
const beforeChangeLastModifiedBy: CollectionBeforeChangeHook = async ({
|
const beforeChangeLastModifiedBy: CollectionBeforeChangeHook = async ({
|
||||||
data: { updatedBy, ...data },
|
data: { updatedBy, ...data },
|
||||||
req,
|
req,
|
||||||
}) => {
|
}) => ({
|
||||||
console.log(data, req.user);
|
...data,
|
||||||
return {
|
[fields.lastModifiedBy]: req.user.id,
|
||||||
...data,
|
});
|
||||||
[fields.lastModifiedBy]: req.user.id,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const lastModifiedByField = (): RelationshipField => ({
|
const lastModifiedByField = (): RelationshipField => ({
|
||||||
name: fields.lastModifiedBy,
|
name: fields.lastModifiedBy,
|
||||||
type: "relationship",
|
type: "relationship",
|
||||||
required: true,
|
required: true,
|
||||||
relationTo: Users.slug,
|
relationTo: Recorders.slug,
|
||||||
admin: { readOnly: true, position: "sidebar" },
|
admin: { readOnly: true, position: "sidebar" },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue