Skip to content

Commit

Permalink
feat: create navigation island (graasp#576)
Browse files Browse the repository at this point in the history
* feat: create navigation island

* fix: tests

* fix: sonar cloud issues

* fix: remove cnacel-in-progress

* fix: shadow color, tests and redirect on item index page

* fix: update components and add test for island

* fix: translate and add button to go to home

* fix: update prev-next buttons to retunr null if both are null

* fix: use hooks to render the island only when there is content inside

* fix: update test
  • Loading branch information
spaenleh authored Mar 25, 2024
1 parent c82cce9 commit 76d5e21
Show file tree
Hide file tree
Showing 30 changed files with 871 additions and 454 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/cypress.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:

concurrency:
group: cypress-${{ github.ref }}
cancel-in-progress: true
cancel-in-progress: false

jobs:
cypress:
Expand Down
6 changes: 3 additions & 3 deletions cypress/e2e/apps.cy.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'cypress-iframe';

import { buildMainPath } from '@/config/paths';
import { buildContentPagePath } from '@/config/paths';

import {
APP_USING_CONTEXT_ITEM,
Expand All @@ -25,7 +25,7 @@ describe('Apps', () => {
it('App should request context', () => {
const { id, name } = APP_USING_CONTEXT_ITEM;
cy.setUpApi({ items: [APP_USING_CONTEXT_ITEM] });
cy.visit(buildMainPath({ rootId: id }));
cy.visit(buildContentPagePath({ rootId: id, itemId: id }));

cy.wait(3000);
const iframeSelector = `iframe[title="${name}"]`;
Expand Down Expand Up @@ -70,7 +70,7 @@ describe('Public Apps', () => {
currentMember: null,
});

cy.visit(buildMainPath({ rootId: id }));
cy.visit(buildContentPagePath({ rootId: id, itemId: id }));
});

it('Public App should request context', () => {
Expand Down
29 changes: 17 additions & 12 deletions cypress/e2e/chatbox.cy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { buildMainPath } from '../../src/config/paths';
import { buildContentPagePath } from '@/config/paths';

import {
ITEM_CHATBOX_BUTTON_ID,
ITEM_CHATBOX_ID,
Expand All @@ -20,24 +21,25 @@ describe('Chatbox', () => {
});

it('Chatbox button should toggle chatbox visibility', () => {
cy.visit(buildMainPath({ rootId: ITEM_WITH_CHAT_BOX.id }));
const { id } = ITEM_WITH_CHAT_BOX;
cy.visit(buildContentPagePath({ rootId: id, itemId: id }));

cy.wait('@getCurrentMember');
cy.get(`#${ITEM_CHATBOX_BUTTON_ID}`).should('exist');
cy.get(`#${ITEM_CHATBOX_ID}`).should('not.exist');

cy.get(`#${ITEM_CHATBOX_BUTTON_ID}`).click();
// chatbox is closed by default
cy.get(`#${ITEM_CHATBOX_ID}`).should('not.be.visible');
cy.get(`#${ITEM_CHATBOX_BUTTON_ID}`).should('be.visible').click();

cy.get(`#${ITEM_CHATBOX_ID}`).should('be.visible');
});

it('Side panel button should hide chatbox', () => {
cy.visit(buildMainPath({ rootId: ITEM_WITH_CHAT_BOX.id }));
const { id } = ITEM_WITH_CHAT_BOX;
cy.visit(buildContentPagePath({ rootId: id, itemId: id }));

cy.wait('@getCurrentMember');
cy.get(`#${ITEM_CHATBOX_BUTTON_ID}`).should('exist');
cy.get(`#${ITEM_CHATBOX_ID}`).should('not.be.exist');

cy.get(`#${ITEM_CHATBOX_ID}`).should('not.be.visible');
cy.get(`#${ITEM_CHATBOX_BUTTON_ID}`).should('be.visible');
cy.get(`#${ITEM_CHATBOX_BUTTON_ID}`).click();

cy.get(`#${ITEM_CHATBOX_ID}`).should('be.visible');
Expand All @@ -47,17 +49,20 @@ describe('Chatbox', () => {
});

it('Disabled chatbox should not have button', () => {
cy.visit(buildMainPath({ rootId: ITEM_WITHOUT_CHAT_BOX.id }));
const { id } = ITEM_WITH_CHAT_BOX;
cy.visit(buildContentPagePath({ rootId: id, itemId: id }));

cy.wait('@getCurrentMember');
cy.get(`#${ITEM_CHATBOX_BUTTON_ID}`).should('not.exist');
cy.get(`#${ITEM_CHATBOX_ID}`).should('not.exist');
});

it('Chatbox button is clickable on document', () => {
const { id } = GRAASP_DOCUMENT_ITEM_WITH_CHAT_BOX;
cy.visit(
buildMainPath({
rootId: GRAASP_DOCUMENT_ITEM_WITH_CHAT_BOX.id,
buildContentPagePath({
rootId: id,
itemId: id,
}),
);
cy.wait('@getCurrentMember');
Expand Down
4 changes: 2 additions & 2 deletions cypress/e2e/collapsed.cy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { buildMainPath } from '@/config/paths';
import { buildContentPagePath } from '@/config/paths';
import { buildCollapsibleId } from '@/config/selectors';

import { FOLDER_WITH_COLLAPSIBLE_SHORTCUT_ITEMS } from '../fixtures/items';
Expand All @@ -12,7 +12,7 @@ describe('Collapsible', () => {

it('Shows a collapsible wrapper around a collapsible shortcut', () => {
const parent = FOLDER_WITH_COLLAPSIBLE_SHORTCUT_ITEMS.items[1];
cy.visit(buildMainPath({ rootId: parent.id }));
cy.visit(buildContentPagePath({ rootId: parent.id, itemId: parent.id }));
const collapsedShortcut = FOLDER_WITH_COLLAPSIBLE_SHORTCUT_ITEMS.items[2];
// collapsible document should show as collapsed
cy.get(`#${buildCollapsibleId(collapsedShortcut.id)}`)
Expand Down
10 changes: 5 additions & 5 deletions cypress/e2e/hidden.cy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { buildMainPath } from '../../src/config/paths';
import { buildContentPagePath } from '../../src/config/paths';
import { buildDocumentId } from '../../src/config/selectors';
import {
FOLDER_WITH_HIDDEN_ITEMS,
Expand All @@ -13,7 +13,7 @@ describe('Hidden Items', () => {
});

const parent = FOLDER_WITH_HIDDEN_ITEMS.items[0];
cy.visit(buildMainPath({ rootId: parent.id }));
cy.visit(buildContentPagePath({ rootId: parent.id, itemId: parent.id }));

// hidden document should not be displayed
cy.get(`#${buildDocumentId(FOLDER_WITH_HIDDEN_ITEMS.items[1].id)}`).should(
Expand All @@ -31,7 +31,7 @@ describe('Hidden Items', () => {
});

const parent = FOLDER_WITH_HIDDEN_ITEMS.items[0];
cy.visit(buildMainPath({ rootId: parent.id }));
cy.visit(buildContentPagePath({ rootId: parent.id, itemId: parent.id }));

cy.get(`#${buildDocumentId(FOLDER_WITH_HIDDEN_ITEMS.items[1].id)}`).should(
'be.visible',
Expand All @@ -49,7 +49,7 @@ describe('Hidden Items', () => {
});

const parent = FOLDER_WITH_HIDDEN_ITEMS.items[0];
cy.visit(buildMainPath({ rootId: parent.id }));
cy.visit(buildContentPagePath({ rootId: parent.id, itemId: parent.id }));

cy.get(`#${buildDocumentId(FOLDER_WITH_HIDDEN_ITEMS.items[1].id)}`).should(
'be.visible',
Expand All @@ -67,7 +67,7 @@ describe('Hidden Items', () => {
});

const parent = PUBLIC_FOLDER_WITH_HIDDEN_ITEMS.items[0];
cy.visit(buildMainPath({ rootId: parent.id }));
cy.visit(buildContentPagePath({ rootId: parent.id, itemId: parent.id }));

cy.get(
`#${buildDocumentId(PUBLIC_FOLDER_WITH_HIDDEN_ITEMS.items[1].id)}`,
Expand Down
27 changes: 27 additions & 0 deletions cypress/e2e/island.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { buildContentPagePath } from '@/config/paths';
import { ITEM_CHATBOX_BUTTON_ID } from '@/config/selectors';

import {
DOCUMENT_WITHOUT_CHAT_BOX,
DOCUMENT_WITH_CHAT_BOX,
} from '../fixtures/items';

describe('Island', () => {
it('Show island with chat button on document with chat', () => {
const item = DOCUMENT_WITH_CHAT_BOX;
cy.setUpApi({
items: [item],
});
cy.visit(buildContentPagePath({ rootId: item.id, itemId: item.id }));
cy.get(`#${ITEM_CHATBOX_BUTTON_ID}`).should('be.visible');
});

it('Hide island on document without chat', () => {
const item = DOCUMENT_WITHOUT_CHAT_BOX;
cy.setUpApi({
items: [item],
});
cy.visit(buildContentPagePath({ rootId: item.id, itemId: item.id }));
cy.get(`#${ITEM_CHATBOX_BUTTON_ID}`).should('not.exist');
});
});
42 changes: 28 additions & 14 deletions cypress/e2e/main.cy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { buildMainPath } from '../../src/config/paths';
import { buildContentPagePath } from '../../src/config/paths';
import {
FOLDER_NAME_TITLE_CLASS,
MAIN_MENU_ID,
Expand Down Expand Up @@ -55,19 +55,19 @@ describe('Main Screen', () => {
describe('Links', () => {
it('Website link', () => {
const { id } = GRAASP_LINK_ITEM;
cy.visit(buildMainPath({ rootId: id }));
cy.visit(buildContentPagePath({ rootId: id, itemId: id }));

expectLinkViewScreenLayout(GRAASP_LINK_ITEM);
});
it('Website link as iframe', () => {
const { id } = GRAASP_LINK_ITEM_IFRAME_ONLY;
cy.visit(buildMainPath({ rootId: id }));
cy.visit(buildContentPagePath({ rootId: id, itemId: id }));

expectLinkViewScreenLayout(GRAASP_LINK_ITEM_IFRAME_ONLY);
});
it('Youtube link', () => {
const { id } = YOUTUBE_LINK_ITEM;
cy.visit(buildMainPath({ rootId: id }));
cy.visit(buildContentPagePath({ rootId: id, itemId: id }));

expectLinkViewScreenLayout(YOUTUBE_LINK_ITEM);
});
Expand All @@ -76,35 +76,45 @@ describe('Main Screen', () => {
describe('Files', () => {
it('Image', () => {
const { id } = IMAGE_ITEM_DEFAULT;
cy.visit(buildMainPath({ rootId: id }));
cy.visit(buildContentPagePath({ rootId: id, itemId: id }));

expectFileViewScreenLayout(IMAGE_ITEM_DEFAULT);
});
it('Video', () => {
const { id } = VIDEO_ITEM_DEFAULT;
cy.visit(buildMainPath({ rootId: id }));
cy.visit(buildContentPagePath({ rootId: id, itemId: id }));

expectFileViewScreenLayout(VIDEO_ITEM_DEFAULT);
});
it('Pdf', () => {
const { id } = PDF_ITEM_DEFAULT;
cy.visit(buildMainPath({ rootId: id }));
cy.visit(buildContentPagePath({ rootId: id, itemId: id }));

expectFileViewScreenLayout(PDF_ITEM_DEFAULT);
});
});

describe('Documents', () => {
it('Graasp Document', () => {
cy.visit(buildMainPath({ rootId: GRAASP_DOCUMENT_ITEM.id }));
cy.visit(
buildContentPagePath({
rootId: GRAASP_DOCUMENT_ITEM.id,
itemId: GRAASP_DOCUMENT_ITEM.id,
}),
);

expectDocumentViewScreenLayout(GRAASP_DOCUMENT_ITEM);
});
});

describe('Apps', () => {
it('App', () => {
cy.visit(buildMainPath({ rootId: GRAASP_APP_ITEM.id }));
cy.visit(
buildContentPagePath({
rootId: GRAASP_APP_ITEM.id,
itemId: GRAASP_APP_ITEM.id,
}),
);

expectAppViewScreenLayout(GRAASP_APP_ITEM);
});
Expand All @@ -113,15 +123,19 @@ describe('Main Screen', () => {
describe('Folders', () => {
it('Display sub Folder', () => {
const parent = FOLDER_WITH_SUBFOLDER_ITEM.items[0];
cy.visit(buildMainPath({ rootId: parent.id }));
cy.visit(
buildContentPagePath({ rootId: parent.id, itemId: parent.id }),
);

cy.get(`.${FOLDER_NAME_TITLE_CLASS}`).should('contain', parent.name);

expectFolderButtonLayout(FOLDER_WITH_SUBFOLDER_ITEM.items[1]);
});
it('Display Folder without childrenOrder', () => {
const parent = FOLDER_WITHOUT_CHILDREN_ORDER.items[0];
cy.visit(buildMainPath({ rootId: parent.id }));
cy.visit(
buildContentPagePath({ rootId: parent.id, itemId: parent.id }),
);

cy.get(`.${FOLDER_NAME_TITLE_CLASS}`).should('contain', parent.name);
});
Expand All @@ -133,7 +147,7 @@ describe('Main Screen', () => {
cy.setUpApi(STATIC_ELECTRICITY);
const parentFolder = STATIC_ELECTRICITY.items[0];
const rootId = parentFolder.id;
cy.visit(buildMainPath({ rootId }));
cy.visit(buildContentPagePath({ rootId, itemId: rootId }));

expectFolderLayout({ rootId, items: STATIC_ELECTRICITY.items });
});
Expand All @@ -144,14 +158,14 @@ describe('Main Screen', () => {
});
const parentFolder = STATIC_ELECTRICITY.items[0];
const rootId = parentFolder.id;
cy.visit(buildMainPath({ rootId }));
cy.visit(buildContentPagePath({ rootId, itemId: rootId }));
cy.get(`#${MAIN_MENU_ID}`).should('not.exist');
});
it(`Display ${PUBLIC_STATIC_ELECTRICITY.items[0].name}`, () => {
cy.setUpApi({ ...PUBLIC_STATIC_ELECTRICITY, currentMember: MEMBERS.BOB });
const parentFolder = PUBLIC_STATIC_ELECTRICITY.items[0];
const rootId = parentFolder.id;
cy.visit(buildMainPath({ rootId }));
cy.visit(buildContentPagePath({ rootId, itemId: rootId }));

expectFolderLayout({ rootId, items: PUBLIC_STATIC_ELECTRICITY.items });
});
Expand Down
8 changes: 4 additions & 4 deletions cypress/e2e/pinned.cy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { buildMainPath } from '../../src/config/paths';
import { buildContentPagePath, buildMainPath } from '../../src/config/paths';
import {
ITEM_PINNED_BUTTON_ID,
ITEM_PINNED_ID,
Expand Down Expand Up @@ -27,10 +27,10 @@ describe('Pinned Items', () => {
it('Pinned button should toggle sidebar visibility', () => {
const parent = FOLDER_WITH_SUBFOLDER_ITEM.items[0];

cy.visit(buildMainPath({ rootId: parent.id }));
cy.visit(buildContentPagePath({ rootId: parent.id, itemId: parent.id }));

cy.wait('@getChildren');
cy.get(`#${ITEM_PINNED_BUTTON_ID}`).should('exist');
cy.get(`#${ITEM_PINNED_BUTTON_ID}`).should('be.visible');
cy.get(`#${ITEM_PINNED_ID}`).should('be.visible');

cy.get(`#${ITEM_PINNED_BUTTON_ID}`).click();
Expand All @@ -40,7 +40,7 @@ describe('Pinned Items', () => {
it('Parent folder should display pinned children', () => {
const parent = FOLDER_WITH_PINNED_ITEMS.items[0];
const pinned = FOLDER_WITH_PINNED_ITEMS.items[2];
cy.visit(buildMainPath({ rootId: parent.id }));
cy.visit(buildContentPagePath({ rootId: parent.id, itemId: parent.id }));

cy.get(`#${ITEM_PINNED_ID} #${buildFolderButtonId(pinned.id)}`).should(
'contain',
Expand Down
26 changes: 26 additions & 0 deletions cypress/fixtures/items.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,32 @@ export const ITEM_WITH_CHAT_BOX: MockItem = {
},
};

export const DOCUMENT_WITH_CHAT_BOX: MockItem = {
...DEFAULT_FOLDER_ITEM,
id: 'ecafbd2a-5688-11eb-ae93-0242ac130002',
name: 'parent folder',
path: 'ecafbd2a_5688_11eb_ae93_0242ac130002',
type: 'document',
extra: { document: { content: 'hello this is a document' } },
settings: {
isPinned: false,
showChatbox: true,
},
};

export const DOCUMENT_WITHOUT_CHAT_BOX: MockItem = {
...DEFAULT_FOLDER_ITEM,
id: 'ecafbd2a-5688-11eb-ae93-0242ac130002',
name: 'parent folder',
path: 'ecafbd2a_5688_11eb_ae93_0242ac130002',
type: 'document',
extra: { document: { content: 'hello this is a document with no chatbox' } },
settings: {
isPinned: false,
showChatbox: false,
},
};

export const ITEM_WITHOUT_CHAT_BOX: MockItem = {
...DEFAULT_FOLDER_ITEM,
id: 'fdf09f5a-5688-11eb-ae93-0242ac130003',
Expand Down
Loading

0 comments on commit 76d5e21

Please sign in to comment.