Skip to content

Commit

Permalink
feat: add checkbox in DescriptionForm to allow to add description abo…
Browse files Browse the repository at this point in the history
…ve (#1050)

* feat: add checkbox in DescriptionForm to allow to add description above

* feat: use select instead of checkbox for description placement

* feat: update query-client to 2.8.0

* feat: remove displaying description above folder

* feat: add description placement in settings and edit item

* test: add tests to verify description placement feature

* feat: remove description of the description's placement setting

---------

Co-authored-by: Kim Lan Phan Hoang <[email protected]>
  • Loading branch information
ReidyT and pyphilia authored Mar 7, 2024
1 parent 683e3af commit a38f27d
Show file tree
Hide file tree
Showing 15 changed files with 299 additions and 71 deletions.
12 changes: 12 additions & 0 deletions cypress/e2e/item/create/createFolder.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
CREATE_ITEM_BUTTON_ID,
ITEM_FORM_CONFIRM_BUTTON_ID,
ITEM_FORM_NAME_INPUT_ID,
ITEM_SETTING_DESCRIPTION_PLACEMENT_SELECT_ID,
buildItemsTableRowIdAttribute,
} from '../../../../src/config/selectors';
import ItemLayoutMode from '../../../../src/enums/itemLayoutMode';
Expand Down Expand Up @@ -52,6 +53,17 @@ describe('Create Folder', () => {
true,
);
});

it('description placement should not exist for folder', () => {
// create
cy.setUpApi();
cy.visit(HOME_PATH);
createFolder(CREATED_BLANK_NAME_ITEM, { confirm: false });

cy.get(`#${ITEM_SETTING_DESCRIPTION_PLACEMENT_SELECT_ID}`).should(
'not.exist',
);
});
});

describe('Grid', () => {
Expand Down
25 changes: 25 additions & 0 deletions cypress/e2e/item/edit/editFile.cy.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { DescriptionPlacement } from '@graasp/sdk';

import { HOME_PATH, buildItemPath } from '../../../../src/config/paths';
import {
EDIT_ITEM_MODAL_CANCEL_BUTTON_ID,
ITEM_FORM_CONFIRM_BUTTON_ID,
ITEM_SETTING_DESCRIPTION_PLACEMENT_SELECT_ID,
TEXT_EDITOR_CLASS,
buildDescriptionPlacementId,
buildEditButtonId,
} from '../../../../src/config/selectors';
import { ItemLayoutMode } from '../../../../src/enums';
Expand All @@ -28,6 +33,26 @@ describe('Edit File', () => {
});
});

it('edit description placement to above', () => {
const { id } = IMAGE_ITEM_DEFAULT;
cy.visit(buildItemPath(id));

cy.get(`#${buildEditButtonId(id)}`).click();

cy.get(`#${ITEM_SETTING_DESCRIPTION_PLACEMENT_SELECT_ID}`).click();
cy.get(
`#${buildDescriptionPlacementId(DescriptionPlacement.ABOVE)}`,
).click();
cy.get(`#${ITEM_FORM_CONFIRM_BUTTON_ID}`).click();

cy.wait(`@editItem`).then(({ request: { url, body } }) => {
expect(url).to.contain(id);
expect(body?.settings).to.contain({
descriptionPlacement: DescriptionPlacement.ABOVE,
});
});
});

it("edit s3File's caption", () => {
const { id } = VIDEO_ITEM_S3;
cy.visit(buildItemPath(id));
Expand Down
39 changes: 38 additions & 1 deletion cypress/e2e/item/settings/itemSettings.cy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { ItemType, MaxWidth, getFileExtra } from '@graasp/sdk';
import {
DescriptionPlacement,
ItemType,
MaxWidth,
getFileExtra,
} from '@graasp/sdk';
import { langs } from '@graasp/translations';

import { getMemberById } from '@/utils/member';
Expand All @@ -17,12 +22,14 @@ import {
ITEM_PANEL_NAME_ID,
ITEM_PANEL_TABLE_ID,
ITEM_SETTINGS_BUTTON_CLASS,
ITEM_SETTING_DESCRIPTION_PLACEMENT_SELECT_ID,
LANGUAGE_SELECTOR_ID,
SETTINGS_CHATBOX_TOGGLE_ID,
SETTINGS_LINK_SHOW_BUTTON_ID,
SETTINGS_LINK_SHOW_IFRAME_ID,
SETTINGS_PINNED_TOGGLE_ID,
SETTINGS_SAVE_ACTIONS_TOGGLE_ID,
buildDescriptionPlacementId,
} from '../../../../src/config/selectors';
import {
ITEM_WITH_CHATBOX_MESSAGES,
Expand Down Expand Up @@ -372,5 +379,35 @@ describe('Item Settings', () => {
);
});
});

