Skip to content
This repository has been archived by the owner on Jan 23, 2025. It is now read-only.

Commit

Permalink
feat: prevent move on shared page (#855)
Browse files Browse the repository at this point in the history
  • Loading branch information
pyphilia authored Nov 21, 2023
1 parent bb4279c commit 39b7314
Show file tree
Hide file tree
Showing 18 changed files with 105 additions and 48 deletions.
27 changes: 1 addition & 26 deletions cypress/e2e/item/move/listMoveItem.cy.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
import {
HOME_PATH,
SHARED_ITEMS_PATH,
buildItemPath,
} from '../../../../src/config/paths';
import { HOME_PATH, buildItemPath } from '../../../../src/config/paths';
import {
ITEM_MENU_MOVE_BUTTON_CLASS,
TREE_MODAL_MY_ITEMS_ID,
TREE_MODAL_SHARED_ITEMS_ID,
buildItemMenu,
buildItemMenuButtonId,
} from '../../../../src/config/selectors';
import { ITEM_LAYOUT_MODES } from '../../../../src/enums';
import { SAMPLE_ITEMS } from '../../../fixtures/items';
import { SHARED_ITEMS } from '../../../fixtures/sharedItems';
import { TABLE_ITEM_RENDER_TIME } from '../../../support/constants';

const moveItem = ({
Expand Down Expand Up @@ -91,23 +85,4 @@ describe('Move Item in List', () => {
expect(url).to.contain(movedItem);
});
});

it('move item in shared item', () => {
cy.setUpApi(SHARED_ITEMS);

// go to children item
cy.visit(SHARED_ITEMS_PATH);

cy.switchMode(ITEM_LAYOUT_MODES.LIST);

// move
const { path: toItemPath, id: toItemId } = SHARED_ITEMS.items[0];
const { id: movedItem } = SHARED_ITEMS.items[1];
moveItem({ id: movedItem, toItemPath, rootId: TREE_MODAL_SHARED_ITEMS_ID });

cy.wait('@moveItems').then(({ request: { body, url } }) => {
expect(body.parentId).to.equal(toItemId);
expect(url).to.contain(movedItem);
});
});
});
36 changes: 36 additions & 0 deletions cypress/e2e/item/shared/sharedItems.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import {
ITEM_MENU_MOVE_BUTTON_CLASS,
buildItemMenu,
buildItemMenuButtonId,
} from '@/config/selectors';

import { SHARED_ITEMS_PATH } from '../../../../src/config/paths';
import ITEM_LAYOUT_MODES from '../../../../src/enums/itemLayoutModes';
import { SAMPLE_ITEMS } from '../../../fixtures/items';
import { MEMBERS } from '../../../fixtures/members';

