Skip to content

Commit

Permalink
feat: Add CheckOption on Omnichannel's departments multi selects (#…
Browse files Browse the repository at this point in the history
…32193)

Co-authored-by: Douglas Fabris <27704687+dougfabris@users.noreply.github.com>
  • Loading branch information
csuadev and dougfabris authored May 9, 2024
1 parent 0154fac commit e0ba4e6
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 60 deletions.
5 changes: 5 additions & 0 deletions .changeset/strange-bears-dance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': minor
---

Adds CheckOption to departments multi selects improving options visibility state
10 changes: 8 additions & 2 deletions apps/meteor/client/components/AutoCompleteDepartmentMultiple.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Option, PaginatedMultiSelectFiltered } from '@rocket.chat/fuselage';
import { CheckOption, PaginatedMultiSelectFiltered } from '@rocket.chat/fuselage';
import type { PaginatedMultiSelectOption } from '@rocket.chat/fuselage';
import { useDebouncedValue } from '@rocket.chat/fuselage-hooks';
import { useTranslation } from '@rocket.chat/ui-contexts';
Expand Down Expand Up @@ -65,7 +65,13 @@ const AutoCompleteDepartmentMultiple = ({
return loadMoreDepartments(start, Math.min(50, departmentsTotal));
}
}
renderItem={({ label, ...props }) => <Option {...props} label={<span style={{ whiteSpace: 'normal' }}>{label}</span>} />}
renderItem={({ label, ...props }) => (
<CheckOption
{...props}
label={<span style={{ whiteSpace: 'normal' }}>{label}</span>}
selected={value.some((item) => item.value === props.value)}
/>
)}
/>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Field, FieldLabel, FieldRow, FieldHint, Box, PaginatedMultiSelectFiltered, Option } from '@rocket.chat/fuselage';
import { Field, FieldLabel, FieldRow, FieldHint, Box, PaginatedMultiSelectFiltered, CheckOption } from '@rocket.chat/fuselage';
import type { PaginatedMultiSelectOption } from '@rocket.chat/fuselage';
import { useDebouncedValue } from '@rocket.chat/fuselage-hooks';
import type { TranslationKey } from '@rocket.chat/ui-contexts';
Expand Down Expand Up @@ -65,7 +65,13 @@ export const DepartmentForwarding = ({ departmentId, value = [], handler, label
loadMoreDepartments(start, Math.min(50, departmentsTotal));
}
}
renderItem={({ label, ...props }) => <Option {...props} label={<span style={{ whiteSpace: 'normal' }}>{label}</span>} />}
renderItem={({ label, ...props }) => (
<CheckOption
{...props}
label={<span style={{ whiteSpace: 'normal' }}>{label}</span>}
selected={value.some((item) => item.value === props.value)}
/>
)}
/>
</Box>
</FieldRow>
Expand Down
11 changes: 9 additions & 2 deletions apps/meteor/ee/client/omnichannel/units/UnitEdit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
Box,
FieldLabel,
FieldRow,
Option,
CheckOption,
} from '@rocket.chat/fuselage';
import { useMutableCallback, useDebouncedValue, useUniqueId } from '@rocket.chat/fuselage-hooks';
import { useToastMessageDispatch, useMethod, useTranslation, useRouter } from '@rocket.chat/ui-contexts';
Expand Down Expand Up @@ -243,7 +243,11 @@ const UnitEdit = ({ unitData, unitMonitors, unitDepartments }: UnitEditProps) =>
aria-required={true}
aria-invalid={Boolean(errors?.departments)}
renderItem={({ label, ...props }) => (
<Option {...props} label={<span style={{ whiteSpace: 'normal' }}>{label}</span>} />
<CheckOption
{...props}
label={<span style={{ whiteSpace: 'normal' }}>{label}</span>}
selected={value.some((item) => item.value === props.value)}
/>
)}
/>
)}
Expand Down Expand Up @@ -285,6 +289,9 @@ const UnitEdit = ({ unitData, unitMonitors, unitDepartments }: UnitEditProps) =>
aria-describedby={`${monitorsField}-error`}
aria-required={true}
aria-invalid={Boolean(errors?.monitors)}
renderItem={({ label, ...props }) => (
<CheckOption {...props} label={label} selected={value.some((item) => item.value === props.value)} />
)}
/>
)}
/>
Expand Down
137 changes: 83 additions & 54 deletions apps/meteor/tests/e2e/omnichannel/omnichannel-units.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@ test.describe('OC - Manage Units', () => {
let poOmnichannelUnits: OmnichannelUnits;

let department: Awaited<ReturnType<typeof createDepartment>>;
let department2: Awaited<ReturnType<typeof createDepartment>>;

let agent: Awaited<ReturnType<typeof createAgent>>;

let monitor: Awaited<ReturnType<typeof createMonitor>>;

test.beforeAll(async ({ api }) => {
department = await createDepartment(api);
department2 = await createDepartment(api);
});

test.beforeAll(async ({ api }) => {
Expand All @@ -37,20 +39,20 @@ test.describe('OC - Manage Units', () => {

test.afterAll(async () => {
await department.delete();
await department2.delete();
await monitor.delete();
await agent.delete();
});

test.beforeEach(async ({ page }: { page: Page }) => {
poOmnichannelUnits = new OmnichannelUnits(page);
await page.goto('/omnichannel');
await poOmnichannelUnits.sidenav.linkUnits.click();
});

test('OC - Manage Units - Create Unit', async ({ page }) => {
const unitName = faker.string.uuid();

await page.goto('/omnichannel');
await poOmnichannelUnits.sidenav.linkUnits.click();

await test.step('expect correct form default state', async () => {
await poOmnichannelUnits.btnCreateUnit.click();
await expect(poOmnichannelUnits.contextualBar).toBeVisible();
Expand All @@ -76,49 +78,30 @@ test.describe('OC - Manage Units', () => {
});

await test.step('expect to delete unit', async () => {
await test.step('expect confirm delete unit', async () => {
await test.step('expect to be able to cancel delete', async () => {
await poOmnichannelUnits.btnDeleteByName(unitName).click();
await expect(poOmnichannelUnits.confirmDeleteModal).toBeVisible();
await poOmnichannelUnits.btnCancelDeleteModal.click();
await expect(poOmnichannelUnits.confirmDeleteModal).not.toBeVisible();
});

await test.step('expect to confirm delete', async () => {
await poOmnichannelUnits.btnDeleteByName(unitName).click();
await expect(poOmnichannelUnits.confirmDeleteModal).toBeVisible();
await poOmnichannelUnits.btnConfirmDeleteModal.click();
await expect(poOmnichannelUnits.confirmDeleteModal).not.toBeVisible();
});
});

await test.step('expect to have been deleted', async () => {
if (await poOmnichannelUnits.inputSearch.isVisible()) {
await poOmnichannelUnits.search(unitName);
await expect(poOmnichannelUnits.findRowByName(unitName)).not.toBeVisible();
} else {
await expect(page.locator('h3 >> text="No units yet"')).toBeVisible();
}
});
await poOmnichannelUnits.btnDeleteByName(unitName).click();
await expect(poOmnichannelUnits.confirmDeleteModal).toBeVisible();
await poOmnichannelUnits.btnConfirmDeleteModal.click();
await expect(poOmnichannelUnits.confirmDeleteModal).not.toBeVisible();
await expect(page.locator('h3 >> text="No units yet"')).toBeVisible();
});
});

test('OC - Manage Units - Edit unit', async ({ api, page }) => {
test('OC - Manage Units - Edit unit name', async ({ api, page }) => {
const unitName = faker.string.uuid();
const editedUnitName = faker.string.uuid();

const unit = await test.step('expect to create new unit', async () => {
const { data: unit } = await createOrUpdateUnit(api, {
name: faker.string.uuid(),
const { data: newUnit } = await createOrUpdateUnit(api, {
name: unitName,
visibility: 'public',
monitors: [{ monitorId: monitor.data._id, username: 'user2' }],
departments: [{ departmentId: department.data._id }],
});

return unit;
return newUnit;
});

await page.goto('/omnichannel');
await poOmnichannelUnits.sidenav.linkUnits.click();
await page.reload();

await test.step('expect to edit unit', async () => {
await poOmnichannelUnits.search(unit.name);
Expand All @@ -138,29 +121,75 @@ test.describe('OC - Manage Units', () => {
await poOmnichannelUnits.findRowByName(editedUnitName).click();
await expect(poOmnichannelUnits.contextualBar).toBeVisible();

await test.step('expect confirm delete unit', async () => {
await test.step('expect to be able to cancel delete', async () => {
await poOmnichannelUnits.btnDelete.click();
await expect(poOmnichannelUnits.confirmDeleteModal).toBeVisible();
await poOmnichannelUnits.btnCancelDeleteModal.click();
await expect(poOmnichannelUnits.confirmDeleteModal).not.toBeVisible();
});

await test.step('expect to confirm delete', async () => {
await poOmnichannelUnits.btnDelete.click();
await expect(poOmnichannelUnits.confirmDeleteModal).toBeVisible();
await poOmnichannelUnits.btnConfirmDeleteModal.click();
await expect(poOmnichannelUnits.confirmDeleteModal).not.toBeVisible();
});

await expect(poOmnichannelUnits.contextualBar).not.toBeVisible();
await test.step('expect to confirm delete', async () => {
await poOmnichannelUnits.btnDelete.click();
await expect(poOmnichannelUnits.confirmDeleteModal).toBeVisible();
await poOmnichannelUnits.btnConfirmDeleteModal.click();
await expect(poOmnichannelUnits.confirmDeleteModal).not.toBeVisible();
});

await test.step('expect to have been deleted', async () => {
await expect(poOmnichannelUnits.inputSearch).toBeVisible();
await poOmnichannelUnits.inputSearch.clear();
await expect(page.locator('h3 >> text="No units yet"')).toBeVisible();
});
await expect(poOmnichannelUnits.contextualBar).not.toBeVisible();
});
});

test('OC - Manage Units - Edit unit departments', async ({ api, page }) => {
const unit = await test.step('expect to create new unit', async () => {
const { data: unit } = await createOrUpdateUnit(api, {
name: faker.string.uuid(),
visibility: 'public',
monitors: [{ monitorId: monitor.data._id, username: 'user2' }],
departments: [{ departmentId: department.data._id }],
});

return unit;
});

await page.reload();

await test.step('expect to add unit departments', async () => {
await poOmnichannelUnits.search(unit.name);
await poOmnichannelUnits.findRowByName(unit.name).click();
await expect(poOmnichannelUnits.contextualBar).toBeVisible();
await poOmnichannelUnits.selectDepartment({ name: department2.data.name, _id: department2.data._id });
await poOmnichannelUnits.btnSave.click();
});

await test.step('expect department to be in the chosen departments list', async () => {
await poOmnichannelUnits.search(unit.name);
await poOmnichannelUnits.findRowByName(unit.name).click();
await expect(poOmnichannelUnits.contextualBar).toBeVisible();
await expect(page.getByRole('option', { name: department2.data.name })).toBeVisible();
await poOmnichannelUnits.btnContextualbarClose.click();
});

await test.step('expect to remove unit departments', async () => {
await poOmnichannelUnits.search(unit.name);
await poOmnichannelUnits.findRowByName(unit.name).click();
await expect(poOmnichannelUnits.contextualBar).toBeVisible();
await poOmnichannelUnits.selectDepartment({ name: department2.data.name, _id: department2.data._id });
await poOmnichannelUnits.selectMonitor('user2');
await poOmnichannelUnits.btnSave.click();
});

await test.step('expect department to not be in the chosen departments list', async () => {
await poOmnichannelUnits.search(unit.name);
await poOmnichannelUnits.findRowByName(unit.name).click();
await expect(poOmnichannelUnits.contextualBar).toBeVisible();
await expect(page.getByRole('option', { name: department2.data.name })).toBeHidden();
await poOmnichannelUnits.btnContextualbarClose.click();
});

await test.step('expect to delete unit', async () => {
await poOmnichannelUnits.findRowByName(unit.name).click();
await expect(poOmnichannelUnits.contextualBar).toBeVisible();
await test.step('expect to confirm delete', async () => {
await poOmnichannelUnits.btnDelete.click();
await expect(poOmnichannelUnits.confirmDeleteModal).toBeVisible();
await poOmnichannelUnits.btnConfirmDeleteModal.click();
await expect(poOmnichannelUnits.confirmDeleteModal).not.toBeVisible();
});

await expect(poOmnichannelUnits.contextualBar).not.toBeVisible();
});
})
});
4 changes: 4 additions & 0 deletions apps/meteor/tests/e2e/page-objects/omnichannel-units.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ export class OmnichannelUnits extends OmnichannelAdministration {
return this.page.locator('button', { has: this.page.locator('select[name="visibility"]') });
}

get btnContextualbarClose(): Locator {
return this.page.locator('[data-qa="ContextualbarActionClose"]');
}

private selectOption(name: string) {
return this.page.locator(`[role=option][value="${name}"]`);
}
Expand Down

0 comments on commit e0ba4e6

Please sign in to comment.