Skip to content

Commit

Permalink
feat: add description placement in settings and edit item
Browse files Browse the repository at this point in the history
  • Loading branch information
ReidyT committed Mar 6, 2024
1 parent 6324c02 commit 0c3d8c5
Show file tree
Hide file tree
Showing 8 changed files with 158 additions and 77 deletions.
51 changes: 13 additions & 38 deletions src/components/item/form/DescriptionForm.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,13 @@
import {
FormControl,
InputLabel,
MenuItem,
Select,
Stack,
} from '@mui/material';
import { Stack } from '@mui/material';

import {
DescriptionPlacement,
DescriptionPlacementType,
DiscriminatedItem,
ItemType,
} from '@graasp/sdk';
import TextEditor from '@graasp/ui/text-editor';

import { useBuilderTranslation } from '@/config/i18n';
import { BUILDER } from '@/langs/constants';

const DEFAULT_PLACEMENT = DescriptionPlacement.BELOW;
import DescriptionPlacementForm from './DescriptionPlacementForm';

type DescriptionFormProps = {
id?: string;
Expand All @@ -31,51 +22,35 @@ const DescriptionForm = ({
item,
setChanges,
}: DescriptionFormProps): JSX.Element => {
const { t } = useBuilderTranslation();

const onChange = (content: string): void => {
setChanges({
description: content,
});
};

const onPlacementChanged = (placement: string): void => {
const onPlacementChanged = (placement: DescriptionPlacementType): void => {
setChanges({
settings: {
descriptionPlacement: placement as DescriptionPlacementType,
descriptionPlacement: placement,
},
});
};

return (
<Stack>
<Stack spacing={2}>
<TextEditor
id={id}
value={(updatedProperties?.description || item?.description) ?? ''}
onChange={onChange}
showActions={false}
/>
<FormControl sx={{ mt: 2, minWidth: 120 }} size="small">
<InputLabel id="description-placement-label">
{t(BUILDER.ITEM_SETTINGS_DESCRIPTION_PLACEMENT_LABEL)}
</InputLabel>
<Select
labelId="description-placement-label"
value={
updatedProperties.settings?.descriptionPlacement ??
DEFAULT_PLACEMENT
}
label={t(BUILDER.ITEM_SETTINGS_DESCRIPTION_PLACEMENT_LABEL)}
onChange={(e) => onPlacementChanged(e.target.value)}
>
<MenuItem value={DescriptionPlacement.ABOVE}>
{t(BUILDER.ITEM_SETTINGS_DESCRIPTION_PLACEMENT_ABOVE)}
</MenuItem>
<MenuItem value={DescriptionPlacement.BELOW}>
{t(BUILDER.ITEM_SETTINGS_DESCRIPTION_PLACEMENT_BELOW)}
</MenuItem>
</Select>
</FormControl>

{updatedProperties.type !== ItemType.FOLDER && (
<DescriptionPlacementForm
updatedProperties={updatedProperties}
onPlacementChanged={onPlacementChanged}
/>
)}
</Stack>
);
};
Expand Down
56 changes: 56 additions & 0 deletions src/components/item/form/DescriptionPlacementForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { MenuItem, Select } from '@mui/material';

import {
DescriptionPlacement,
DescriptionPlacementType,
DiscriminatedItem,
} from '@graasp/sdk';

import { useBuilderTranslation } from '@/config/i18n';
import { BUILDER } from '@/langs/constants';

import ItemSettingProperty from '../settings/ItemSettingProperty';

const DEFAULT_PLACEMENT = DescriptionPlacement.BELOW;

type DescriptionPlacementFormProps = {
updatedProperties: Partial<DiscriminatedItem>;
onPlacementChanged: (payload: DescriptionPlacementType) => void;
};

const DescriptionPlacementForm = ({
updatedProperties,
onPlacementChanged,
}: DescriptionPlacementFormProps): JSX.Element | null => {
const { t } = useBuilderTranslation();

const handlePlacementChanged = (placement: string): void => {
onPlacementChanged(placement as DescriptionPlacementType);
};

return (
<ItemSettingProperty
title={t(BUILDER.ITEM_SETTINGS_DESCRIPTION_PLACEMENT_TITLE)}
valueText={t(BUILDER.ITEM_SETTINGS_DESCRIPTION_PLACEMENT_TEXT)}
inputSetting={
<Select
value={
updatedProperties.settings?.descriptionPlacement ??
DEFAULT_PLACEMENT
}
onChange={(e) => handlePlacementChanged(e.target.value)}
size="small"
>
<MenuItem value={DescriptionPlacement.ABOVE}>
{t(BUILDER.ITEM_SETTINGS_DESCRIPTION_PLACEMENT_ABOVE)}
</MenuItem>
<MenuItem value={DescriptionPlacement.BELOW}>
{t(BUILDER.ITEM_SETTINGS_DESCRIPTION_PLACEMENT_BELOW)}
</MenuItem>
</Select>
}
/>
);
};

export default DescriptionPlacementForm;
41 changes: 41 additions & 0 deletions src/components/item/settings/ItemSettingCheckBoxProperty.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Switch } from '@mui/material';

import ItemSettingProperty from './ItemSettingProperty';

type Props = {
onClick: (checked: boolean) => void;
title: string;
checked: boolean;
valueText: string;
id?: string;
disabled?: boolean;
icon?: JSX.Element;
};

const ItemSettingCheckBoxProperty = ({
onClick,
title,
checked = false,
id,
disabled,
icon,
valueText,
}: Props): JSX.Element => (
<ItemSettingProperty
title={title}
valueText={valueText}
icon={icon}
inputSetting={
<Switch
id={id}
disabled={disabled}
checked={checked}
onChange={(e) => {
onClick(e.target.checked);
}}
/>
}
/>
);

export default ItemSettingCheckBoxProperty;
25 changes: 5 additions & 20 deletions src/components/item/settings/ItemSettingProperty.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
import { Stack, Switch, Typography } from '@mui/material';
import { Stack, Typography } from '@mui/material';

type Props = {
onClick: (checked: boolean) => void;
title: string;
checked: boolean;
valueText: string;
id?: string;
disabled?: boolean;
inputSetting: JSX.Element;
icon?: JSX.Element;
};

const ItemSettingProperty = ({
onClick,
title,
checked = false,
id,
disabled,
icon,
valueText,
inputSetting,
icon,
}: Props): JSX.Element => (
<Stack
direction="row"
Expand All @@ -38,16 +32,7 @@ const ItemSettingProperty = ({
</Stack>
</Stack>
</Stack>
<Stack>
<Switch
id={id}
disabled={disabled}
checked={checked}
onChange={(e) => {
onClick(e.target.checked);
}}
/>
</Stack>
<Stack>{inputSetting}</Stack>
</Stack>
);

Expand Down
42 changes: 31 additions & 11 deletions src/components/item/settings/ItemSettingsProperties.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,28 @@ import {
} from '@/config/selectors';
import { BUILDER } from '@/langs/constants';

import DescriptionPlacementForm from '../form/DescriptionPlacementForm';
import FileSettings from './FileSettings';
import ItemSettingProperty from './ItemSettingProperty';
import ItemSettingCheckBoxProperty from './ItemSettingCheckBoxProperty';
import LinkSettings from './LinkSettings';

type Props = {
item: DiscriminatedItem;
};

type ItemSetting = DiscriminatedItem['settings'];

const ItemSettingsProperties = ({ item }: Props): JSX.Element => {
const { t: translateBuilder } = useBuilderTranslation();
const { mutate: editItem } = mutations.useEditItem();

const { settings } = item;

const handleOnToggle = (
event: { target: { checked: boolean } },
settingKey: string,
): void => {
const newValue = event.target.checked;
// TODO: remove | string in settingKey when enableAnalytics is added to settings in SDK...
const handleSettingChanged = <K extends keyof ItemSetting>(
settingKey: K | string,
newValue: unknown,
) => {
editItem({
id: item.id,
name: item.name,
Expand All @@ -46,6 +49,13 @@ const ItemSettingsProperties = ({ item }: Props): JSX.Element => {
});
};

const handleOnToggle = <K extends keyof ItemSetting>(
event: { target: { checked: boolean } },
settingKey: K | string,
): void => {
handleSettingChanged(settingKey, event.target.checked);
};

const renderSettingsPerType = () => {
switch (item.type) {
case ItemType.LINK:
Expand All @@ -55,7 +65,7 @@ const ItemSettingsProperties = ({ item }: Props): JSX.Element => {
return <FileSettings item={item} />;
case ItemType.APP:
return (
<ItemSettingProperty
<ItemSettingCheckBoxProperty
id={SETTINGS_RESIZE_TOGGLE_ID}
title={translateBuilder(
BUILDER.ITEM_SETTINGS_RESIZABLE_ENABLED_TEXT,
Expand Down Expand Up @@ -83,7 +93,7 @@ const ItemSettingsProperties = ({ item }: Props): JSX.Element => {
<Typography variant="h6" mt={3}>
{translateBuilder(BUILDER.SETTINGS_TITLE)}
</Typography>
<ItemSettingProperty
<ItemSettingCheckBoxProperty
title={translateBuilder(BUILDER.ITEM_SETTINGS_IS_COLLAPSED_TITLE)}
icon={<CollapseButton type={ActionButton.ICON} item={item} />}
checked={Boolean(settings.isCollapsible)}
Expand All @@ -105,7 +115,7 @@ const ItemSettingsProperties = ({ item }: Props): JSX.Element => {
})()}
/>

<ItemSettingProperty
<ItemSettingCheckBoxProperty
id={SETTINGS_PINNED_TOGGLE_ID}
icon={
<PinButton
Expand All @@ -125,7 +135,7 @@ const ItemSettingsProperties = ({ item }: Props): JSX.Element => {
}
/>

<ItemSettingProperty
<ItemSettingCheckBoxProperty
icon={
<ChatboxButton
showChat={Boolean(settings.showChatbox)}
Expand All @@ -144,20 +154,30 @@ const ItemSettingsProperties = ({ item }: Props): JSX.Element => {
: translateBuilder(BUILDER.ITEM_SETTINGS_SHOW_CHAT_DISABLED_TEXT)
}
/>
<ItemSettingProperty
<ItemSettingCheckBoxProperty
id={SETTINGS_SAVE_ACTIONS_TOGGLE_ID}
title={translateBuilder(BUILDER.SETTINGS_SAVE_ACTIONS)}
checked={Boolean(
settings?.enableSaveActions ?? DEFAULT_SAVE_ACTIONS_SETTING,
)}
onClick={(checked: boolean): void => {
// TODO: add enableAnalytics in the ItemSettings type
handleOnToggle({ target: { checked } }, 'enableAnalytics');
}}
valueText="Coming soon"
disabled
/>

{renderSettingsPerType()}

{item.type !== ItemType.FOLDER && (
<DescriptionPlacementForm
updatedProperties={item}
onPlacementChanged={(newPlacement) =>
handleSettingChanged('descriptionPlacement', newPlacement)
}
/>
)}
</>
);
};
Expand Down
6 changes: 4 additions & 2 deletions src/langs/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,8 @@ export const BUILDER = {
'ITEM_SETTINGS_DESCRIPTION_PLACEMENT_ABOVE',
ITEM_SETTINGS_DESCRIPTION_PLACEMENT_BELOW:
'ITEM_SETTINGS_DESCRIPTION_PLACEMENT_BELOW',
ITEM_SETTINGS_DESCRIPTION_PLACEMENT_LABEL:
'ITEM_SETTINGS_DESCRIPTION_PLACEMENT_LABEL',
ITEM_SETTINGS_DESCRIPTION_PLACEMENT_TITLE:
'ITEM_SETTINGS_DESCRIPTION_PLACEMENT_TITLE',
ITEM_SETTINGS_DESCRIPTION_PLACEMENT_TEXT:
'ITEM_SETTINGS_DESCRIPTION_PLACEMENT_TEXT',
};
7 changes: 4 additions & 3 deletions src/langs/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,8 @@
"ITEM_SETTINGS_IS_COLLAPSED_DISABLED_TEXT": "This item is not collapsed",
"ITEM_SETTINGS_IS_COLLAPSED_ENABLED_TEXT": "This item is collapsed",
"ITEM_SETTINGS_IS_COLLAPSED_TITLE": "Collapse item",
"ITEM_SETTINGS_DESCRIPTION_PLACEMENT_ABOVE": "Display the description above the content",
"ITEM_SETTINGS_DESCRIPTION_PLACEMENT_BELOW": "Display the description below the content",
"ITEM_SETTINGS_DESCRIPTION_PLACEMENT_LABEL": "Placement of the description"
"ITEM_SETTINGS_DESCRIPTION_PLACEMENT_ABOVE": "Above the content",
"ITEM_SETTINGS_DESCRIPTION_PLACEMENT_BELOW": "Below the content",
"ITEM_SETTINGS_DESCRIPTION_PLACEMENT_TITLE": "Placement",
"ITEM_SETTINGS_DESCRIPTION_PLACEMENT_TEXT": "Placement of the description"
}
7 changes: 4 additions & 3 deletions src/langs/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,8 @@
"ITEM_SETTINGS_IS_COLLAPSED_DISABLED_TEXT": "Cet élément n'est pas minifié",
"ITEM_SETTINGS_IS_COLLAPSED_ENABLED_TEXT": "Cet élément est minifié",
"ITEM_SETTINGS_IS_COLLAPSED_TITLE": "Minifier un élément",
"ITEM_SETTINGS_DESCRIPTION_PLACEMENT_ABOVE": "Afficher la description au-dessus du contenu",
"ITEM_SETTINGS_DESCRIPTION_PLACEMENT_BELOW": "Afficher la description en-dessous du contenu",
"ITEM_SETTINGS_DESCRIPTION_PLACEMENT_LABEL": "Placement de la description"
"ITEM_SETTINGS_DESCRIPTION_PLACEMENT_ABOVE": "Au-dessus du contenu",
"ITEM_SETTINGS_DESCRIPTION_PLACEMENT_BELOW": "En-dessous du contenu",
"ITEM_SETTINGS_DESCRIPTION_PLACEMENT_TITLE": "Placement",
"ITEM_SETTINGS_DESCRIPTION_PLACEMENT_TEXT": "Placement de la description"
}

0 comments on commit 0c3d8c5

Please sign in to comment.