describe('DescriptionPlacement Settings', () => {
it('folder should not have description placement', () => {
const { id, type } = ITEMS_SETTINGS.items[1];
cy.visit(buildItemSettingsPath(id));

cy.get(`#${ITEM_PANEL_TABLE_ID}`).contains(type);

cy.get(`#${ITEM_SETTING_DESCRIPTION_PLACEMENT_SELECT_ID}`).should(
'not.exist',
);
});

it('update placement to above for file', () => {
const { id } = IMAGE_ITEM_DEFAULT;
cy.visit(buildItemSettingsPath(id));

cy.get(`#${ITEM_SETTING_DESCRIPTION_PLACEMENT_SELECT_ID}`).click();
cy.get(
`#${buildDescriptionPlacementId(DescriptionPlacement.ABOVE)}`,
).click();

cy.wait(`@editItem`).then(({ request: { url, body } }) => {
expect(url).to.contain(id);
expect(body?.settings).to.contain({
descriptionPlacement: DescriptionPlacement.ABOVE,
});
});
});
});
});
});
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@
"@emotion/react": "11.11.4",
"@emotion/styled": "11.11.0",
"@graasp/chatbox": "3.1.0",
"@graasp/query-client": "2.7.1",
"@graasp/sdk": "4.0.1",
"@graasp/query-client": "2.8.0",
"@graasp/sdk": "4.1.0",
"@graasp/translations": "1.25.2",
"@graasp/ui": "4.8.5",
"@graasp/ui": "4.9.0",
"@mui/icons-material": "5.15.11",
"@mui/lab": "5.0.0-alpha.166",
"@mui/material": "5.15.11",
Expand Down
39 changes: 32 additions & 7 deletions src/components/item/form/DescriptionForm.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import { DiscriminatedItem } from '@graasp/sdk';
import { Stack } from '@mui/material';

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

import DescriptionPlacementForm from './DescriptionPlacementForm';

type DescriptionFormProps = {
id?: string;
item?: DiscriminatedItem;
Expand All @@ -20,13 +28,30 @@ const DescriptionForm = ({
});
};

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

return (
<TextEditor
id={id}
value={(updatedProperties?.description || item?.description) ?? ''}
onChange={onChange}
showActions={false}
/>
<Stack spacing={2}>
<TextEditor
id={id}
value={(updatedProperties?.description || item?.description) ?? ''}
onChange={onChange}
showActions={false}
/>

{updatedProperties.type !== ItemType.FOLDER && (
<DescriptionPlacementForm
updatedProperties={updatedProperties}
onPlacementChanged={onPlacementChanged}
/>
)}
</Stack>
);
};

Expand Down
66 changes: 66 additions & 0 deletions src/components/item/form/DescriptionPlacementForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { MenuItem, Select } from '@mui/material';

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

import { useBuilderTranslation } from '@/config/i18n';
import {
ITEM_SETTING_DESCRIPTION_PLACEMENT_SELECT_ID,
buildDescriptionPlacementId,
} from '@/config/selectors';
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)}
inputSetting={
<Select
id={ITEM_SETTING_DESCRIPTION_PLACEMENT_SELECT_ID}
value={
updatedProperties.settings?.descriptionPlacement ??
DEFAULT_PLACEMENT
}
onChange={(e) => handlePlacementChanged(e.target.value)}
size="small"
>
<MenuItem
id={buildDescriptionPlacementId(DescriptionPlacement.ABOVE)}
value={DescriptionPlacement.ABOVE}
>
{t(BUILDER.ITEM_SETTINGS_DESCRIPTION_PLACEMENT_ABOVE)}
</MenuItem>
<MenuItem
id={buildDescriptionPlacementId(DescriptionPlacement.BELOW)}
value={DescriptionPlacement.BELOW}
>
{t(BUILDER.ITEM_SETTINGS_DESCRIPTION_PLACEMENT_BELOW)}
</MenuItem>
</Select>
}
/>
);
};

export default DescriptionPlacementForm;
4 changes: 4 additions & 0 deletions src/components/item/form/EditModalWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ const EditModalWrapper = ({
extra: !isEqual(item.extra, updatedItem.extra)
? (updatedItem.extra as any)
: undefined,
// only patch settings it it has been changed
...(!isEqual(item.settings, updatedItem.settings)
? { settings: updatedItem.settings }
: {}),
});
}

Expand Down
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;
35 changes: 11 additions & 24 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;
valueText?: string;
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 @@ -33,21 +27,14 @@ const ItemSettingProperty = ({
{title}
</Typography>
</Stack>
<Stack>
<Typography variant="body2">{valueText}</Typography>
</Stack>
{valueText && (
<Stack>
<Typography variant="body2">{valueText}</Typography>
</Stack>
)}
</Stack>
</Stack>
<Stack>
<Switch
id={id}
disabled={disabled}
checked={checked}
onChange={(e) => {
onClick(e.target.checked);
}}
/>
</Stack>
<Stack>{inputSetting}</Stack>
</Stack>
);

Expand Down
Loading

0 comments on commit a38f27d

Please sign in to comment.