Skip to content

Commit

Permalink
fix: Template block feedback bug fixes [CU-8692wq8w6] (#691)
Browse files Browse the repository at this point in the history
* Template title and description cleanup; button justification bug fix;

* RTE title and description update while in edit mode fix

* Button layout fix while block has no preview
  • Loading branch information
Ruslan Sazonov authored Nov 22, 2023
1 parent fd4bb6b commit de58b55
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 99 deletions.
84 changes: 40 additions & 44 deletions packages/template-block/src/TemplateBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,37 @@ import {
useBlockTemplates,
useEditorState,
} from '@frontify/app-bridge';
import { ReactElement, useEffect, useReducer, useState } from 'react';
import { ReactElement, useEffect, useState } from 'react';
import {
BlockInjectButton,
BlockProps,
TextStyles,
convertToRteValue,
getBackgroundColorStyles,
radiusStyleMap,
toRgbaString,
} from '@frontify/guideline-blocks-settings';
import { AnchoringType, PreviewType, Settings, TextPositioningType, textPositioningToFlexDirection } from './types';
import {
AnchoringType,
PreviewType,
Settings,
TextPositioningType,
justifyHorizontal,
textPositioningToFlexDirection,
} from './types';
import { GAP, TEMPLATE_BLOCK_SETTING_ID, VERTICAL_GAP } from './constants';
import { IconPlus24, merge } from '@frontify/fondue';
import { getCardPadding, getLayoutClasses } from './helpers/layoutHelper';
import { getCardPadding, getLayoutClasses, getRandomKey } from './helpers/layoutHelper';
import { TemplatePreview } from './components/TemplatePreview';
import { AlertError } from './components/AlertError';
import { TemplateDataActionType, templateDataReducer } from './reducers/templateDataReducer';
import { TemplateText } from './components/TemplateText';
import { CustomButton } from './components/CustomButton';

export const TemplateBlock = ({ appBridge }: BlockProps): ReactElement => {
const [blockSettings, updateBlockSettings] = useBlockSettings<Settings>(appBridge);
const [selectedTemplate, setSelectedTemplate] = useState<Template | null>(null);
const [lastErrorMessage, setLastErrorMessage] = useState('');
const [templateTextKey, setTemplateTextKey] = useState(getRandomKey());
const isEditing = useEditorState(appBridge);
const { blockAssets } = useBlockAssets(appBridge);
const { blockTemplates, updateTemplateIdsFromKey, error } = useBlockTemplates(appBridge);
Expand All @@ -58,11 +67,6 @@ export const TemplateBlock = ({ appBridge }: BlockProps): ReactElement => {
} = blockSettings;
const { previewCustom } = blockAssets;

const [{ templateTitle, templateDescription }, dispatch] = useReducer(templateDataReducer, {
templateTitle: title ?? '',
templateDescription: description ?? '',
});

const hasPreview = preview !== PreviewType.None;
const flexDirection = hasPreview ? textPositioningToFlexDirection[textPositioning] : 'row';
const isRows = hasPreview && (flexDirection === 'row' || flexDirection === 'row-reverse');
Expand All @@ -81,19 +85,9 @@ export const TemplateBlock = ({ appBridge }: BlockProps): ReactElement => {
};
}, []);

useEffect(() => {
updateBlockSettings({ title: templateTitle });
}, [templateTitle]);

useEffect(() => {
updateBlockSettings({ description: templateDescription });
}, [templateDescription]);

useEffect(() => {
if (error !== null) {
setLastErrorMessage(error);
dispatch({ type: TemplateDataActionType.UPDATE_TITLE, payload: { newValue: '' } });
dispatch({ type: TemplateDataActionType.UPDATE_DESCRIPTION, payload: { newValue: '' } });
}
}, [error]);

Expand All @@ -107,6 +101,18 @@ export const TemplateBlock = ({ appBridge }: BlockProps): ReactElement => {
}
}, [blockTemplates]);

const saveDescription = async (newDescription: string) => {
if (description !== newDescription) {
await updateBlockSettings({ description: newDescription });
}
};

const saveTitle = async (newTitle: string) => {
if (title !== newTitle) {
await updateBlockSettings({ title: convertToRteValue(TextStyles.heading3, newTitle) });
}
};

