Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions apps/cms/src/app/(payload)/admin/importMap.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { TenantField as TenantField_1d0591e3cf4f332c83a86da13a0de59a } from '@payloadcms/plugin-multi-tenant/client';
import { TenantSelector as TenantSelector_1d0591e3cf4f332c83a86da13a0de59a } from '@payloadcms/plugin-multi-tenant/client';
import { GlobalViewRedirect as GlobalViewRedirect_d6d5f193a167989e2ee7d14202901e62 } from '@payloadcms/plugin-multi-tenant/rsc';
import { TenantSelectionProvider as TenantSelectionProvider_d6d5f193a167989e2ee7d14202901e62 } from '@payloadcms/plugin-multi-tenant/rsc';
import { OverviewComponent as OverviewComponent_a8a977ebc872c5d5ea7ee689724c0860 } from '@payloadcms/plugin-seo/client';
import { MetaTitleComponent as MetaTitleComponent_a8a977ebc872c5d5ea7ee689724c0860 } from '@payloadcms/plugin-seo/client';
import { MetaImageComponent as MetaImageComponent_a8a977ebc872c5d5ea7ee689724c0860 } from '@payloadcms/plugin-seo/client';
import { MetaDescriptionComponent as MetaDescriptionComponent_a8a977ebc872c5d5ea7ee689724c0860 } from '@payloadcms/plugin-seo/client';
import { PreviewComponent as PreviewComponent_a8a977ebc872c5d5ea7ee689724c0860 } from '@payloadcms/plugin-seo/client';
import { HeadingFeatureClient as HeadingFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client';
import { FixedToolbarFeatureClient as FixedToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client';
import { InlineToolbarFeatureClient as InlineToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client';
import { HorizontalRuleFeatureClient as HorizontalRuleFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client';
Expand All @@ -24,7 +26,6 @@ import { StrikethroughFeatureClient as StrikethroughFeatureClient_e70f5e05f09f93
import { UnderlineFeatureClient as UnderlineFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client';
import { BoldFeatureClient as BoldFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client';
import { ItalicFeatureClient as ItalicFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client';
import { HeadingFeatureClient as HeadingFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client';
import { BlocksFeatureClient as BlocksFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client';
import { RscEntryLexicalField as RscEntryLexicalField_44fe37237e0ebf4470c9990d8cb7b07e } from '@payloadcms/richtext-lexical/rsc';
import { RscEntryLexicalCell as RscEntryLexicalCell_44fe37237e0ebf4470c9990d8cb7b07e } from '@payloadcms/richtext-lexical/rsc';
Expand All @@ -33,8 +34,9 @@ import { S3ClientUploadHandler as S3ClientUploadHandler_f97aa6c64367fa259c5bc056
import { default as default_83b0dfab156f3636ed94b94854d15ad5 } from '@codeware/app-cms/ui/components/RedirectNotifier';
import { default as default_7925a79d2af6389df70d2dd269ffbfbb } from '@codeware/app-cms/ui/components/VerifyTenantDomain';
import { default as default_06af4458abd1296f9d6bccce90425927 } from '@codeware/app-cms/ui/fields/code/Code.client';
import { default as default_52b6c8f3cfeb54cb642a26fe54c075b9 } from '@codeware/apps/cms/components/ArrayRowLabel';
import { default as default_42ab7a6f795fd44e8c166a2bb6b2adc0 } from '@codeware/apps/cms/components/Logo.client';
import { default as default_d497a38447405736d600359900364450 } from '@codeware/apps/cms/components/NavigationArrayRowLabel';
import { default as default_dec1059b7bb8eb8da3a9f0fc400fffbd } from '@codeware/apps/cms/components/TenantsArrayRowLabel';

export const importMap = {
'@payloadcms/plugin-multi-tenant/client#TenantField':
Expand Down Expand Up @@ -81,6 +83,8 @@ export const importMap = {
BoldFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
'@payloadcms/richtext-lexical/client#ItalicFeatureClient':
ItalicFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
'@codeware/apps/cms/components/NavigationArrayRowLabel#default':
default_d497a38447405736d600359900364450,
'@payloadcms/plugin-seo/client#OverviewComponent':
OverviewComponent_a8a977ebc872c5d5ea7ee689724c0860,
'@payloadcms/plugin-seo/client#MetaTitleComponent':
Expand All @@ -95,10 +99,12 @@ export const importMap = {
BlocksFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
'@codeware/app-cms/ui/fields/code/Code.client#default':
default_06af4458abd1296f9d6bccce90425927,
'@codeware/apps/cms/components/ArrayRowLabel#default':
default_52b6c8f3cfeb54cb642a26fe54c075b9,
'@codeware/apps/cms/components/TenantsArrayRowLabel#default':
default_dec1059b7bb8eb8da3a9f0fc400fffbd,
'@codeware/apps/cms/components/Logo.client#default':
default_42ab7a6f795fd44e8c166a2bb6b2adc0,
'@payloadcms/plugin-multi-tenant/rsc#GlobalViewRedirect':
GlobalViewRedirect_d6d5f193a167989e2ee7d14202901e62,
'@codeware/app-cms/ui/components/VerifyTenantDomain#default':
default_7925a79d2af6389df70d2dd269ffbfbb,
'@codeware/app-cms/ui/components/RedirectNotifier#default':
Expand Down
2 changes: 2 additions & 0 deletions apps/cms/src/collections/categories/categories.collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { CollectionConfig } from 'payload';
import { getEnv } from '@codeware/app-cms/feature/env-loader';
import { slugField } from '@codeware/app-cms/ui/fields';
import { verifyApiKeyAccess } from '@codeware/app-cms/util/access';
import { adminGroups } from '@codeware/app-cms/util/definitions';

const env = getEnv();

Expand All @@ -12,6 +13,7 @@ const env = getEnv();
const categories: CollectionConfig = {
slug: 'categories',
admin: {
group: adminGroups.content,
defaultColumns: ['name', 'slug', 'tenant'],
useAsTitle: 'name'
},
Expand Down
3 changes: 3 additions & 0 deletions apps/cms/src/collections/media/media.collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { fileURLToPath } from 'url';

import type { CollectionConfig } from 'payload';

import { adminGroups } from '@codeware/app-cms/util/definitions';

const filename = fileURLToPath(import.meta.url);
const dirname = path.dirname(filename);

Expand All @@ -12,6 +14,7 @@ const dirname = path.dirname(filename);
const media: CollectionConfig = {
slug: 'media',
admin: {
group: adminGroups.fileArea,
defaultColumns: ['filename', 'mimeType', 'tenant', 'createdAt'],
description: {
en: 'Media files currently only support images and can be used in posts and pages.',
Expand Down
95 changes: 95 additions & 0 deletions apps/cms/src/collections/navigation/navigation.collection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import type { CollectionConfig, Condition } from 'payload';

import { getEnv } from '@codeware/app-cms/feature/env-loader';
import {
systemUserOrTenantAdminAccess,
verifyApiKeyAccess
} from '@codeware/app-cms/util/access';
import { adminGroups } from '@codeware/app-cms/util/definitions';
import type { Navigation } from '@codeware/shared/util/payload-types';

const env = getEnv();

/**
* Whether a custom label source is selected.
*/
const isCustomLabelSource: Condition<
Navigation,
NonNullable<Navigation['items']>[number]
> = (_, siblingData) => siblingData.labelSource === 'custom';

/**
* Navigation collection.
*/
const navigation: CollectionConfig = {
slug: 'navigation',
admin: {
group: adminGroups.settings
},
access: {
read: verifyApiKeyAccess({ secret: env.SIGNATURE_SECRET }),
update: systemUserOrTenantAdminAccess
},
labels: {
singular: { en: 'Navigation', sv: 'Navigation' },
plural: { en: 'Navigation', sv: 'Navigation' }
},
fields: [
{
name: 'items',
type: 'array',
label: { en: 'Navigation Tree', sv: 'Navigationsträd' },
fields: [
{
name: 'reference',
type: 'relationship',
label: {
en: 'Navigate to document',
sv: 'Navigera till dokument'
},
relationTo: ['pages', 'posts'],
required: true
},
{
name: 'labelSource',
type: 'radio',
label: false,
admin: {
layout: 'horizontal'
},
defaultValue: 'document',
options: [
{
label: {
en: 'Use document name as link label',
sv: 'Använd dokumentets namn som länktext'
},
value: 'document'
},
{
label: { en: 'Custom link label', sv: 'Anpassad länktext' },
value: 'custom'
}
]
},
{
name: 'customLabel',
type: 'text',
label: { en: 'Link label', sv: 'Länktext' },
admin: {
condition: isCustomLabelSource
},
required: true
}
],
admin: {
initCollapsed: true,
components: {
RowLabel: '@codeware/apps/cms/components/NavigationArrayRowLabel'
}
}
}
]
};

export default navigation;
2 changes: 2 additions & 0 deletions apps/cms/src/collections/pages/pages.collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { getEnv } from '@codeware/app-cms/feature/env-loader';
import { slugField } from '@codeware/app-cms/ui/fields';
import { seoTab } from '@codeware/app-cms/ui/tabs';
import { verifyApiKeyAccess } from '@codeware/app-cms/util/access';
import { adminGroups } from '@codeware/app-cms/util/definitions';
import { populatePublishedAtHook } from '@codeware/app-cms/util/hooks';

const env = getEnv();
Expand All @@ -14,6 +15,7 @@ const env = getEnv();
const pages: CollectionConfig<'pages'> = {
slug: 'pages',
admin: {
group: adminGroups.content,
defaultColumns: ['name', 'slug', 'tenant', 'updatedAt'],
useAsTitle: 'name',
description: {
Expand Down
2 changes: 2 additions & 0 deletions apps/cms/src/collections/posts/posts.collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { getEnv } from '@codeware/app-cms/feature/env-loader';
import { slugField } from '@codeware/app-cms/ui/fields';
import { seoTab } from '@codeware/app-cms/ui/tabs';
import { verifyApiKeyAccess } from '@codeware/app-cms/util/access';
import { adminGroups } from '@codeware/app-cms/util/definitions';
import { filterByTenantScope } from '@codeware/app-cms/util/filters';

import { updatePublishedAtHook } from './hooks/update-published-at.hook';
Expand All @@ -19,6 +20,7 @@ const env = getEnv();
const posts: CollectionConfig<'posts'> = {
slug: 'posts',
admin: {
group: adminGroups.content,
defaultColumns: ['title', 'tenant', 'updatedAt'],
useAsTitle: 'title',
description: {
Expand Down
64 changes: 64 additions & 0 deletions apps/cms/src/collections/site-settings/site-settings.collection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import type { CollectionConfig } from 'payload';

import { getEnv } from '@codeware/app-cms/feature/env-loader';
import {
systemUserOrTenantAdminAccess,
verifyApiKeyAccess
} from '@codeware/app-cms/util/access';
import { adminGroups } from '@codeware/app-cms/util/definitions';

const env = getEnv();

/**
* Site settings collection.
*/
const siteSettings: CollectionConfig = {
slug: 'site-settings',
admin: {
group: adminGroups.settings
},
access: {
read: verifyApiKeyAccess({
secret: env.SIGNATURE_SECRET
}),
update: systemUserOrTenantAdminAccess
},
labels: {
singular: { en: 'Site Settings', sv: 'Webbplatsinställningar' },
plural: { en: 'Site Settings', sv: 'Webbplatsinställningar' }
},
fields: [
{
type: 'tabs',
tabs: [
{
name: 'general',
fields: [
{
name: 'appName',
type: 'text',
label: { en: 'Application name', sv: 'Namnet på applikationen' },
required: true
},
{
name: 'landingPage',
type: 'relationship',
relationTo: 'pages',
label: { en: 'Landing page', sv: 'Startsida' },
admin: {
description: {
en: 'The page that will be used as the landing page for the application.',
sv: 'Sidan som kommer att användas som startsida för applikationen.'
}
},
index: true,
required: true
}
]
}
]
}
]
};

export default siteSettings;
3 changes: 2 additions & 1 deletion apps/cms/src/collections/tenants/tenants.collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
authenticatedAccess,
systemUserAccess
} from '@codeware/app-cms/util/access';
import { hasRole } from '@codeware/app-cms/util/misc';
import { adminGroups } from '@codeware/app-cms/util/definitions';

import { enforceApiKeyHook } from './hooks/enforce-api-key.hook';

Expand All @@ -28,6 +28,7 @@ const tenants: CollectionConfig = {
beforeChange: [enforceApiKeyHook]
},
admin: {
group: adminGroups.settings,
useAsTitle: 'name',
description: {
en: 'A workspace is like an organization or a company and is often called a "tenant". The content is scoped to the members of the workspace.',
Expand Down
4 changes: 2 additions & 2 deletions apps/cms/src/collections/users/fields/tenants-array.field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export const tenantsArrayField = (): Field => {
plural: { en: 'Workspaces', sv: 'Arbetsytor' }
},
access: {
create: systemUserAccess,
create: systemUserOrTenantAdminAccess,
update: systemUserOrTenantAdminAccess
},
admin: {
Expand All @@ -70,7 +70,7 @@ export const tenantsArrayField = (): Field => {
// Hide the top level label since we have a similar label in the tab
Label: undefined,
// Custom tenant/role header
RowLabel: '@codeware/apps/cms/components/ArrayRowLabel'
RowLabel: '@codeware/apps/cms/components/TenantsArrayRowLabel'
},
initCollapsed: true
}
Expand Down
2 changes: 2 additions & 0 deletions apps/cms/src/collections/users/users.collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
systemUserAccess,
systemUserOrTenantAdminAccess
} from '@codeware/app-cms/util/access';
import { adminGroups } from '@codeware/app-cms/util/definitions';

import { adminAccessToAllDocTenants } from './access/admin-access-to-all-doc-tenants';
import { tenantsArrayField } from './fields/tenants-array.field';
Expand All @@ -16,6 +17,7 @@ const users: CollectionConfig<'users'> = {
slug: 'users',
auth: { maxLoginAttempts: 5, lockTime: 1000 * 60 * 60 * 24 },
admin: {
group: adminGroups.settings,
useAsTitle: 'name'
},
labels: {
Expand Down
63 changes: 63 additions & 0 deletions apps/cms/src/components/NavigationArrayRowLabel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import type { Navigation } from '@codeware/shared/util/payload-types';

import type { ArrayRowLabel } from './array-row-label.type';

/**
* Custom array row label for the navigation array field.
*
* Displays the navigation item label instead of the default row number.
*/
export const NavigationArrayRowLabel: React.FC<ArrayRowLabel> = async (
props
) => {
const { payload, data, rowLabel, rowNumber } = props;
const { items } = data as Navigation;

// Get current nav item
const navItem = (items ?? []).at((rowNumber ?? 0) - 1);

if (!navItem?.reference) {
return rowLabel;
}

const {
customLabel,
labelSource,
reference: { relationTo, value }
} = navItem;

// Check custom label
if (labelSource === 'custom') {
return customLabel;
}

// Check reference to pages
if (relationTo === 'pages') {
if (typeof value === 'object') {
return value.name;
}
const page = await payload.findByID({
collection: 'pages',
id: value,
disableErrors: true
});
return page?.name ?? `Page #${value}`;
}

// Check reference to posts
if (relationTo === 'posts') {
if (typeof value === 'object') {
return value.title;
}
const post = await payload.findByID({
collection: 'posts',
id: value,
disableErrors: true
});
return post?.title ?? `Post #${value}`;
}

throw new Error('Invalid reference relation type');
};

export default NavigationArrayRowLabel;
Loading