From a3c8882d0b515baccc5be7f7f02765bde0d7ffac Mon Sep 17 00:00:00 2001 From: Vitalii Nobis Date: Thu, 21 Sep 2023 13:02:44 +0000 Subject: [PATCH 1/5] fix: fix form builder settings after switching to new locale --- packages/api-form-builder/src/index.ts | 4 +++- .../src/plugins/crud/settings.crud.ts | 12 ++++++++---- .../settings/createSettingsForNewLocale.ts | 15 +++++++++++++++ .../src/plugins/settings/index.ts | 3 +++ packages/api-form-builder/src/types.ts | 1 + 5 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 packages/api-form-builder/src/plugins/settings/createSettingsForNewLocale.ts create mode 100644 packages/api-form-builder/src/plugins/settings/index.ts diff --git a/packages/api-form-builder/src/index.ts b/packages/api-form-builder/src/index.ts index a6e886ce945..bb56df9d281 100644 --- a/packages/api-form-builder/src/index.ts +++ b/packages/api-form-builder/src/index.ts @@ -1,6 +1,7 @@ import createCruds from "./plugins/crud"; import graphql from "./plugins/graphql"; import triggerHandlers from "./plugins/triggers"; +import settings from "./plugins/settings"; import validators from "./plugins/validators"; import formsGraphQL from "./plugins/graphql/form"; import formSettingsGraphQL from "./plugins/graphql/formSettings"; @@ -17,6 +18,7 @@ export const createFormBuilder = (params: CreateFormBuilderParams) => { triggerHandlers, validators, formsGraphQL, - formSettingsGraphQL + formSettingsGraphQL, + settings ]; }; diff --git a/packages/api-form-builder/src/plugins/crud/settings.crud.ts b/packages/api-form-builder/src/plugins/crud/settings.crud.ts index d0999ec84ca..f8c30c65d68 100644 --- a/packages/api-form-builder/src/plugins/crud/settings.crud.ts +++ b/packages/api-form-builder/src/plugins/crud/settings.crud.ts @@ -60,7 +60,7 @@ export const createSettingsCrud = (params: CreateSettingsCrudParams): SettingsCR onSettingsBeforeDelete, onSettingsAfterDelete, async getSettings(this: FormBuilder, params) { - const { auth, throwOnNotFound } = params || {}; + const { auth, throwOnNotFound, locale } = params || {}; if (auth !== false) { await settingsPermissions.ensure(); @@ -70,7 +70,7 @@ export const createSettingsCrud = (params: CreateSettingsCrudParams): SettingsCR try { settings = await this.storageOperations.getSettings({ tenant: getTenant().id, - locale: getLocale().code + locale: locale || getLocale().code }); } catch (ex) { throw new WebinyError( @@ -89,7 +89,11 @@ export const createSettingsCrud = (params: CreateSettingsCrudParams): SettingsCR const data = await formBuilderSettings.toJSON(); - const original = await this.getSettings({ auth: false }); + const original = await this.getSettings({ + auth: false, + locale: input.locale + }); + if (original) { throw new WebinyError( `"Form Builder" settings already exist.`, @@ -106,7 +110,7 @@ export const createSettingsCrud = (params: CreateSettingsCrudParams): SettingsCR domain: data.domain, reCaptcha: data.reCaptcha, tenant: getTenant().id, - locale: getLocale().code + locale: input.locale || getLocale().code }; try { await onSettingsBeforeCreate.publish({ diff --git a/packages/api-form-builder/src/plugins/settings/createSettingsForNewLocale.ts b/packages/api-form-builder/src/plugins/settings/createSettingsForNewLocale.ts new file mode 100644 index 00000000000..9932d30e282 --- /dev/null +++ b/packages/api-form-builder/src/plugins/settings/createSettingsForNewLocale.ts @@ -0,0 +1,15 @@ +import { ContextPlugin } from "@webiny/api"; +import { FormBuilderContext } from "~/types"; + +export const createSettingsForNewLocale = new ContextPlugin(context => { + context.i18n.locales.onLocaleAfterCreate.subscribe(async ({ locale }) => { + const existingSettings = await context.formBuilder.getSettings({ + auth: false, + locale: locale.code + }); + + if (!existingSettings) { + await context.formBuilder.createSettings({ locale: locale.code }); + } + }); +}); diff --git a/packages/api-form-builder/src/plugins/settings/index.ts b/packages/api-form-builder/src/plugins/settings/index.ts new file mode 100644 index 00000000000..421592395cb --- /dev/null +++ b/packages/api-form-builder/src/plugins/settings/index.ts @@ -0,0 +1,3 @@ +import { createSettingsForNewLocale } from "./createSettingsForNewLocale"; + +export default [createSettingsForNewLocale]; diff --git a/packages/api-form-builder/src/types.ts b/packages/api-form-builder/src/types.ts index c562f9e4dde..53bb546811a 100644 --- a/packages/api-form-builder/src/types.ts +++ b/packages/api-form-builder/src/types.ts @@ -368,6 +368,7 @@ export interface Settings { export interface SettingsCRUDGetParams { auth?: boolean; throwOnNotFound?: boolean; + locale?: string; } /** From 8ab30900fd6df656cc76d1bf4105372953f84560 Mon Sep 17 00:00:00 2001 From: Vitalii Nobis Date: Fri, 13 Oct 2023 16:03:54 +0000 Subject: [PATCH 2/5] fix: requested changes --- .../api-form-builder/src/plugins/crud/settings.crud.ts | 5 +++-- .../src/plugins/settings/createSettingsForNewLocale.ts | 9 +++------ .../plugins/settings/deleteSettingsForDeletedLocale.ts | 8 ++++++++ packages/api-form-builder/src/plugins/settings/index.ts | 3 ++- packages/api-form-builder/src/types.ts | 6 +++++- 5 files changed, 21 insertions(+), 10 deletions(-) create mode 100644 packages/api-form-builder/src/plugins/settings/deleteSettingsForDeletedLocale.ts diff --git a/packages/api-form-builder/src/plugins/crud/settings.crud.ts b/packages/api-form-builder/src/plugins/crud/settings.crud.ts index f8c30c65d68..96de28eeec8 100644 --- a/packages/api-form-builder/src/plugins/crud/settings.crud.ts +++ b/packages/api-form-builder/src/plugins/crud/settings.crud.ts @@ -190,10 +190,11 @@ export const createSettingsCrud = (params: CreateSettingsCrudParams): SettingsCR ); } }, - async deleteSettings(this: FormBuilder) { + async deleteSettings(this: FormBuilder, params) { + const { locale } = params || {}; await settingsPermissions.ensure(); - const settings = await this.getSettings(); + const settings = await this.getSettings({ locale }); if (!settings) { return; } diff --git a/packages/api-form-builder/src/plugins/settings/createSettingsForNewLocale.ts b/packages/api-form-builder/src/plugins/settings/createSettingsForNewLocale.ts index 9932d30e282..3b41790b735 100644 --- a/packages/api-form-builder/src/plugins/settings/createSettingsForNewLocale.ts +++ b/packages/api-form-builder/src/plugins/settings/createSettingsForNewLocale.ts @@ -3,13 +3,10 @@ import { FormBuilderContext } from "~/types"; export const createSettingsForNewLocale = new ContextPlugin(context => { context.i18n.locales.onLocaleAfterCreate.subscribe(async ({ locale }) => { - const existingSettings = await context.formBuilder.getSettings({ - auth: false, - locale: locale.code + const currentSettings = await context.formBuilder.getSettings({ + auth: false }); - if (!existingSettings) { - await context.formBuilder.createSettings({ locale: locale.code }); - } + await context.formBuilder.createSettings({ ...currentSettings, locale: locale.code }); }); }); diff --git a/packages/api-form-builder/src/plugins/settings/deleteSettingsForDeletedLocale.ts b/packages/api-form-builder/src/plugins/settings/deleteSettingsForDeletedLocale.ts new file mode 100644 index 00000000000..9e9542aeeb6 --- /dev/null +++ b/packages/api-form-builder/src/plugins/settings/deleteSettingsForDeletedLocale.ts @@ -0,0 +1,8 @@ +import { ContextPlugin } from "@webiny/api"; +import { FormBuilderContext } from "~/types"; + +export const deleteSettingsForDeletedLocale = new ContextPlugin(context => { + context.i18n.locales.onLocaleAfterDelete.subscribe(async ({ locale }) => { + await context.formBuilder.deleteSettings({ locale: locale.code }); + }); +}); diff --git a/packages/api-form-builder/src/plugins/settings/index.ts b/packages/api-form-builder/src/plugins/settings/index.ts index 421592395cb..899f552eb2e 100644 --- a/packages/api-form-builder/src/plugins/settings/index.ts +++ b/packages/api-form-builder/src/plugins/settings/index.ts @@ -1,3 +1,4 @@ import { createSettingsForNewLocale } from "./createSettingsForNewLocale"; +import { deleteSettingsForDeletedLocale } from "./deleteSettingsForDeletedLocale"; -export default [createSettingsForNewLocale]; +export default [createSettingsForNewLocale, deleteSettingsForDeletedLocale]; diff --git a/packages/api-form-builder/src/types.ts b/packages/api-form-builder/src/types.ts index 1b7fcc466a8..48a7d3c4876 100644 --- a/packages/api-form-builder/src/types.ts +++ b/packages/api-form-builder/src/types.ts @@ -377,6 +377,10 @@ export interface SettingsCRUDGetParams { locale?: string; } +export interface SettingsCRUDDeleteParams { + locale?: string; +} + /** * Settings CRUD Lifecycle Events */ @@ -405,7 +409,7 @@ export interface SettingsCRUD { getSettings(params?: SettingsCRUDGetParams): Promise; createSettings(data: Partial): Promise; updateSettings(data: Partial): Promise; - deleteSettings(): Promise; + deleteSettings(params?: SettingsCRUDDeleteParams): Promise; /** * Lifecycle Events */ From 5b235ad24477db4d197f668b743292f9cf685c27 Mon Sep 17 00:00:00 2001 From: Vitalii Nobis Date: Mon, 16 Oct 2023 12:31:07 +0000 Subject: [PATCH 3/5] fix: page builder changes --- .../src/graphql/crud/categories.crud.ts | 9 ++++---- .../src/graphql/crud/settings.crud.ts | 8 +++---- .../api-page-builder/src/graphql/index.ts | 3 ++- .../api-page-builder/src/graphql/types.ts | 8 +++++-- .../api-page-builder/src/plugins/index.ts | 1 + .../createInitialPageCategoryForNewLocale.ts | 16 ++++++++++++++ .../settings/createSettingsForNewLocale.ts | 22 +++++++++++++++++++ .../src/plugins/settings/index.ts | 4 ++++ .../views/locales/hooks/useLocaleForm.ts | 2 +- 9 files changed, 61 insertions(+), 12 deletions(-) create mode 100644 packages/api-page-builder/src/plugins/settings/createInitialPageCategoryForNewLocale.ts create mode 100644 packages/api-page-builder/src/plugins/settings/createSettingsForNewLocale.ts create mode 100644 packages/api-page-builder/src/plugins/settings/index.ts diff --git a/packages/api-page-builder/src/graphql/crud/categories.crud.ts b/packages/api-page-builder/src/graphql/crud/categories.crud.ts index 7f0edaf50a1..220d683be72 100644 --- a/packages/api-page-builder/src/graphql/crud/categories.crud.ts +++ b/packages/api-page-builder/src/graphql/crud/categories.crud.ts @@ -85,13 +85,13 @@ export const createCategoriesCrud = (params: CreateCategoriesCrudParams): Catego * This method should return category or null. No error throwing on not found. */ async getCategory(slug, options = { auth: true }) { - const { auth } = options; + const { auth, locale } = options; const params: CategoryStorageOperationsGetParams = { where: { slug, tenant: getTenantId(), - locale: getLocaleCode() + locale: locale || getLocaleCode() } }; @@ -177,7 +177,8 @@ export const createCategoriesCrud = (params: CreateCategoriesCrudParams): Catego } const existingCategory = await this.getCategory(input.slug, { - auth: false + auth: false, + locale: input.locale }); if (existingCategory) { throw new NotFoundError(`Category with slug "${input.slug}" already exists.`); @@ -196,7 +197,7 @@ export const createCategoriesCrud = (params: CreateCategoriesCrudParams): Catego displayName: identity.displayName }, tenant: getTenantId(), - locale: getLocaleCode() + locale: input.locale || getLocaleCode() }; try { diff --git a/packages/api-page-builder/src/graphql/crud/settings.crud.ts b/packages/api-page-builder/src/graphql/crud/settings.crud.ts index ec486d034da..4e3e2570b0f 100644 --- a/packages/api-page-builder/src/graphql/crud/settings.crud.ts +++ b/packages/api-page-builder/src/graphql/crud/settings.crud.ts @@ -91,7 +91,7 @@ export const createSettingsCrud = (params: CreateSettingsCrudParams): SettingsCr } }); }, - async getSettings(this: PageBuilderContextObject) { + async getSettings(this: PageBuilderContextObject, options) { // With this line commented, we made this endpoint public. // We did this because of the public website pages which need to access the settings. // It's possible we'll create another GraphQL field, made for this exact purpose. @@ -99,7 +99,7 @@ export const createSettingsCrud = (params: CreateSettingsCrudParams): SettingsCr const key = { tenant: getTenantId(), - locale: getLocaleCode() + locale: options?.locale || getLocaleCode() }; try { @@ -119,11 +119,11 @@ export const createSettingsCrud = (params: CreateSettingsCrudParams): SettingsCr async updateSettings(this: PageBuilderContextObject, input) { const params = { tenant: getTenantId(), - locale: getLocaleCode(), + locale: input.locale || getLocaleCode(), type: SETTINGS_TYPE.DEFAULT }; - let original = await this.getSettings(); + let original = await this.getSettings({ locale: params.locale }); if (!original) { const data: SettingsStorageOperationsCreateParams = { input: input, diff --git a/packages/api-page-builder/src/graphql/index.ts b/packages/api-page-builder/src/graphql/index.ts index 559cb76e829..2bd9065ccb8 100644 --- a/packages/api-page-builder/src/graphql/index.ts +++ b/packages/api-page-builder/src/graphql/index.ts @@ -4,6 +4,7 @@ import { GraphQLSchemaPlugin } from "@webiny/handler-graphql/types"; import { createCrud, CreateCrudParams } from "./crud"; import graphql from "./graphql"; import { createElementProcessors } from "~/graphql/elementProcessors"; +import settingsPlugins from "~/plugins/settings"; export const createPageBuilderGraphQL = (): GraphQLSchemaPlugin[] => { return graphql(); @@ -11,5 +12,5 @@ export const createPageBuilderGraphQL = (): GraphQLSchemaPlugin[] => { export type ContextParams = CreateCrudParams; export const createPageBuilderContext = (params: ContextParams) => { - return [createCrud(params), createElementProcessors()]; + return [createCrud(params), createElementProcessors(), settingsPlugins]; }; diff --git a/packages/api-page-builder/src/graphql/types.ts b/packages/api-page-builder/src/graphql/types.ts index 55edd85edee..7b4967e4a44 100644 --- a/packages/api-page-builder/src/graphql/types.ts +++ b/packages/api-page-builder/src/graphql/types.ts @@ -423,7 +423,10 @@ export interface OnCategoryAfterDeleteTopicParams { * @category Categories */ export interface CategoriesCrud { - getCategory(slug: string, options?: { auth: boolean }): Promise; + getCategory( + slug: string, + options?: { auth: boolean; locale?: string } + ): Promise; listCategories(): Promise; createCategory(data: PbCategoryInput): Promise; updateCategory(slug: string, data: PbCategoryInput): Promise; @@ -576,7 +579,7 @@ export interface MenusCrud { * The options passed into the crud methods */ export interface DefaultSettingsCrudOptions { - tenant: string | false | undefined; + tenant?: string | false; locale: string | false; } @@ -1051,6 +1054,7 @@ export interface PbCategoryInput { slug: string; url: string; layout: string; + locale?: string; } export interface PbUpdatePageInput { diff --git a/packages/api-page-builder/src/plugins/index.ts b/packages/api-page-builder/src/plugins/index.ts index aaffe3bd236..346b005c360 100644 --- a/packages/api-page-builder/src/plugins/index.ts +++ b/packages/api-page-builder/src/plugins/index.ts @@ -1,3 +1,4 @@ +export * from "./settings"; export * from "./ContentCompressionPlugin"; export * from "./JsonpackContentCompressionPlugin"; export * from "./PageBuilderPageValidationModifierPlugin"; diff --git a/packages/api-page-builder/src/plugins/settings/createInitialPageCategoryForNewLocale.ts b/packages/api-page-builder/src/plugins/settings/createInitialPageCategoryForNewLocale.ts new file mode 100644 index 00000000000..0a09d18840d --- /dev/null +++ b/packages/api-page-builder/src/plugins/settings/createInitialPageCategoryForNewLocale.ts @@ -0,0 +1,16 @@ +import { ContextPlugin } from "@webiny/api"; +import { PbContext } from "~/types"; + +export const createInitialPageCategoryForNewLocale = new ContextPlugin(context => { + context.i18n.locales.onLocaleAfterCreate.subscribe(async ({ locale }) => { + try { + await context.pageBuilder.createCategory({ + name: "Static", + slug: "static", + url: "/static/", + layout: "static", + locale: locale.code + }); + } catch {} + }); +}); diff --git a/packages/api-page-builder/src/plugins/settings/createSettingsForNewLocale.ts b/packages/api-page-builder/src/plugins/settings/createSettingsForNewLocale.ts new file mode 100644 index 00000000000..6cb650be3fb --- /dev/null +++ b/packages/api-page-builder/src/plugins/settings/createSettingsForNewLocale.ts @@ -0,0 +1,22 @@ +import { ContextPlugin } from "@webiny/api"; +import { PbContext } from "~/types"; + +export const createSettingsForNewLocale = new ContextPlugin(context => { + context.i18n.locales.onLocaleAfterCreate.subscribe(async ({ locale }) => { + const existingSettings = await context.pageBuilder.getSettings({ + locale: locale.code + }); + + if (!existingSettings) { + const currentLocaleSettings = await context.pageBuilder.getSettings(); + await context.pageBuilder.updateSettings({ + ...currentLocaleSettings, + pages: { + home: null, + notFound: null + }, + locale: locale.code + }); + } + }); +}); diff --git a/packages/api-page-builder/src/plugins/settings/index.ts b/packages/api-page-builder/src/plugins/settings/index.ts new file mode 100644 index 00000000000..48f39372b77 --- /dev/null +++ b/packages/api-page-builder/src/plugins/settings/index.ts @@ -0,0 +1,4 @@ +import { createInitialPageCategoryForNewLocale } from "./createInitialPageCategoryForNewLocale"; +import { createSettingsForNewLocale } from "./createSettingsForNewLocale"; + +export default [createInitialPageCategoryForNewLocale, createSettingsForNewLocale]; diff --git a/packages/app-i18n/src/admin/views/locales/hooks/useLocaleForm.ts b/packages/app-i18n/src/admin/views/locales/hooks/useLocaleForm.ts index db833ea6726..847e4d1a961 100644 --- a/packages/app-i18n/src/admin/views/locales/hooks/useLocaleForm.ts +++ b/packages/app-i18n/src/admin/views/locales/hooks/useLocaleForm.ts @@ -65,7 +65,7 @@ export const useLocaleForm = (): UseLocaleForm => { !isUpdate && history.push(`/i18n/locales?code=${data.code}`); showSnackbar(t`Locale saved successfully.`); - refetchLocales(); + await refetchLocales(); // Reload page window.location.reload(); }, From 77dfdefc14650a81f3792cd48e31b57e1465649a Mon Sep 17 00:00:00 2001 From: Vitalii Nobis Date: Mon, 16 Oct 2023 13:02:08 +0000 Subject: [PATCH 4/5] fix: fix types --- .../src/operations/settings/index.ts | 4 ++-- .../api-page-builder-so-ddb/src/operations/settings/index.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/api-page-builder-so-ddb-es/src/operations/settings/index.ts b/packages/api-page-builder-so-ddb-es/src/operations/settings/index.ts index d01f93afdda..380a88b5071 100644 --- a/packages/api-page-builder-so-ddb-es/src/operations/settings/index.ts +++ b/packages/api-page-builder-so-ddb-es/src/operations/settings/index.ts @@ -16,8 +16,8 @@ import WebinyError from "@webiny/error"; * it in consideration and create the partition key for the global settings. */ interface PartitionKeyParams { - tenant: string | boolean | undefined; - locale: string | boolean | undefined; + tenant?: string | boolean; + locale?: string | boolean; } const createPartitionKey = (params: PartitionKeyParams): string => { diff --git a/packages/api-page-builder-so-ddb/src/operations/settings/index.ts b/packages/api-page-builder-so-ddb/src/operations/settings/index.ts index d01f93afdda..380a88b5071 100644 --- a/packages/api-page-builder-so-ddb/src/operations/settings/index.ts +++ b/packages/api-page-builder-so-ddb/src/operations/settings/index.ts @@ -16,8 +16,8 @@ import WebinyError from "@webiny/error"; * it in consideration and create the partition key for the global settings. */ interface PartitionKeyParams { - tenant: string | boolean | undefined; - locale: string | boolean | undefined; + tenant?: string | boolean; + locale?: string | boolean; } const createPartitionKey = (params: PartitionKeyParams): string => { From f876759488941b00de50a5bd7eb36bca759675e9 Mon Sep 17 00:00:00 2001 From: Vitalii Nobis Date: Fri, 20 Oct 2023 13:48:47 +0000 Subject: [PATCH 5/5] feat: add delete page builder settings crud option --- .../src/operations/settings/index.ts | 23 +++++++++- .../src/operations/settings/index.ts | 23 +++++++++- packages/api-page-builder/src/graphql/crud.ts | 7 ++++ .../src/graphql/crud/settings.crud.ts | 42 ++++++++++++++++++- .../api-page-builder/src/graphql/types.ts | 17 +++++++- .../deleteSettingsForDeletedLocale.ts | 8 ++++ .../src/plugins/settings/index.ts | 7 +++- packages/api-page-builder/src/types.ts | 8 ++++ 8 files changed, 130 insertions(+), 5 deletions(-) create mode 100644 packages/api-page-builder/src/plugins/settings/deleteSettingsForDeletedLocale.ts diff --git a/packages/api-page-builder-so-ddb-es/src/operations/settings/index.ts b/packages/api-page-builder-so-ddb-es/src/operations/settings/index.ts index 380a88b5071..9e374a39d32 100644 --- a/packages/api-page-builder-so-ddb-es/src/operations/settings/index.ts +++ b/packages/api-page-builder-so-ddb-es/src/operations/settings/index.ts @@ -5,7 +5,8 @@ import { SettingsStorageOperations, SettingsStorageOperationsCreateParams, SettingsStorageOperationsGetParams, - SettingsStorageOperationsUpdateParams + SettingsStorageOperationsUpdateParams, + SettingsStorageOperationsDeleteParams } from "@webiny/api-page-builder/types"; import { Entity } from "dynamodb-toolbox"; import { get as getRecord } from "@webiny/db-dynamodb/utils/get"; @@ -144,6 +145,25 @@ export const createSettingsStorageOperations = ({ ); } }; + + const deleteSettings = async (params: SettingsStorageOperationsDeleteParams) => { + const { settings } = params; + const keys = { + PK: createPartitionKey(settings), + SK: "A" + }; + try { + await entity.delete(keys); + } catch (ex) { + throw new WebinyError( + ex.message || "Could not delete the settings record by given keys.", + ex.code || "DELETE_SETTINGS_ERROR", + { + keys + } + ); + } + }; /** * We can simply return the partition key for this storage operations. */ @@ -156,6 +176,7 @@ export const createSettingsStorageOperations = ({ getDefaults, create, update, + delete: deleteSettings, createCacheKey }; }; diff --git a/packages/api-page-builder-so-ddb/src/operations/settings/index.ts b/packages/api-page-builder-so-ddb/src/operations/settings/index.ts index 380a88b5071..9e374a39d32 100644 --- a/packages/api-page-builder-so-ddb/src/operations/settings/index.ts +++ b/packages/api-page-builder-so-ddb/src/operations/settings/index.ts @@ -5,7 +5,8 @@ import { SettingsStorageOperations, SettingsStorageOperationsCreateParams, SettingsStorageOperationsGetParams, - SettingsStorageOperationsUpdateParams + SettingsStorageOperationsUpdateParams, + SettingsStorageOperationsDeleteParams } from "@webiny/api-page-builder/types"; import { Entity } from "dynamodb-toolbox"; import { get as getRecord } from "@webiny/db-dynamodb/utils/get"; @@ -144,6 +145,25 @@ export const createSettingsStorageOperations = ({ ); } }; + + const deleteSettings = async (params: SettingsStorageOperationsDeleteParams) => { + const { settings } = params; + const keys = { + PK: createPartitionKey(settings), + SK: "A" + }; + try { + await entity.delete(keys); + } catch (ex) { + throw new WebinyError( + ex.message || "Could not delete the settings record by given keys.", + ex.code || "DELETE_SETTINGS_ERROR", + { + keys + } + ); + } + }; /** * We can simply return the partition key for this storage operations. */ @@ -156,6 +176,7 @@ export const createSettingsStorageOperations = ({ getDefaults, create, update, + delete: deleteSettings, createCacheKey }; }; diff --git a/packages/api-page-builder/src/graphql/crud.ts b/packages/api-page-builder/src/graphql/crud.ts index 2444bce6b75..e124bde2250 100644 --- a/packages/api-page-builder/src/graphql/crud.ts +++ b/packages/api-page-builder/src/graphql/crud.ts @@ -120,6 +120,12 @@ const setup = (params: CreateCrudParams) => { fullAccessPermissionName: "pb.*" }); + const settingsPermissions = new PageTemplatesPermissions({ + getIdentity: context.security.getIdentity, + getPermissions: () => context.security.getPermissions("pb.settings"), + fullAccessPermissionName: "pb.*" + }); + const system = await createSystemCrud({ context, storageOperations, @@ -129,6 +135,7 @@ const setup = (params: CreateCrudParams) => { const settings = createSettingsCrud({ context, storageOperations, + settingsPermissions, getTenantId, getLocaleCode }); diff --git a/packages/api-page-builder/src/graphql/crud/settings.crud.ts b/packages/api-page-builder/src/graphql/crud/settings.crud.ts index 4e3e2570b0f..b3a668fae20 100644 --- a/packages/api-page-builder/src/graphql/crud/settings.crud.ts +++ b/packages/api-page-builder/src/graphql/crud/settings.crud.ts @@ -1,6 +1,8 @@ import { OnSettingsAfterUpdateTopicParams, OnSettingsBeforeUpdateTopicParams, + OnSettingsAfterDeleteTopicParams, + OnSettingsBeforeDeleteTopicParams, PageBuilderContextObject, PageBuilderStorageOperations, PageSpecialType, @@ -17,6 +19,7 @@ import lodashGet from "lodash/get"; import DataLoader from "dataloader"; import { createTopic } from "@webiny/pubsub"; import { createSettingsCreateValidation } from "~/graphql/crud/settings/validation"; +import { PageTemplatesPermissions } from "~/graphql/crud/permissions/PageTemplatesPermissions"; import { createZodError, removeUndefinedValues } from "@webiny/utils"; interface SettingsParams { @@ -35,12 +38,13 @@ enum SETTINGS_TYPE { export interface CreateSettingsCrudParams { context: PbContext; storageOperations: PageBuilderStorageOperations; + settingsPermissions: PageTemplatesPermissions; getTenantId: () => string; getLocaleCode: () => string; } export const createSettingsCrud = (params: CreateSettingsCrudParams): SettingsCrud => { - const { storageOperations, getLocaleCode, getTenantId } = params; + const { storageOperations, settingsPermissions, getLocaleCode, getTenantId } = params; const settingsDataLoader = new DataLoader( async keys => { @@ -57,6 +61,7 @@ export const createSettingsCrud = (params: CreateSettingsCrudParams): SettingsCr } ); + // create const onSettingsBeforeUpdate = createTopic( "pageBuilder.onSettingsBeforeUpdate" ); @@ -64,6 +69,14 @@ export const createSettingsCrud = (params: CreateSettingsCrudParams): SettingsCr "pageBuilder.onSettingsAfterUpdate" ); + // delete + const onSettingsBeforeDelete = createTopic( + "pageBuilder.onSettingsBeforeDelete" + ); + const onSettingsAfterDelete = createTopic( + "pageBuilder.onSettingsAfterDelete" + ); + return { /** * Lifecycle events - deprecated in 5.34.0 - will be removed in 5.36.0 @@ -75,6 +88,8 @@ export const createSettingsCrud = (params: CreateSettingsCrudParams): SettingsCr */ onSettingsBeforeUpdate, onSettingsAfterUpdate, + onSettingsBeforeDelete, + onSettingsAfterDelete, async getCurrentSettings(this: PageBuilderContextObject) { // With this line commented, we made this endpoint public. // We did this because of the public website pages which need to access the settings. @@ -247,6 +262,31 @@ export const createSettingsCrud = (params: CreateSettingsCrudParams): SettingsCr } ); } + }, + async deleteSettings(this: PageBuilderContextObject, params) { + const { locale } = params || {}; + await settingsPermissions.ensure({ rwd: "d" }); + + const settings = await this.getSettings({ locale }); + if (!settings) { + return; + } + try { + await onSettingsBeforeDelete.publish({ + settings + }); + + await storageOperations.settings.delete({ settings }); + + await onSettingsAfterDelete.publish({ + settings + }); + } catch (ex) { + throw new WebinyError( + ex.message || "Could not delete settings.", + ex.code || "DELETE_SETTINGS_ERROR" + ); + } } }; }; diff --git a/packages/api-page-builder/src/graphql/types.ts b/packages/api-page-builder/src/graphql/types.ts index 7b4967e4a44..4ec3208c5a4 100644 --- a/packages/api-page-builder/src/graphql/types.ts +++ b/packages/api-page-builder/src/graphql/types.ts @@ -580,7 +580,7 @@ export interface MenusCrud { */ export interface DefaultSettingsCrudOptions { tenant?: string | false; - locale: string | false; + locale?: string | false; } export interface SettingsUpdateTopicMetaParams { @@ -604,6 +604,18 @@ export interface OnSettingsAfterUpdateTopicParams { settings: Settings; meta: SettingsUpdateTopicMetaParams; } +/** + * @category Lifecycle events + */ +export interface OnSettingsBeforeDeleteTopicParams { + settings: Settings; +} +/** + * @category Lifecycle events + */ +export interface OnSettingsAfterDeleteTopicParams { + settings: Settings; +} /** * @category Settings @@ -618,6 +630,7 @@ export interface SettingsCrud { data: Record, options?: { auth?: boolean } & DefaultSettingsCrudOptions ) => Promise; + deleteSettings(params?: DefaultSettingsCrudOptions): Promise; /** * Lifecycle events - deprecated in 5.34.0 - will be removed in 5.36.0 */ @@ -634,6 +647,8 @@ export interface SettingsCrud { */ onSettingsBeforeUpdate: Topic; onSettingsAfterUpdate: Topic; + onSettingsBeforeDelete: Topic; + onSettingsAfterDelete: Topic; } /** diff --git a/packages/api-page-builder/src/plugins/settings/deleteSettingsForDeletedLocale.ts b/packages/api-page-builder/src/plugins/settings/deleteSettingsForDeletedLocale.ts new file mode 100644 index 00000000000..adde462f52d --- /dev/null +++ b/packages/api-page-builder/src/plugins/settings/deleteSettingsForDeletedLocale.ts @@ -0,0 +1,8 @@ +import { ContextPlugin } from "@webiny/api"; +import { PbContext } from "~/types"; + +export const deleteSettingsForDeletedLocale = new ContextPlugin(context => { + context.i18n.locales.onLocaleAfterDelete.subscribe(async ({ locale }) => { + await context.pageBuilder.deleteSettings({ locale: locale.code }); + }); +}); diff --git a/packages/api-page-builder/src/plugins/settings/index.ts b/packages/api-page-builder/src/plugins/settings/index.ts index 48f39372b77..675200a70c8 100644 --- a/packages/api-page-builder/src/plugins/settings/index.ts +++ b/packages/api-page-builder/src/plugins/settings/index.ts @@ -1,4 +1,9 @@ import { createInitialPageCategoryForNewLocale } from "./createInitialPageCategoryForNewLocale"; import { createSettingsForNewLocale } from "./createSettingsForNewLocale"; +import { deleteSettingsForDeletedLocale } from "./deleteSettingsForDeletedLocale"; -export default [createInitialPageCategoryForNewLocale, createSettingsForNewLocale]; +export default [ + createInitialPageCategoryForNewLocale, + createSettingsForNewLocale, + deleteSettingsForDeletedLocale +]; diff --git a/packages/api-page-builder/src/types.ts b/packages/api-page-builder/src/types.ts index c9cfcd6df25..7bc8d314ff6 100644 --- a/packages/api-page-builder/src/types.ts +++ b/packages/api-page-builder/src/types.ts @@ -454,6 +454,13 @@ export interface SettingsStorageOperationsUpdateParams { original: Settings; settings: Settings; } +/** + * @category StorageOperations + * @category SettingsStorageOperations + */ +export interface SettingsStorageOperationsDeleteParams { + settings: Settings; +} /** * @category StorageOperations * @category SettingsStorageOperations @@ -469,6 +476,7 @@ export interface SettingsStorageOperations { getDefaults: () => Promise; create: (params: SettingsStorageOperationsCreateParams) => Promise; update: (params: SettingsStorageOperationsUpdateParams) => Promise; + delete: (params: SettingsStorageOperationsDeleteParams) => Promise; } /**