const handleNewPublication = async () => {
if (selectedTemplate !== null) {
const previewUrl =
Expand All @@ -126,22 +132,15 @@ export const TemplateBlock = ({ appBridge }: BlockProps): ReactElement => {
};

const onTemplateSelected = async (result: { template: TemplateLegacy }) => {
const { title, description } = blockSettings;

try {
await updateTemplateIdsFromKey(TEMPLATE_BLOCK_SETTING_ID, [result.template.id]);
updateBlockSettings({
template: result.template,
templateId: result.template.id,
});
dispatch({
type: TemplateDataActionType.UPDATE_TITLE,
payload: { newValue: result.template.title, prevValue: title },
});
dispatch({
type: TemplateDataActionType.UPDATE_DESCRIPTION,
payload: { newValue: result.template.description, prevValue: description },
});
await saveTitle(result.template.title);
await saveDescription(result.template.description);
setTemplateTextKey(getRandomKey());
} catch (error) {
setLastErrorMessage(error as string);
}
Expand Down Expand Up @@ -194,26 +193,23 @@ export const TemplateBlock = ({ appBridge }: BlockProps): ReactElement => {
<div className={merge(['tw-grow tw-min-w-0', !hasPreview && 'tw-col-span-2'])}>
<TemplateText
appBridge={appBridge}
title={templateTitle}
title={title}
blockSettings={blockSettings}
description={templateDescription}
description={description}
pageCount={selectedTemplate?.pages.length ?? 0}
isEditing={isEditing}
setTitle={(newValue, prevValue) =>
dispatch({
type: TemplateDataActionType.UPDATE_TITLE,
payload: { newValue, prevValue },
})
}
setDescription={(newValue, prevValue) =>
dispatch({
type: TemplateDataActionType.UPDATE_DESCRIPTION,
payload: { newValue, prevValue },
})
}
key={templateTextKey}
setTitle={saveTitle}
setDescription={saveDescription}
/>
</div>
<div className={merge(['', hasPreview && 'tw-flex tw-justify-end tw-items-start'])}>
<div
className={merge([
hasPreview
? justifyHorizontal[textAnchoringHorizontal]
: 'tw-flex tw-items-center tw-justify-end',
])}
>
<CustomButton
blockSettings={blockSettings}
isEditing={isEditing}
Expand Down
56 changes: 41 additions & 15 deletions packages/template-block/src/components/TemplateText.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
/* (c) Copyright Frontify Ltd., all rights reserved. */

import { useMemo } from 'react';
import React, { useMemo } from 'react';
import {
BlockStyles,
RichTextEditor,
TextStylePluginsWithoutImage,
TextStyles,
convertToRteValue,
getDefaultPluginsWithLinkChooser,
} from '@frontify/guideline-blocks-settings';
import { getTitlePlugin } from '../helpers/rtePlugin';
import { AppBridgeBlock } from '@frontify/app-bridge';
import { Settings } from '../types';
import {
AutoformatPlugin,
BoldPlugin,
ItalicPlugin,
PluginComposer,
ResetFormattingPlugin,
SoftBreakPlugin,
StrikethroughPlugin,
TextStylePlugin,
UnderlinePlugin,
} from '@frontify/fondue';

export type TemplateTextProps = {
appBridge: AppBridgeBlock;
Expand All @@ -19,8 +30,9 @@ export type TemplateTextProps = {
description: string;
pageCount: number | undefined;
isEditing: boolean;
setTitle: (newValue: string, prevValue?: string) => void;
setDescription: (newValue: string, prevValue?: string) => void;
key: number;
setTitle: (newTitle: string) => void;
setDescription: (newDescription: string) => void;
};

export const TemplateText = ({
Expand All @@ -29,38 +41,52 @@ export const TemplateText = ({
description,
pageCount,
isEditing,
key,
setTitle,
setDescription,
}: TemplateTextProps) => {
const pageCountStyles = BlockStyles[TextStyles.imageCaption];
const pageCountLabel = pageCount === 1 ? 'page' : 'pages';
const memoTitleRte = useMemo(() => {
return (

const customTitlePlugins = useMemo(() => {
return new PluginComposer()
.setPlugin([new SoftBreakPlugin(), new TextStylePlugin({ textStyles: TextStylePluginsWithoutImage })])
.setPlugin([new BoldPlugin(), new ItalicPlugin(), new UnderlinePlugin(), new StrikethroughPlugin()])
.setPlugin([new ResetFormattingPlugin(), new AutoformatPlugin()]);
}, []);

const memoTitleRte = useMemo(
() => (
<RichTextEditor
id="template-block-title"
value={title || convertToRteValue(TextStyles.heading3)}
key={key}
value={title ?? convertToRteValue(TextStyles.heading3)}
placeholder="Add a title"
onTextChange={setTitle}
isEditing={isEditing}
plugins={getTitlePlugin()}
plugins={customTitlePlugins}
/>
);
}, [title, isEditing, setTitle]);
),
[customTitlePlugins, isEditing, setTitle, title],
);

const memoDescriptionRte = useMemo(() => {
return (
const memoDescriptionRte = useMemo(
() => (
<RichTextEditor
id="template-block-description"
value={description || convertToRteValue()}
value={description}
key={key}
placeholder={
'Add a description that will be displayed in the block\n\nNote: When template description is available, it will be added by default'
}
onTextChange={setDescription}
isEditing={isEditing}
plugins={getDefaultPluginsWithLinkChooser(appBridge)}
/>
);
}, [description, isEditing, setDescription, appBridge]);
),
[appBridge, description, isEditing, setDescription],
);

return (
<div>
<div className="tw-mb-2">
Expand Down
4 changes: 4 additions & 0 deletions packages/template-block/src/helpers/layoutHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,7 @@ export const getLayoutClasses = (hasPreview: boolean, isRows: boolean) => {

return hasPreview ? previewClasses : 'tw-grid tw-grid-cols-3';
};

export const getRandomKey = () => {
return new Date().getTime();
};
40 changes: 0 additions & 40 deletions packages/template-block/src/helpers/rtePlugin.ts

This file was deleted.

6 changes: 6 additions & 0 deletions packages/template-block/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,9 @@ export const paddingStyleMap: Record<Padding, string> = {
[Padding.Medium]: '20px',
[Padding.Large]: '30px',
};

export const justifyHorizontal: Record<AnchoringType, string> = {
[AnchoringType.Start]: 'tw-justify-start',
[AnchoringType.Center]: 'tw-justify-center',
[AnchoringType.End]: 'tw-justify-end',
};

0 comments on commit de58b55

Please sign in to comment.