fix: ctb reload state after save & delete (#22805)

This commit is contained in:
Alexandre BODIN 2025-02-10 16:12:25 +01:00 committed by GitHub
parent 0521e81a13
commit a6235c371b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
26 changed files with 121 additions and 120 deletions

View File

@ -18,7 +18,7 @@ export default defineConfig([
{
dir: path.join(import.meta.dirname, 'dist/server'),
entryFileNames: '[name].mjs',
chunkFileNames: 'chunks/[name]-[hash].js',
chunkFileNames: 'chunks/[name]-[hash].mjs',
exports: 'auto',
format: 'esm',
sourcemap: true,
@ -44,7 +44,7 @@ export default defineConfig([
{
dir: path.join(import.meta.dirname, 'dist'),
entryFileNames: '[name].mjs',
chunkFileNames: 'chunks/[name]-[hash].js',
chunkFileNames: 'chunks/[name]-[hash].mjs',
exports: 'auto',
format: 'esm',
sourcemap: true,
@ -71,7 +71,7 @@ export default defineConfig([
{
dir: path.join(import.meta.dirname, 'dist/admin'),
entryFileNames: '[name].mjs',
chunkFileNames: 'chunks/[name]-[hash].js',
chunkFileNames: 'chunks/[name]-[hash].mjs',
exports: 'auto',
format: 'esm',
sourcemap: true,

View File

@ -8,6 +8,9 @@ import { previewAdmin } from './preview';
import { routes } from './router';
import { prefixPluginTranslations } from './utils/translations';
// NOTE: we have to preload it to ensure chunks will have it available as global
import 'prismjs';
// eslint-disable-next-line import/no-default-export
export default {
register(app: any) {

View File

@ -13,9 +13,57 @@ import { codeLanguages } from '../utils/constants';
import { baseHandleConvert } from '../utils/conversions';
import { pressEnterTwiceToExit } from '../utils/enterKey';
import { type Block } from '../utils/types';
// Import the PrismJS theme to highlight the code
import 'prismjs/themes/prism-solarizedlight.css';
import './utils/prismLanguages';
import 'prismjs/components/prism-asmatmel';
import 'prismjs/components/prism-bash';
import 'prismjs/components/prism-basic';
import 'prismjs/components/prism-c';
import 'prismjs/components/prism-clojure';
import 'prismjs/components/prism-cobol';
import 'prismjs/components/prism-cpp';
import 'prismjs/components/prism-csharp';
import 'prismjs/components/prism-dart';
import 'prismjs/components/prism-docker';
import 'prismjs/components/prism-elixir';
import 'prismjs/components/prism-erlang';
import 'prismjs/components/prism-fortran';
import 'prismjs/components/prism-fsharp';
import 'prismjs/components/prism-go';
import 'prismjs/components/prism-graphql';
import 'prismjs/components/prism-groovy';
import 'prismjs/components/prism-haskell';
import 'prismjs/components/prism-haxe';
import 'prismjs/components/prism-ini';
import 'prismjs/components/prism-java';
import 'prismjs/components/prism-javascript';
import 'prismjs/components/prism-jsx';
import 'prismjs/components/prism-json';
import 'prismjs/components/prism-julia';
import 'prismjs/components/prism-kotlin';
import 'prismjs/components/prism-latex';
import 'prismjs/components/prism-lua';
import 'prismjs/components/prism-markdown';
import 'prismjs/components/prism-matlab';
import 'prismjs/components/prism-makefile';
import 'prismjs/components/prism-objectivec';
import 'prismjs/components/prism-perl';
import 'prismjs/components/prism-php';
import 'prismjs/components/prism-powershell';
import 'prismjs/components/prism-python';
import 'prismjs/components/prism-r';
import 'prismjs/components/prism-ruby';
import 'prismjs/components/prism-rust';
import 'prismjs/components/prism-sas';
import 'prismjs/components/prism-scala';
import 'prismjs/components/prism-scheme';
import 'prismjs/components/prism-sql';
import 'prismjs/components/prism-stata';
import 'prismjs/components/prism-swift';
import 'prismjs/components/prism-typescript';
import 'prismjs/components/prism-tsx';
import 'prismjs/components/prism-vbnet';
import 'prismjs/components/prism-yaml';
type BaseRangeCustom = BaseRange & { className: string };

View File

@ -1,49 +0,0 @@
import 'prismjs/components/prism-asmatmel';
import 'prismjs/components/prism-bash';
import 'prismjs/components/prism-basic';
import 'prismjs/components/prism-c';
import 'prismjs/components/prism-clojure';
import 'prismjs/components/prism-cobol';
import 'prismjs/components/prism-cpp';
import 'prismjs/components/prism-csharp';
import 'prismjs/components/prism-dart';
import 'prismjs/components/prism-docker';
import 'prismjs/components/prism-elixir';
import 'prismjs/components/prism-erlang';
import 'prismjs/components/prism-fortran';
import 'prismjs/components/prism-fsharp';
import 'prismjs/components/prism-go';
import 'prismjs/components/prism-graphql';
import 'prismjs/components/prism-groovy';
import 'prismjs/components/prism-haskell';
import 'prismjs/components/prism-haxe';
import 'prismjs/components/prism-ini';
import 'prismjs/components/prism-java';
import 'prismjs/components/prism-javascript';
import 'prismjs/components/prism-jsx';
import 'prismjs/components/prism-json';
import 'prismjs/components/prism-julia';
import 'prismjs/components/prism-kotlin';
import 'prismjs/components/prism-latex';
import 'prismjs/components/prism-lua';
import 'prismjs/components/prism-markdown';
import 'prismjs/components/prism-matlab';
import 'prismjs/components/prism-makefile';
import 'prismjs/components/prism-objectivec';
import 'prismjs/components/prism-perl';
import 'prismjs/components/prism-php';
import 'prismjs/components/prism-powershell';
import 'prismjs/components/prism-python';
import 'prismjs/components/prism-r';
import 'prismjs/components/prism-ruby';
import 'prismjs/components/prism-rust';
import 'prismjs/components/prism-sas';
import 'prismjs/components/prism-scala';
import 'prismjs/components/prism-scheme';
import 'prismjs/components/prism-sql';
import 'prismjs/components/prism-stata';
import 'prismjs/components/prism-swift';
import 'prismjs/components/prism-typescript';
import 'prismjs/components/prism-tsx';
import 'prismjs/components/prism-vbnet';
import 'prismjs/components/prism-yaml';

View File

@ -18,7 +18,7 @@ export default defineConfig([
{
dir: path.join(import.meta.dirname, 'dist/server'),
entryFileNames: '[name].mjs',
chunkFileNames: 'chunks/[name]-[hash].js',
chunkFileNames: 'chunks/[name]-[hash].mjs',
exports: 'auto',
format: 'esm',
sourcemap: true,
@ -41,7 +41,7 @@ export default defineConfig([
{
dir: path.join(import.meta.dirname, 'dist/admin'),
entryFileNames: '[name].mjs',
chunkFileNames: 'chunks/[name]-[hash].js',
chunkFileNames: 'chunks/[name]-[hash].mjs',
exports: 'named',
format: 'esm',
sourcemap: true,
@ -64,7 +64,7 @@ export default defineConfig([
{
dir: path.join(import.meta.dirname, 'dist/shared'),
entryFileNames: '[name].mjs',
chunkFileNames: 'chunks/[name]-[hash].js',
chunkFileNames: 'chunks/[name]-[hash].mjs',
exports: 'auto',
format: 'esm',
sourcemap: true,

View File

@ -18,7 +18,7 @@ export default defineConfig([
{
dir: path.join(import.meta.dirname, 'dist/server'),
entryFileNames: '[name].mjs',
chunkFileNames: 'chunks/[name]-[hash].js',
chunkFileNames: 'chunks/[name]-[hash].mjs',
exports: 'auto',
format: 'esm',
sourcemap: true,
@ -41,7 +41,7 @@ export default defineConfig([
{
dir: path.join(import.meta.dirname, 'dist/admin'),
entryFileNames: '[name].mjs',
chunkFileNames: 'chunks/[name]-[hash].js',
chunkFileNames: 'chunks/[name]-[hash].mjs',
exports: 'auto',
format: 'esm',
sourcemap: true,

View File

@ -306,6 +306,7 @@ const DataManagerProvider = ({ children }: DataManagerProviderProps) => {
try {
const requestURL = `/${pluginId}/${endPoint}/${currentUid}`;
const isTemporary = get(modifiedData, [firstKeyToMainSchema, 'isTemporary'], false);
// eslint-disable-next-line no-alert
const userConfirm = window.confirm(
formatMessage({
@ -339,6 +340,7 @@ const DataManagerProvider = ({ children }: DataManagerProviderProps) => {
// Unlock the app
await unlockAppWithAutoreload?.();
await getDataRef.current();
// Refetch the permissions
await updatePermissions();
}
@ -562,7 +564,6 @@ const DataManagerProvider = ({ children }: DataManagerProviderProps) => {
// refetch and update initial state after the data has been saved
await getDataRef.current();
dispatch(actions.updateInitialState());
// Update the app's permissions
await updatePermissions();

View File

@ -160,6 +160,35 @@ const slice = createSlice({
state.contentTypes = contentTypes;
state.reservedNames = reservedNames;
state.isLoading = false;
state.modifiedData = {
...DEFAULT_MODIFIED_DATA,
component: state.modifiedData.component
? components[state.modifiedData.component.uid]
: undefined,
contentType: state.modifiedData.contentType
? contentTypes[state.modifiedData.contentType.uid]
: undefined,
components: state.modifiedData.components
? Object.keys(state.modifiedData.components).reduce(
(acc, key) => {
acc[key] = components[key];
return acc;
},
{} as Record<string, Component>
)
: {},
contentTypes: state.modifiedData.contentTypes
? Object.keys(state.modifiedData.contentTypes).reduce(
(acc, key) => {
acc[key] = contentTypes[key];
return acc;
},
{} as Record<string, ContentType>
)
: {},
};
state.initialData = state.modifiedData;
},
addAttribute: (state, action: PayloadAction<AddAttributePayload>) => {
const { attributeToSet, forTarget, targetUid, shouldAddComponentToData } = action.payload;

View File

@ -30,7 +30,7 @@ export interface Component {
}
export interface ContentType {
uid?: Internal.UID.ContentType;
uid: Internal.UID.ContentType;
isTemporary?: boolean;
visible?: boolean;
name?: string;

View File

@ -47,7 +47,9 @@ export const formsAPI: any = {
extendContentType({ validator, form: { advanced, base } }: any) {
const { contentType } = this.types;
contentType.validators.push(validator);
if (validator) {
contentType.validators.push(validator);
}
contentType.form.advanced.push(advanced);
contentType.form.base.push(base);
},
@ -69,7 +71,9 @@ export const formsAPI: any = {
};
}
formType[field].validators.push(validator);
if (validator) {
formType[field].validators.push(validator);
}
formType[field].form.advanced.push(advanced);
formType[field].form.base.push(base);
});

View File

@ -18,7 +18,7 @@ export default defineConfig([
{
dir: path.join(import.meta.dirname, 'dist/server'),
entryFileNames: '[name].mjs',
chunkFileNames: 'chunks/[name]-[hash].js',
chunkFileNames: 'chunks/[name]-[hash].mjs',
exports: 'auto',
format: 'esm',
sourcemap: true,
@ -41,7 +41,7 @@ export default defineConfig([
{
dir: path.join(import.meta.dirname, 'dist/admin'),
entryFileNames: '[name].mjs',
chunkFileNames: 'chunks/[name]-[hash].js',
chunkFileNames: 'chunks/[name]-[hash].mjs',
exports: 'auto',
format: 'esm',
sourcemap: true,

View File

@ -18,7 +18,7 @@ export default defineConfig([
{
dir: path.join(import.meta.dirname, 'dist/server'),
entryFileNames: '[name].mjs',
chunkFileNames: 'chunks/[name]-[hash].js',
chunkFileNames: 'chunks/[name]-[hash].mjs',
exports: 'auto',
format: 'esm',
sourcemap: true,
@ -41,7 +41,7 @@ export default defineConfig([
{
dir: path.join(import.meta.dirname, 'dist/admin'),
entryFileNames: '[name].mjs',
chunkFileNames: 'chunks/[name]-[hash].js',
chunkFileNames: 'chunks/[name]-[hash].mjs',
exports: 'auto',
format: 'esm',
sourcemap: true,

View File

@ -18,7 +18,7 @@ export default defineConfig([
{
dir: path.join(import.meta.dirname, 'dist/server'),
entryFileNames: '[name].mjs',
chunkFileNames: 'chunks/[name]-[hash].js',
chunkFileNames: 'chunks/[name]-[hash].mjs',
exports: 'auto',
format: 'esm',
sourcemap: true,
@ -41,7 +41,7 @@ export default defineConfig([
{
dir: path.join(import.meta.dirname, 'dist/admin'),
entryFileNames: '[name].mjs',
chunkFileNames: 'chunks/[name]-[hash].js',
chunkFileNames: 'chunks/[name]-[hash].mjs',
exports: 'auto',
format: 'esm',
sourcemap: true,

View File

@ -23,7 +23,7 @@ export default defineConfig([
{
dir: import.meta.dirname + '/dist',
entryFileNames: '[name].mjs',
chunkFileNames: 'chunks/[name]-[hash].js',
chunkFileNames: 'chunks/[name]-[hash].mjs',
exports: 'auto',
format: 'esm',
sourcemap: true,

View File

@ -18,7 +18,7 @@ export default defineConfig([
{
dir: path.join(import.meta.dirname, 'dist/server'),
entryFileNames: '[name].mjs',
chunkFileNames: 'chunks/[name]-[hash].js',
chunkFileNames: 'chunks/[name]-[hash].mjs',
exports: 'auto',
format: 'esm',
sourcemap: true,
@ -41,7 +41,7 @@ export default defineConfig([
{
dir: path.join(import.meta.dirname, 'dist/admin'),
entryFileNames: '[name].mjs',
chunkFileNames: 'chunks/[name]-[hash].js',
chunkFileNames: 'chunks/[name]-[hash].mjs',
exports: 'auto',
format: 'esm',
sourcemap: true,

View File

@ -17,7 +17,7 @@ export default defineConfig({
{
dir: path.join(import.meta.dirname, 'dist/admin'),
entryFileNames: '[name].mjs',
chunkFileNames: 'chunks/[name]-[hash].js',
chunkFileNames: 'chunks/[name]-[hash].mjs',
exports: 'auto',
format: 'esm',
sourcemap: true,

View File

@ -18,7 +18,7 @@ export default defineConfig([
{
dir: path.join(import.meta.dirname, 'dist/server'),
entryFileNames: '[name].mjs',
chunkFileNames: 'chunks/[name]-[hash].js',
chunkFileNames: 'chunks/[name]-[hash].mjs',
exports: 'auto',
format: 'esm',
sourcemap: true,
@ -41,7 +41,7 @@ export default defineConfig([
{
dir: path.join(import.meta.dirname, 'dist/admin'),
entryFileNames: '[name].mjs',
chunkFileNames: 'chunks/[name]-[hash].js',
chunkFileNames: 'chunks/[name]-[hash].mjs',
exports: 'auto',
format: 'esm',
sourcemap: true,

View File

@ -18,7 +18,7 @@ export default defineConfig([
{
dir: path.join(import.meta.dirname, 'dist/server'),
entryFileNames: '[name].mjs',
chunkFileNames: 'chunks/[name]-[hash].js',
chunkFileNames: 'chunks/[name]-[hash].mjs',
exports: 'auto',
format: 'esm',
sourcemap: true,
@ -41,7 +41,7 @@ export default defineConfig([
{
dir: path.join(import.meta.dirname, 'dist/admin'),
entryFileNames: '[name].mjs',
chunkFileNames: 'chunks/[name]-[hash].js',
chunkFileNames: 'chunks/[name]-[hash].mjs',
exports: 'auto',
format: 'esm',
sourcemap: true,

View File

@ -18,7 +18,7 @@ export default defineConfig([
{
dir: path.join(import.meta.dirname, 'dist/server'),
entryFileNames: '[name].mjs',
chunkFileNames: 'chunks/[name]-[hash].js',
chunkFileNames: 'chunks/[name]-[hash].mjs',
exports: 'auto',
format: 'esm',
sourcemap: true,
@ -41,7 +41,7 @@ export default defineConfig([
{
dir: path.join(import.meta.dirname, 'dist/admin'),
entryFileNames: '[name].mjs',
chunkFileNames: 'chunks/[name]-[hash].js',
chunkFileNames: 'chunks/[name]-[hash].mjs',
exports: 'auto',
format: 'esm',
sourcemap: true,

View File

@ -18,7 +18,7 @@ export default defineConfig([
{
dir: path.join(import.meta.dirname, 'dist/server'),
entryFileNames: '[name].mjs',
chunkFileNames: 'chunks/[name]-[hash].js',
chunkFileNames: 'chunks/[name]-[hash].mjs',
exports: 'auto',
format: 'esm',
sourcemap: true,
@ -41,7 +41,7 @@ export default defineConfig([
{
dir: path.join(import.meta.dirname, 'dist/admin'),
entryFileNames: '[name].mjs',
chunkFileNames: 'chunks/[name]-[hash].js',
chunkFileNames: 'chunks/[name]-[hash].mjs',
exports: 'auto',
format: 'esm',
sourcemap: true,

View File

@ -18,7 +18,7 @@ export default defineConfig([
{
dir: path.join(import.meta.dirname, 'dist/server'),
entryFileNames: '[name].mjs',
chunkFileNames: 'chunks/[name]-[hash].js',
chunkFileNames: 'chunks/[name]-[hash].mjs',
exports: 'auto',
format: 'esm',
sourcemap: true,
@ -41,7 +41,7 @@ export default defineConfig([
{
dir: path.join(import.meta.dirname, 'dist/admin'),
entryFileNames: '[name].mjs',
chunkFileNames: 'chunks/[name]-[hash].js',
chunkFileNames: 'chunks/[name]-[hash].mjs',
exports: 'auto',
format: 'esm',
sourcemap: true,

View File

@ -18,7 +18,7 @@ export default defineConfig([
{
dir: path.join(import.meta.dirname, 'dist/admin'),
entryFileNames: '[name].mjs',
chunkFileNames: 'chunks/[name]-[hash].js',
chunkFileNames: 'chunks/[name]-[hash].mjs',
exports: 'auto',
format: 'esm',
sourcemap: true,
@ -41,7 +41,7 @@ export default defineConfig([
{
dir: path.join(import.meta.dirname, 'dist/server'),
entryFileNames: '[name].mjs',
chunkFileNames: 'chunks/[name]-[hash].js',
chunkFileNames: 'chunks/[name]-[hash].mjs',
exports: 'auto',
format: 'esm',
sourcemap: true,

View File

@ -28,11 +28,9 @@ const goToHistoryPage = async (page: Page) => {
await moreActionsButton.click();
const historyButton = page.getByRole('menuitem', { name: /content history/i });
// TODO find out why the history button sometimes doesn't appear. Reloading shouldn't be necessary
if (await historyButton.isVisible()) {
await clickAndWait(page, historyButton);
} else {
await page.reload();
await goToHistoryPage(page);
}
};

View File

@ -41,8 +41,6 @@ test.describe('Edit collection type', () => {
await page.getByRole('button', { name: 'Finish' }).click();
await page.getByRole('button', { name: 'Save' }).click();
// TODO: this is here because of a bug where the admin UI doesn't understand the option has changed
// Fix the bug then remove this
await waitForRestart(page);
await expect(page.getByRole('cell', { name: 'product', exact: true })).toBeVisible();
@ -66,10 +64,6 @@ test.describe('Edit collection type', () => {
await waitForRestart(page);
await expect(page.getByRole('heading', { name: ctName })).toBeVisible();
// TODO: this is here because of a bug where the admin UI doesn't understand the option has changed
// Fix the bug then remove this
await page.reload();
// toggle on - we see that the "off" worked because here it doesn't prompt to confirm data loss
await page.getByRole('button', { name: 'Edit' }).first().click();
await page.getByRole('tab', { name: 'Advanced settings' }).click();
@ -89,10 +83,6 @@ test.describe('Edit collection type', () => {
await waitForRestart(page);
await expect(page.getByRole('heading', { name: ctName })).toBeVisible();
// TODO: this is here because of a bug where the admin UI doesn't understand the option has changed
// Fix the bug then remove this
await page.reload();
// toggle on - we see that the "off" worked because here it doesn't prompt to confirm data loss
await page.getByRole('button', { name: 'Edit' }).first().click();
await page.getByRole('tab', { name: 'Advanced settings' }).click();
@ -176,9 +166,6 @@ test.describe('Edit collection type', () => {
await waitForRestart(page);
// TODO: fix bug that requires a page refresh to see that content types have been updated
await page.reload();
await expect(page.getByRole('heading', { name: newname })).toBeVisible();
});
@ -192,9 +179,6 @@ test.describe('Edit collection type', () => {
await waitForRestart(page);
// TODO: fix bug that requires a page refresh to see that content types have been updated
await page.reload();
await expect(page.getByRole('heading', { name: ctName })).not.toBeVisible();
});

View File

@ -137,9 +137,6 @@ test.describe('Update a new component', () => {
// delete it
await deleteComponent(page, 'SomeComponent');
// TODO: fix issue that components aren't removed from side navigation or content types until refresh
await page.reload({ waitUntil: 'networkidle' });
// confirm that it no longer exists in the content type this component was in
await navToHeader(page, ['Content-Type Builder', collectionType.name], collectionType.name);
await expect(page.getByText(componentAttributeName, { exact: true })).not.toBeVisible();

View File

@ -40,10 +40,6 @@ test.describe('Edit single type', () => {
await waitForRestart(page);
await expect(page.getByRole('heading', { name: ctName })).toBeVisible();
// TODO: this is here because of a bug where the admin UI doesn't understand the option has changed
// Fix the bug then remove this
await page.reload();
// toggle on - we see that the "off" worked because here it doesn't prompt to confirm data loss
await page.getByRole('button', { name: 'Edit', exact: true }).click();
await page.getByRole('tab', { name: 'Advanced settings' }).click();
@ -63,10 +59,6 @@ test.describe('Edit single type', () => {
await waitForRestart(page);
await expect(page.getByRole('heading', { name: ctName })).toBeVisible();
// TODO: this is here because of a bug where the admin UI doesn't understand the option has changed
// Fix the bug then remove this
await page.reload();
// toggle on - we see that the "off" worked because here it doesn't prompt to confirm data loss
await page.getByRole('button', { name: 'Edit', exact: true }).click();
await page.getByRole('tab', { name: 'Advanced settings' }).click();
@ -102,9 +94,6 @@ test.describe('Edit single type', () => {
await waitForRestart(page);
// TODO: fix bug that requires a page refresh to see that content types have been updated
await page.reload();
await expect(page.getByRole('heading', { name: newname })).toBeVisible();
});
@ -118,9 +107,6 @@ test.describe('Edit single type', () => {
await waitForRestart(page);
// TODO: fix bug that requires a page refresh to see that content types have been updated
await page.reload();
await expect(page.getByRole('heading', { name: ctName })).not.toBeVisible();
});
});