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(ui): create separate pages for item share, publish and settings #971

Merged
merged 5 commits into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 29 additions & 6 deletions cypress/e2e/item/share/shareItem.cy.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Context, ShortLink, appendPathToUrl } from '@graasp/sdk';

import { buildItemPath } from '@/config/paths';
import { buildItemPath, buildItemSharePath } from '@/config/paths';
import { ShortLinkPlatform } from '@/utils/shortLink';

import {
Expand All @@ -19,12 +19,17 @@ import {
buildGraaspPlayerView,
} from '../../../support/paths';

const checkContainPlatformText = (platform: ShortLinkPlatform) =>
cy
.get(`#${buildShortLinkPlatformTextId(platform)}`)
.should('contain', platform);
export const checkContainPlatformText = (platform: ShortLinkPlatform): void => {
cy.get(`#${buildShortLinkPlatformTextId(platform)}`).should(
'contain',
platform,
);
};

const checkContainUrlText = (platform: ShortLinkPlatform, itemId: string) => {
export const checkContainUrlText = (
platform: ShortLinkPlatform,
itemId: string,
): void => {
let expectedUrl;

// The client host manager can't be used here because
Expand Down Expand Up @@ -191,4 +196,22 @@ describe('Share Item Link', () => {
cy.get(`#${SHARE_ITEM_QR_DIALOG_ID}`).should('exist');
});
});

describe('Without short links', () => {
const item = PUBLISHED_ITEM;

beforeEach(() => {
cy.setUpApi({ items: [item] });
});

it('Builder link is correctly displayed', () => {
cy.visit(buildItemSharePath(item.id));

cy.get(`.${SHORT_LINK_COMPONENT}`).should('have.length', 3);

const context = Context.Builder;
checkContainPlatformText(context);
checkContainUrlText(context, item.id);
});
});
});
4 changes: 2 additions & 2 deletions cypress/e2e/item/thumbnails/uploadThumbnail.cy.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { buildItemPath } from '../../../../src/config/paths';
import {
CROP_MODAL_CONFIRM_BUTTON_CLASSNAME,
ITEM_SETTINGS_BUTTON_CLASS,
ITEM_INFORMATION_BUTTON_ID,
THUMBNAIL_SETTING_UPLOAD_BUTTON_CLASSNAME,
} from '../../../../src/config/selectors';
import {
Expand All @@ -18,7 +18,7 @@ describe('Upload Thumbnails', () => {
it(`upload item thumbnail`, () => {
const { items } = SAMPLE_ITEMS_WITH_THUMBNAILS;
cy.visit(buildItemPath(items[0].id));
cy.get(`.${ITEM_SETTINGS_BUTTON_CLASS}`).click();
cy.get(`#${ITEM_INFORMATION_BUTTON_ID}`).click();

// change item thumbnail
// selectFile ???
Expand Down
7 changes: 2 additions & 5 deletions cypress/e2e/item/view/viewFolder.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,14 @@ describe('View Folder', () => {
// should get current item
cy.wait('@getItem');

expectFolderViewScreenLayout({ item: SAMPLE_ITEMS.items[0] });

// should get children
cy.wait('@getChildren').then(({ response: { body } }) => {
// check all children are created and displayed
for (const item of body) {
cy.get(`#${buildItemCard(item.id)}`).should('exist');
}
});
expectFolderViewScreenLayout({ item: SAMPLE_ITEMS.items[0] });

// visit home
cy.get(`#${NAVIGATION_ROOT_ID} [href="${HOME_PATH}"]`).click();
Expand Down Expand Up @@ -81,9 +80,6 @@ describe('View Folder', () => {

// should get current item
cy.wait('@getItem');

expectFolderViewScreenLayout({ item: SAMPLE_ITEMS.items[0] });

// should get children
cy.wait('@getChildren').then(({ response: { body } }) => {
// check all children are created and displayed
Expand All @@ -92,6 +88,7 @@ describe('View Folder', () => {
}
});

expectFolderViewScreenLayout({ item: SAMPLE_ITEMS.items[0] });
// visit home
cy.get(`#${NAVIGATION_ROOT_ID} [href="${HOME_PATH}"]`).click();

Expand Down
21 changes: 0 additions & 21 deletions cypress/e2e/memberships/viewMemberships.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {
ITEM_MEMBERSHIP_PERMISSION_SELECT_CLASS,
buildItemMembershipRowDeleteButtonId,
buildItemMembershipRowSelector,
buildMemberAvatarClass,
buildShareButtonId,
} from '../../../src/config/selectors';
import { membershipsWithoutUser } from '../../../src/utils/membership';
Expand All @@ -18,26 +17,6 @@ describe('View Memberships', () => {
cy.setUpApi({ ...ITEMS_WITH_MEMBERSHIPS });
});

it('view membership in share item modal', () => {
const [item] = ITEMS_WITH_MEMBERSHIPS.items;
const { memberships } = item;
cy.visit(buildItemPath(item.id));
cy.openMetadataPanel();

const filteredMemberships = membershipsWithoutUser(
memberships,
CURRENT_USER.id,
);

// panel only contains 2 avatars: one user, one +x
// check contains member avatar
const [first, second] = filteredMemberships;
cy.get(`.${buildMemberAvatarClass(first.member.id)}`).should('be.visible');
cy.get(`.${buildMemberAvatarClass(second.member.id)}`).should('be.visible');

// todo: check permission level
});

it('view membership in settings', () => {
const [item] = ITEMS_WITH_MEMBERSHIPS.items;
const { memberships } = item;
Expand Down
22 changes: 8 additions & 14 deletions cypress/support/viewUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import {
import {
DOCUMENT_ITEM_TEXT_EDITOR_SELECTOR,
ITEM_HEADER_ID,
ITEM_PANEL_ID,
ITEM_PANEL_NAME_ID,
ITEM_PANEL_TABLE_ID,
TEXT_EDITOR_CLASS,
Expand All @@ -36,21 +35,20 @@ const expectPanelLayout = ({ item }: { item: ItemForTest }) => {

const { name, creator } = item;

const panel = cy.get(`#${ITEM_PANEL_ID}`);
panel.get(`#${ITEM_PANEL_NAME_ID}`).contains(name);
cy.get(`#${ITEM_PANEL_NAME_ID}`).contains(name);

const creatorName = getMemberById(Object.values(MEMBERS), creator?.id).name;

panel.get(`#${ITEM_PANEL_TABLE_ID}`).should('exist').contains(creatorName);
cy.get(`#${ITEM_PANEL_TABLE_ID}`).should('exist').contains(creatorName);

if (item.type === ItemType.LOCAL_FILE || item.type === ItemType.S3_FILE) {
const { mimetype = 'invalid-mimetype', size = 'invalid-size' } =
item.type === ItemType.LOCAL_FILE
? getFileExtra(item.extra) || {}
: getS3FileExtra(item.extra) || {};
panel.get(`#${ITEM_PANEL_TABLE_ID}`).contains(mimetype);
cy.get(`#${ITEM_PANEL_TABLE_ID}`).contains(mimetype);

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

Expand Down Expand Up @@ -89,11 +87,10 @@ export const expectDocumentViewScreenLayout = ({
expect(editor.html()).to.contain(getDocumentExtra(item.extra)?.content);
});

expectItemHeaderLayout({ item, currentMember });
expectPanelLayout({
item,
});

expectItemHeaderLayout({ item, currentMember });
};

export const expectFileViewScreenLayout = ({
Expand All @@ -108,10 +105,9 @@ export const expectFileViewScreenLayout = ({

cy.get(`.${TEXT_EDITOR_CLASS}`).should('contain', item.description);

expectItemHeaderLayout({ item, currentMember });
// table
expectPanelLayout({ item });

expectItemHeaderLayout({ item, currentMember });
};

export const expectLinkViewScreenLayout = ({
Expand Down Expand Up @@ -143,10 +139,9 @@ export const expectLinkViewScreenLayout = ({
cy.get(`.${TEXT_EDITOR_CLASS}`).should('contain', description);
}

expectItemHeaderLayout({ item, currentMember });
// table
expectPanelLayout({ item });

expectItemHeaderLayout({ item, currentMember });
};

export const expectFolderViewScreenLayout = ({
Expand All @@ -157,7 +152,6 @@ export const expectFolderViewScreenLayout = ({
currentMember?: MemberForTest | null;
}): void => {
// table
expectPanelLayout({ item });

expectItemHeaderLayout({ item, currentMember });
expectPanelLayout({ item });
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"@graasp/query-client": "2.5.0",
"@graasp/sdk": "3.4.1",
"@graasp/translations": "1.22.1",
"@graasp/ui": "4.5.1",
"@graasp/ui": "4.6.1",
"@mui/icons-material": "5.14.19",
"@mui/lab": "5.0.0-alpha.151",
"@mui/material": "5.14.19",
Expand Down
24 changes: 23 additions & 1 deletion src/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import {
FAVORITE_ITEMS_PATH,
HOME_PATH,
ITEMS_PATH,
ITEM_INFORMATION_PATH,
ITEM_PUBLISH_PATH,
ITEM_SETTINGS_PATH,
ITEM_SHARE_PATH,
PUBLISHED_ITEMS_PATH,
RECYCLE_BIN_PATH,
REDIRECT_PATH,
Expand All @@ -23,10 +27,16 @@ import Main from './main/Main';
import Redirect from './main/Redirect';
import FavoriteItemsScreen from './pages/FavoriteItemsScreen';
import HomeScreen from './pages/HomeScreen';
import ItemScreen from './pages/ItemScreen';
import PublishedItemsScreen from './pages/PublishedItemsScreen';
import RecycledItemsScreen from './pages/RecycledItemsScreen';
import SharedItemsScreen from './pages/SharedItemsScreen';
import ItemInformationPage from './pages/item/ItemInformationPage';
import ItemPageLayout from './pages/item/ItemPageLayout';
import ItemScreen from './pages/item/ItemScreen';
import ItemScreenLayout from './pages/item/ItemScreenLayout';
import ItemSettingsPage from './pages/item/ItemSettingsPage';
import ItemSharingPage from './pages/item/ItemSharingPage';
import LibrarySettingsPage from './pages/item/LibrarySettingsPage';

const { useItemFeedbackUpdates } = hooks;

Expand Down Expand Up @@ -89,6 +99,18 @@ const App = (): JSX.Element => {
path={PUBLISHED_ITEMS_PATH}
element={<PublishedWithAuthorization />}
/>
<Route path={buildItemPath()} element={<ItemScreenLayout />}>
<Route index element={<ItemScreen />} />
<Route element={<ItemPageLayout />}>
<Route path={ITEM_SHARE_PATH} element={<ItemSharingPage />} />
<Route path={ITEM_PUBLISH_PATH} element={<LibrarySettingsPage />} />
<Route path={ITEM_SETTINGS_PATH} element={<ItemSettingsPage />} />
<Route
path={ITEM_INFORMATION_PATH}
element={<ItemInformationPage />}
/>
</Route>
</Route>
<Route path={RECYCLE_BIN_PATH} element={<RecycleWithAuthorization />} />
<Route path={buildItemPath()} element={<ItemScreen />} />
<Route path={ITEMS_PATH} element={<HomeWithAuthorization />} />
Expand Down
22 changes: 22 additions & 0 deletions src/components/common/BackButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import ArrowCircleLeftRoundedIcon from '@mui/icons-material/ArrowCircleLeftRounded';
import { IconButton, Tooltip } from '@mui/material';

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

interface Props {
onClick: () => void;
}
const BackButton = ({ onClick }: Props): JSX.Element => {
const { t } = useBuilderTranslation();

return (
<Tooltip title={t(BUILDER.BACK)}>
<IconButton onClick={onClick}>
<ArrowCircleLeftRoundedIcon fontSize="large" />
</IconButton>
</Tooltip>
);
};

export default BackButton;
40 changes: 13 additions & 27 deletions src/components/common/ItemMetadataButton.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,26 @@
import { Link } from 'react-router-dom';

import InfoIcon from '@mui/icons-material/Info';
import { IconButton, Tooltip } from '@mui/material';

import { buildItemInformationPath } from '@/config/paths';

import { useBuilderTranslation } from '../../config/i18n';
import {
ITEM_INFORMATION_BUTTON_ID,
ITEM_INFORMATION_ICON_IS_OPEN_CLASS,
} from '../../config/selectors';
import { ITEM_INFORMATION_BUTTON_ID } from '../../config/selectors';
import { BUILDER } from '../../langs/constants';
import { useLayoutContext } from '../context/LayoutContext';

const ItemMetadataButton = (): JSX.Element => {
const ItemMetadataButton = ({ itemId }: { itemId: string }): JSX.Element => {
const { t: translateBuilder } = useBuilderTranslation();
const {
isItemMetadataMenuOpen,
setIsItemMetadataMenuOpen,
setIsChatboxMenuOpen,
} = useLayoutContext();

const onClick = () => {
setIsItemMetadataMenuOpen(!isItemMetadataMenuOpen);
setIsChatboxMenuOpen(false);
};

return (
<Tooltip title={translateBuilder(BUILDER.ITEM_METADATA_TITLE)}>
<span>
<IconButton
id={ITEM_INFORMATION_BUTTON_ID}
onClick={onClick}
className={
isItemMetadataMenuOpen ? ITEM_INFORMATION_ICON_IS_OPEN_CLASS : ''
}
>
<InfoIcon />
</IconButton>
</span>
<IconButton
component={Link}
to={buildItemInformationPath(itemId)}
id={ITEM_INFORMATION_BUTTON_ID}
>
<InfoIcon />
</IconButton>
</Tooltip>
);
};
Expand Down
Loading
Loading