describe('Shared Items', () => {
beforeEach(() => {
cy.setUpApi({ ...SAMPLE_ITEMS, currentMember: MEMBERS.BOB });
cy.visit(SHARED_ITEMS_PATH);
cy.wait(5000);
});
it('move should be prevented in list', () => {
cy.switchMode(ITEM_LAYOUT_MODES.LIST);
const itemId = SAMPLE_ITEMS.items[1].id;
const menuSelector = `#${buildItemMenuButtonId(itemId)}`;
cy.get(menuSelector).click();
cy.get(`#${buildItemMenu(itemId)} .${ITEM_MENU_MOVE_BUTTON_CLASS}`).should(
'not.exist',
);
});
it('move should be prevented in grid', () => {
cy.switchMode(ITEM_LAYOUT_MODES.GRID);
const itemId = SAMPLE_ITEMS.items[1].id;
const menuSelector = `#${buildItemMenuButtonId(itemId)}`;
cy.get(menuSelector).click();
cy.get(`#${buildItemMenu(itemId)} .${ITEM_MENU_MOVE_BUTTON_CLASS}`).should(
'not.exist',
);
});
});
15 changes: 15 additions & 0 deletions cypress/fixtures/items.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,30 +59,45 @@ const sampleItems: DiscriminatedItem[] = [
id: 'fdf09f5a-5688-11eb-ae93-0242ac130002',
name: 'own_item_name2',
path: 'fdf09f5a_5688_11eb_ae93_0242ac130002',
settings: {
hasThumbnail: false,
},
},
{
...DEFAULT_FOLDER_ITEM,
id: 'fdf09f5a-5688-11eb-ae93-0242ac130003',
name: 'own_item_name3',
path: 'ecafbd2a_5688_11eb_ae93_0242ac130002.fdf09f5a_5688_11eb_ae93_0242ac130003',
settings: {
hasThumbnail: false,
},
},
{
...DEFAULT_FOLDER_ITEM,
id: 'fdf09f5a-5688-11eb-ae93-0242ac130004',
name: 'own_item_name4',
path: 'ecafbd2a_5688_11eb_ae93_0242ac130002.fdf09f5a_5688_11eb_ae93_0242ac130004',
settings: {
hasThumbnail: false,
},
},
{
...DEFAULT_FOLDER_ITEM,
id: 'fdf09f5a-5688-11eb-ae93-0242ac130005',
name: 'own_item_name5',
path: 'ecafbd2a_5688_11eb_ae93_0242ac130002.fdf09f5a_5688_11eb_ae93_0242ac130005',
settings: {
hasThumbnail: false,
},
},
{
...DEFAULT_FOLDER_ITEM,
id: 'ecafbd2a-5688-11eb-ae93-0242ac130006',
name: 'own_item_name6',
path: 'ecafbd2a_5688_11eb_ae93_0242ac130006',
settings: {
hasThumbnail: false,
},
},
];
export const SAMPLE_ITEMS: ApiConfig = {
Expand Down
2 changes: 1 addition & 1 deletion src/components/SharedItems.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import Main from './main/Main';
const SharedItemsLoadableContent = (): JSX.Element => {
const { t: translateBuilder } = useBuilderTranslation();
const { data: sharedItems, isLoading, isError } = hooks.useSharedItems();

if (isError) {
return <ErrorAlert id={SHARED_ITEMS_ERROR_ALERT_ID} />;
}
Expand All @@ -34,6 +33,7 @@ const SharedItemsLoadableContent = (): JSX.Element => {
id={SHARED_ITEMS_ID}
title={translateBuilder(BUILDER.SHARED_ITEMS_TITLE)}
items={sharedItems}
canMove={false}
showCreator
/>
</Box>
Expand Down
4 changes: 3 additions & 1 deletion src/components/item/ItemContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,9 @@ const FolderContent = ({
headerElements={
enableEditing ? [<NewItemButton key="newButton" />] : undefined
}
ToolbarActions={ItemActions}
// todo: not exactly correct, since you could have write rights on some child,
// but it's more tedious to check permissions over all selected items
ToolbarActions={enableEditing ? ItemActions : undefined}
showCreator
/>
);
Expand Down
3 changes: 2 additions & 1 deletion src/components/item/header/ItemHeaderActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ const ItemHeaderActions = ({ item }: Props): JSX.Element => {
const activeActions = (
<>
{showEditButton && <EditButton item={item} />}
<ItemMenu item={item} canEdit={showEditButton} />
{/* prevent moving from top header to avoid confusion */}
<ItemMenu item={item} canMove={false} canEdit={showEditButton} />

<ShareButton itemId={item.id} />
<ChatboxButton
Expand Down
4 changes: 2 additions & 2 deletions src/components/main/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import ErrorAlert from '../common/ErrorAlert';
import FileUploader from '../file/FileUploader';
import { UppyContextProvider } from '../file/UppyContext';
import ItemHeader from '../item/header/ItemHeader';
import ItemActionsRenderer from './ItemActions';
import ItemActions from './ItemActions';
import Items from './Items';
import Main from './Main';
import NewItemButton from './NewItemButton';
Expand Down Expand Up @@ -38,7 +38,7 @@ const HomeLoadableContent = (): JSX.Element => {
title={translateBuilder(BUILDER.MY_ITEMS_TITLE)}
items={ownItems}
headerElements={[<NewItemButton key="newButton" />]}
ToolbarActions={ItemActionsRenderer}
ToolbarActions={ItemActions}
/>
</Box>
</UppyContextProvider>
Expand Down
6 changes: 5 additions & 1 deletion src/components/main/ItemCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,14 @@ type Props = {
item: DiscriminatedItem;
memberships?: ItemMembership[];
itemsStatuses?: ItemsStatuses;
canMove?: boolean;
};

const ItemComponent = ({
item,
memberships,
itemsStatuses,
canMove = true,
}: Props): JSX.Element => {
const { id, name } = item;
const { data: thumbnailUrl, isLoading } = hooks.useItemThumbnailUrl({ id });
Expand Down Expand Up @@ -100,7 +102,9 @@ const ItemComponent = ({
Badges={<Badges data={item} />}
name={item.name}
creator={member?.name}
ItemMenu={<ItemMenu item={item} canEdit={enableEdition} />}
ItemMenu={
<ItemMenu item={item} canEdit={enableEdition} canMove={canMove} />
}
Thumbnail={ThumbnailComponent}
cardId={buildItemCard(item.id)}
NameWrapper={NameWrapper({
Expand Down
27 changes: 18 additions & 9 deletions src/components/main/ItemMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,14 @@ import CopyButton from './CopyButton';
type Props = {
item: DiscriminatedItem;
canEdit?: boolean;
canMove?: boolean;
};

const ItemMenu = ({ item, canEdit = false }: Props): JSX.Element => {
const ItemMenu = ({
item,
canEdit = false,
canMove = true,
}: Props): JSX.Element => {
const { data: member } = useCurrentUserContext();
const [anchorEl, setAnchorEl] = useState<Element | null>(null);
const { t: translateBuilder } = useBuilderTranslation();
Expand Down Expand Up @@ -67,13 +72,17 @@ const ItemMenu = ({ item, canEdit = false }: Props): JSX.Element => {
if (!canEdit) {
return null;
}
return [
<MoveButton
key="move"
type={ActionButton.MENU_ITEM}
itemIds={[item.id]}
onClick={handleClose}
/>,
const result = canMove
? [
<MoveButton
key="move"
type={ActionButton.MENU_ITEM}
itemIds={[item.id]}
onClick={handleClose}
/>,
]
: [];
return result.concat([
<HideButton key="hide" type={ActionButton.MENU_ITEM} item={item} />,
<PinButton key="pin" type={ActionButton.MENU_ITEM} item={item} />,
<CollapseButton
Expand All @@ -87,7 +96,7 @@ const ItemMenu = ({ item, canEdit = false }: Props): JSX.Element => {
itemIds={[item.id]}
onClick={handleClose}
/>,
];
]);
};

const renderAuthenticatedActions = () => {
Expand Down
6 changes: 5 additions & 1 deletion src/components/main/Items.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type Props = {
items?: DiscriminatedItem[];
title: string;
headerElements?: JSX.Element[];
actions?: ({ data }: { data: { id: string } }) => JSX.Element;
actions?: ({ data }: { data: DiscriminatedItem }) => JSX.Element;
ToolbarActions?: ({ selectedIds }: { selectedIds: string[] }) => JSX.Element;
clickable?: boolean;
defaultSortedColumn?: {
Expand All @@ -29,6 +29,7 @@ type Props = {
showThumbnails?: boolean;
showCreator?: boolean;
enableMemberships?: boolean;
canMove?: boolean;
};

const Items = ({
Expand All @@ -44,6 +45,7 @@ const Items = ({
showThumbnails = true,
showCreator = false,
enableMemberships = true,
canMove = true,
}: Props): JSX.Element => {
const { mode } = useLayoutContext();
const itemSearch = useItemSearch(items);
Expand All @@ -65,6 +67,7 @@ const Items = ({
case ITEM_LAYOUT_MODES.GRID:
return (
<ItemsGrid
canMove={canMove}
parentId={parentId}
title={title}
items={itemsToDisplay}
Expand Down Expand Up @@ -92,6 +95,7 @@ const Items = ({
clickable={clickable}
showThumbnails={showThumbnails}
showCreator={showCreator}
canMove={canMove}
/>
);
}
Expand Down
3 changes: 3 additions & 0 deletions src/components/main/ItemsGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ type Props = {
};
headerElements?: JSX.Element[];
parentId?: string;
canMove?: boolean;
};

const ItemsGrid = ({
Expand All @@ -53,6 +54,7 @@ const ItemsGrid = ({
manyMemberships,
itemsStatuses,
parentId,
canMove = true,
}: Props): JSX.Element => {
const { t: translateBuilder } = useBuilderTranslation();
const [page, setPage] = useState(1);
Expand Down Expand Up @@ -87,6 +89,7 @@ const ItemsGrid = ({
return itemsInPage.map((item) => (
<Grid key={item.id} item xs={12} sm={12} md={6} lg={6} xl={4}>
<ItemCard
canMove={canMove}
item={item}
memberships={getMembershipsForItem({
manyMemberships,
Expand Down
5 changes: 4 additions & 1 deletion src/components/main/ItemsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ type Props = {
tableTitle: string;
headerElements?: JSX.Element[];
isSearching?: boolean;
actions?: ({ data }: { data: { id: string } }) => JSX.Element;
actions?: ({ data }: { data: DiscriminatedItem }) => JSX.Element;
ToolbarActions?: ({ selectedIds }: { selectedIds: string[] }) => JSX.Element;
clickable?: boolean;
defaultSortedColumn?: {
Expand All @@ -56,6 +56,7 @@ type Props = {
};
showThumbnails?: boolean;
showCreator?: boolean;
canMove?: boolean;
};

const ItemsTable = ({
Expand All @@ -72,6 +73,7 @@ const ItemsTable = ({
defaultSortedColumn,
showThumbnails = true,
showCreator = false,
canMove = true,
}: Props): JSX.Element => {
const { t: translateBuilder } = useBuilderTranslation();
const { t: translateCommon } = useCommonTranslation();
Expand Down Expand Up @@ -157,6 +159,7 @@ const ItemsTable = ({
const ActionComponent = ActionsCellRenderer({
manyMemberships,
member,
canMove,
});

const BadgesComponent = BadgesCellRenderer({
Expand Down
2 changes: 1 addition & 1 deletion src/components/main/MainMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ const MainMenu = (): JSX.Element => {
<ListItemIcon>
<AutoStoriesIcon />
</ListItemIcon>
<ListItemText>{translateBuilder('Tutorials')}</ListItemText>
<ListItemText>{translateBuilder(BUILDER.TUTORIALS)}</ListItemText>
</ListItemButton>
</ListItem>
);
Expand Down
4 changes: 3 additions & 1 deletion src/components/table/ActionsCellRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import ItemMenu from '../main/ItemMenu';
type Props = {
manyMemberships?: ResultOf<ItemMembership[]>;
member?: Member | null;
canMove?: boolean;
};

type ChildCompProps = {
Expand All @@ -28,6 +29,7 @@ type ChildCompProps = {
const ActionsCellRenderer = ({
manyMemberships,
member,
canMove,
}: Props): ((arg: ChildCompProps) => JSX.Element) => {
const ChildComponent = ({ data: item }: ChildCompProps) => {
const [canEdit, setCanEdit] = useState(false);
Expand All @@ -50,7 +52,7 @@ const ActionsCellRenderer = ({
const renderAnyoneActions = () => (
<>
<DownloadButton id={item.id} name={item.name} />
<ItemMenu item={item} canEdit={canEdit} />
<ItemMenu item={item} canMove={canMove} canEdit={canEdit} />
</>
);

Expand Down
2 changes: 1 addition & 1 deletion src/config/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const GRAASP_LIBRARY_HOST =
export const GRAASP_ANALYZER_HOST =
import.meta.env.VITE_GRAASP_ANALYZER_HOST || 'http://localhost:3113';
export const GRAASP_ACCOUNT_HOST =
import.meta.env.VITE_GRAASP_ACCOUNT_HOST || 'http://localhost:3114';
import.meta.env.VITE_GRAASP_ACCOUNT_HOST || 'http://localhost:3115';

export const H5P_INTEGRATION_URL =
import.meta.env.VITE_H5P_INTEGRATION_URL || `${API_HOST}/p/h5p-integration`;
Expand Down
Loading

0 comments on commit 39b7314

Please sign in to comment.