Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add checkbox in DescriptionForm to allow to add description above #1050

Merged
merged 8 commits into from
Mar 7, 2024
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