Skip to content
This repository has been archived by the owner on Sep 9, 2024. It is now read-only.

Commit

Permalink
Merge branch 'main' into next
Browse files Browse the repository at this point in the history
  • Loading branch information
KaneFreeman committed Apr 26, 2024
2 parents bae4d87 + fce4c8e commit ee7544d
Show file tree
Hide file tree
Showing 34 changed files with 300 additions and 71 deletions.
2 changes: 1 addition & 1 deletion cypress/utils/steps.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'cypress-real-events';
import format from 'date-fns/format';
import { format } from 'date-fns/format';

import { editorStatus, notifications, publishTypes, workflowStatus } from './constants';

Expand Down
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
"version": "4.2.0"
"version": "4.3.0"
}
4 changes: 2 additions & 2 deletions packages/app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@staticcms/app",
"version": "4.2.0",
"version": "4.3.0",
"license": "MIT",
"description": "Static CMS application.",
"repository": "https://github.com/StaticJsCMS/static-cms",
Expand Down Expand Up @@ -39,7 +39,7 @@
"dependencies": {
"@babel/eslint-parser": "7.23.3",
"@babel/runtime": "7.23.7",
"@staticcms/core": "^4.2.0",
"@staticcms/core": "^4.3.0",
"buffer": "6.0.3",
"react": "18.2.0",
"react-dom": "18.2.0",
Expand Down
4 changes: 4 additions & 0 deletions packages/core/dev-test/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ i18n:
# Optional, defaults to the first item in locales.
# The locale to be used for fields validation and as a baseline for the entry.
default_locale: en

# Optional, defaults to true.
# Enforce required fields in non-default locales
enforce_required_non_default: true
collections:
- name: posts
label: Posts
Expand Down
6 changes: 3 additions & 3 deletions packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@staticcms/core",
"version": "4.2.0",
"version": "4.3.0",
"license": "MIT",
"description": "Static CMS core application.",
"repository": "https://github.com/StaticJsCMS/static-cms",
Expand Down Expand Up @@ -71,7 +71,7 @@
"@mui/base": "5.0.0-beta.30",
"@mui/material": "5.15.3",
"@mui/system": "5.15.3",
"@mui/x-date-pickers": "6.18.6",
"@mui/x-date-pickers": "7.3.1",
"@reduxjs/toolkit": "1.9.7",
"@styled-icons/bootstrap": "10.47.0",
"@styled-icons/fa-brands": "10.47.0",
Expand All @@ -97,7 +97,7 @@
"common-tags": "1.8.2",
"copy-text-to-clipboard": "3.2.0",
"create-react-class": "15.7.0",
"date-fns": "2.30.0",
"date-fns": "3.6.0",
"deepmerge": "4.3.1",
"diacritics": "1.3.0",
"escape-html": "1.0.3",
Expand Down
14 changes: 12 additions & 2 deletions packages/core/src/actions/__tests__/config.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,12 @@ describe('config', () => {
},
],
}).collections[0].i18n,
).toEqual({ structure: 'multiple_folders', locales: ['en', 'de'], default_locale: 'en' });
).toEqual({
structure: 'multiple_folders',
locales: ['en', 'de'],
default_locale: 'en',
enforce_required_non_default: true,
});
});

it('should not set root i18n on collection when collection i18n is not set', () => {
Expand Down Expand Up @@ -757,7 +762,12 @@ describe('config', () => {
},
],
}).collections[0].i18n,
).toEqual({ structure: 'multiple_folders', locales: ['en', 'fr'], default_locale: 'fr' });
).toEqual({
structure: 'multiple_folders',
locales: ['en', 'fr'],
default_locale: 'fr',
enforce_required_non_default: true,
});
});

it('should throw when i18n structure is not single_file on files collection', () => {
Expand Down
15 changes: 12 additions & 3 deletions packages/core/src/actions/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,17 +92,24 @@ function setI18nField<T extends BaseField = UnknownField>(field: T) {

function getI18nDefaults(
collectionOrFileI18n: boolean | Partial<I18nInfo>,
{ default_locale, locales = ['en'], structure = I18N_STRUCTURE_SINGLE_FILE }: Partial<I18nInfo>,
{
default_locale,
locales = ['en'],
structure = I18N_STRUCTURE_SINGLE_FILE,
enforce_required_non_default = true,
}: Partial<I18nInfo>,
): I18nInfo {
if (typeof collectionOrFileI18n === 'boolean') {
return { default_locale, locales, structure };
return { default_locale, locales, structure, enforce_required_non_default };
} else {
const mergedI18n: I18nInfo = deepmerge(
{ default_locale, locales, structure },
{ default_locale, locales, structure, enforce_required_non_default },
collectionOrFileI18n,
);
mergedI18n.locales = collectionOrFileI18n.locales ?? locales;
mergedI18n.default_locale = collectionOrFileI18n.default_locale || locales?.[0];
mergedI18n.enforce_required_non_default =
collectionOrFileI18n.enforce_required_non_default || true;
throwOnMissingDefaultLocale(mergedI18n);
return mergedI18n;
}
Expand Down Expand Up @@ -202,6 +209,7 @@ function applyCollectionFileDefaults(
locales: collectionI18n.locales,
default_locale: collectionI18n.default_locale,
structure: collectionI18n.structure,
enforce_required_non_default: collectionI18n.enforce_required_non_default,
});
file.i18n = fileI18n;
} else {
Expand Down Expand Up @@ -315,6 +323,7 @@ export function applyDefaults<EF extends BaseField = UnknownField>(

if (i18n) {
i18n.default_locale = i18n.default_locale ?? i18n.locales[0];
i18n.enforce_required_non_default = i18n.enforce_required_non_default ?? true;
}

throwOnMissingDefaultLocale(i18n);
Expand Down
7 changes: 4 additions & 3 deletions packages/core/src/backends/test/implementation.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import attempt from 'lodash/attempt';
import isError from 'lodash/isError';
import take from 'lodash/take';
import trim from 'lodash/trim';
import unset from 'lodash/unset';
import { basename, dirname } from 'path';
import { v4 as uuid } from 'uuid';
Expand All @@ -15,7 +16,6 @@ import { isNotEmpty } from '@staticcms/core/lib/util/string.util';
import AssetProxy from '@staticcms/core/valueObjects/AssetProxy';
import AuthenticationPage from './AuthenticationPage';

import type { WorkflowStatus } from '@staticcms/core/constants/publishModes';
import type {
BackendClass,
BackendEntry,
Expand All @@ -29,6 +29,7 @@ import type {
UnpublishedEntry,
User,
} from '@staticcms/core';
import type { WorkflowStatus } from '@staticcms/core/constants/publishModes';

type RepoFile = { path: string; content: string | AssetProxy; isDirectory?: boolean };
type RepoTree = { [key: string]: RepoFile | RepoTree };
Expand Down Expand Up @@ -289,14 +290,14 @@ export default class TestBackend implements BackendClass {
}
const files = getFolderFiles(
window.repoFiles,
mediaFolder.split('/')[0],
trim(mediaFolder, '/').split('/')[0],
'',
100,
undefined,
undefined,
folderSupport,
).filter(f => {
return dirname(f.path) === mediaFolder;
return dirname(f.path) === trim(mediaFolder, '/');
});

return files.map(f => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const collectionClasses = generateClassNames('Collection', [
'header-icon',
'header-label',
'new-entry-button',
'new-entry-button-text',
]);

export default collectionClasses;
7 changes: 6 additions & 1 deletion packages/core/src/components/collections/Collection.css
Original file line number Diff line number Diff line change
Expand Up @@ -83,5 +83,10 @@

.CMS_Collection_new-entry-button {
@apply hidden
md:flex;
md:flex
min-w-0;
}

.CMS_Collection_new-entry-button-text {
@apply truncate;
}
8 changes: 5 additions & 3 deletions packages/core/src/components/collections/CollectionHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,11 @@ const CollectionHeader: FC<CollectionHeaderProps> = ({ collection }) => {
</h2>
{newEntryUrl ? (
<Button to={newEntryUrl} className={collectionClasses['new-entry-button']}>
{t('collection.collectionTop.newButton', {
collectionLabel: collectionLabelSingular ?? pluralLabel,
})}
<div className={collectionClasses['new-entry-button-text']}>
{t('collection.collectionTop.newButton', {
collectionLabel: collectionLabelSingular ?? pluralLabel,
})}
</div>
</Button>
) : null}
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Info as InfoIcon } from '@styled-icons/material-outlined/Info';
import format from 'date-fns/format';
import parse from 'date-fns/parse';
import { format } from 'date-fns/format';
import { parse } from 'date-fns/parse';
import React, { useEffect, useMemo, useState } from 'react';

import useTranslate from '@staticcms/core/lib/hooks/useTranslate';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import AutoSizer from 'react-virtualized-auto-sizer';
import { VariableSizeGrid as Grid } from 'react-window';

import {
COLLECTION_CARD_DATE_HEIGHT,
COLLECTION_CARD_HEIGHT,
COLLECTION_CARD_HEIGHT_WITHOUT_IMAGE,
COLLECTION_CARD_MARGIN,
Expand Down Expand Up @@ -64,7 +65,7 @@ const CardWrapper: FC<GridChildComponentProps<CardGridItemData>> = ({
}
const data = entryData[index];
const cardHeight =
index < cardHeights.length ? cardHeights[index] + COLLECTION_CARD_MARGIN : style.height;
index < cardHeights.length ? cardHeights[index] + COLLECTION_CARD_MARGIN * 2 : style.height;

return (
<div
Expand Down Expand Up @@ -114,9 +115,15 @@ const EntryListingCardGrid: FC<EntryListingCardGridProps> = ({
}, []);

const getDefaultHeight = useCallback((data?: CollectionEntryData) => {
return isNotNullish(data?.imageFieldName)
const base = isNotNullish(data?.imageFieldName)
? COLLECTION_CARD_HEIGHT
: COLLECTION_CARD_HEIGHT_WITHOUT_IMAGE;

if (isNotNullish(data?.dateFieldName)) {
return base + COLLECTION_CARD_DATE_HEIGHT;
}

return base;
}, []);

const [prevCardHeights, setPrevCardHeight] = useState<number[]>([]);
Expand Down Expand Up @@ -185,12 +192,12 @@ const EntryListingCardGrid: FC<EntryListingCardGridProps> = ({
}

if (cardHeights[i] > rowHeight && cardHeights[i]) {
rowHeight = cardHeights[i] + COLLECTION_CARD_MARGIN;
rowHeight = cardHeights[i] + COLLECTION_CARD_MARGIN * 2;
}
}

if (rowHeight === 0) {
rowHeight = getDefaultHeight() + COLLECTION_CARD_MARGIN;
rowHeight = getDefaultHeight() + COLLECTION_CARD_MARGIN * 2;
}

return rowHeight;
Expand Down
5 changes: 5 additions & 0 deletions packages/core/src/components/entry-editor/EditorToolbar.css
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
lg:!hidden;
}

.CMS_EditorToolbar_discard-button {
@apply flex
lg:!hidden;
}

.CMS_EditorToolbar_delete-button {
@apply flex
lg:!hidden;
Expand Down
29 changes: 25 additions & 4 deletions packages/core/src/components/entry-editor/EditorToolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ import MenuGroup from '../common/menu/MenuGroup';
import MenuItemButton from '../common/menu/MenuItemButton';
import EditorWorkflowToolbarButtons from './EditorWorkflowToolbarButtons';

import type { WorkflowStatus } from '@staticcms/core/constants/publishModes';
import type { CollectionWithDefaults, EditorPersistOptions } from '@staticcms/core';
import type { WorkflowStatus } from '@staticcms/core/constants/publishModes';
import type { FC, MouseEventHandler } from 'react';

import './EditorToolbar.css';
Expand All @@ -41,6 +41,7 @@ export const classes = generateClassNames('EditorToolbar', [
'more-menu-button',
'more-menu-label-icon',
'preview-toggle',
'discard-button',
'delete-button',
'publish-button',
'publish-button-icon',
Expand Down Expand Up @@ -419,14 +420,34 @@ const EditorToolbar: FC<EditorToolbarProps> = ({
disabled={disabled}
/>
) : null}
{canDelete ? (
{hasChanged ? (
<IconButton
icon={TrashIcon}
key="discard-button"
title={t('editor.editorToolbar.discardChanges')}
color="warning"
variant="text"
onClick={handleDiscardDraft}
rootClassName={classes['discard-button']}
aria-label="discard chnages"
disabled={disabled}
/>
) : canDelete &&
(!useOpenAuthoring || hasUnpublishedChanges) &&
(!useWorkflow || workflowDeleteLabel) ? (
<IconButton
icon={TrashIcon}
key="delete-button"
title={t('editor.editorToolbar.deleteEntry')}
title={useWorkflow ? t(workflowDeleteLabel!) : t('editor.editorToolbar.deleteEntry')}
color="error"
variant="text"
onClick={onDelete}
onClick={
useWorkflow &&
workflowDeleteLabel &&
workflowDeleteLabel !== 'editor.editorToolbar.deletePublishedEntry'
? onDeleteUnpublishedChanges
: onDelete
}
rootClassName={classes['delete-button']}
aria-label="delete"
disabled={disabled}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ const EditorControl: FC<EditorControlProps> = ({
(!dirty && !submitted) ||
disabled ||
i18nDisabled ||
(forList && field.widget === 'object' && field.fields.length === 1)
(forList && field.widget === 'object' && field.fields.length === 1) ||
(i18n?.enforceRequiredNonDefault === false && i18n?.currentLocale !== i18n?.defaultLocale)
) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,12 @@ const EditorControlPane: FC<EditorControlPaneProps> = ({

const i18n = useMemo(() => {
if (hasI18n(collection)) {
const { locales, default_locale } = getI18nInfo(collection);
const { locales, default_locale, enforce_required_non_default } = getI18nInfo(collection);
return {
currentLocale: locale ?? locales?.[0],
locales,
defaultLocale: default_locale,
enforceRequiredNonDefault: enforce_required_non_default,
} as I18nSettings;
}

Expand Down
1 change: 1 addition & 0 deletions packages/core/src/constants/configSchema.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const i18n = {
uniqueItems: true,
},
default_locale: localeType,
enforce_required_non_default: { type: 'boolean' },
},
};

Expand Down
1 change: 1 addition & 0 deletions packages/core/src/constants/views.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const COLLECTION_CARD_WIDTH = 240;
export const COLLECTION_CARD_HEIGHT = 204;
export const COLLECTION_CARD_IMAGE_HEIGHT = 140;
export const COLLECTION_CARD_HEIGHT_WITHOUT_IMAGE = 56;
export const COLLECTION_CARD_DATE_HEIGHT = 24;
export const COLLECTION_CARD_MARGIN = 10;

export const EDITOR_SIZE_COMPACT = 'compact';
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ export interface I18nSettings {
currentLocale: string;
defaultLocale: string;
locales: string[];
enforceRequiredNonDefault?: boolean;
}

export type Format = keyof typeof formatExtensions;
Expand Down Expand Up @@ -1306,6 +1307,7 @@ export interface I18nInfo {
locales: string[];
default_locale?: string;
structure: I18nStructure;
enforce_required_non_default?: boolean;
}

export interface ProcessedCodeLanguage {
Expand Down
Loading

0 comments on commit ee7544d

Please sign in to comment.