diff --git a/apps/journeys-admin/__generated__/GetLanguages.ts b/apps/journeys-admin/__generated__/GetLanguages.ts new file mode 100644 index 00000000000..563653ffc46 --- /dev/null +++ b/apps/journeys-admin/__generated__/GetLanguages.ts @@ -0,0 +1,28 @@ +/* tslint:disable */ +/* eslint-disable */ +// @generated +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL query operation: GetLanguages +// ==================================================== + +export interface GetLanguages_languages_name { + __typename: "Translation"; + value: string; + primary: boolean; +} + +export interface GetLanguages_languages { + __typename: "Language"; + id: string; + name: (GetLanguages_languages_name | null)[]; +} + +export interface GetLanguages { + languages: GetLanguages_languages[]; +} + +export interface GetLanguagesVariables { + languageId?: string | null; +} diff --git a/apps/journeys-admin/src/components/Editor/VideoLibrary/LanguageFilter/Drawer/Drawer.spec.tsx b/apps/journeys-admin/src/components/Editor/VideoLibrary/LanguageFilter/Drawer/Drawer.spec.tsx new file mode 100644 index 00000000000..6096982250e --- /dev/null +++ b/apps/journeys-admin/src/components/Editor/VideoLibrary/LanguageFilter/Drawer/Drawer.spec.tsx @@ -0,0 +1,146 @@ +import { MockedProvider } from '@apollo/client/testing' +import { fireEvent, render, waitFor } from '@testing-library/react' +import { GET_LANGUAGES } from './Drawer' +import { Drawer } from '.' + +jest.mock('@mui/material/useMediaQuery', () => ({ + __esModule: true, + default: jest.fn(() => true) +})) + +describe('LanguageDrawer', () => { + const mocks = [ + { + request: { + query: GET_LANGUAGES, + variables: { + languageId: '529' + } + }, + result: { + data: { + languages: [ + { + id: '529', + name: [ + { + value: 'English', + primary: true + } + ] + }, + { + id: '496', + name: [ + { + value: 'Français', + primary: true + }, + { + value: 'French', + primary: false + } + ] + }, + { + id: '1106', + name: [ + { + value: 'Deutsch', + primary: true + }, + { + value: 'German, Standard', + primary: false + } + ] + } + ] + } + } + } + ] + + it('should call onClose when closed', () => { + const handleClose = jest.fn() + const { getByRole } = render( + + + + ) + fireEvent.click(getByRole('button', { name: 'Close' })) + expect(handleClose).toHaveBeenCalled() + }) + + it('should select languages based on selectedIds', async () => { + const handleClose = jest.fn() + const { getByRole } = render( + + + + ) + await waitFor(() => + expect(getByRole('checkbox', { name: 'English English' })).toBeChecked() + ) + expect(getByRole('checkbox', { name: 'French Français' })).not.toBeChecked() + }) + + it('should call onChange and onClose when Apply clicked', async () => { + const handleChange = jest.fn() + const handleClose = jest.fn() + const { getByRole } = render( + + + + ) + await waitFor(() => + expect(getByRole('checkbox', { name: 'English English' })).toBeChecked() + ) + fireEvent.click(getByRole('checkbox', { name: 'English English' })) + fireEvent.click(getByRole('checkbox', { name: 'French Français' })) + fireEvent.click(getByRole('button', { name: 'Apply' })) + expect(handleChange).toHaveBeenCalledWith(['496']) + expect(handleClose).toHaveBeenCalled() + }) + + it('should clear selection when Clear clicked', async () => { + const handleChange = jest.fn() + const { getByRole } = render( + + + + ) + await waitFor(() => + expect(getByRole('checkbox', { name: 'English English' })).toBeChecked() + ) + fireEvent.click(getByRole('button', { name: 'Clear' })) + expect(getByRole('button', { name: 'Clear' })).toBeDisabled() + fireEvent.click(getByRole('checkbox', { name: 'French Français' })) + fireEvent.click(getByRole('button', { name: 'Apply' })) + expect(handleChange).toHaveBeenCalledWith(['496']) + }) +}) diff --git a/apps/journeys-admin/src/components/Editor/VideoLibrary/LanguageFilter/Drawer/Drawer.stories.tsx b/apps/journeys-admin/src/components/Editor/VideoLibrary/LanguageFilter/Drawer/Drawer.stories.tsx new file mode 100644 index 00000000000..070403b3c3c --- /dev/null +++ b/apps/journeys-admin/src/components/Editor/VideoLibrary/LanguageFilter/Drawer/Drawer.stories.tsx @@ -0,0 +1,90 @@ +import { Story, Meta } from '@storybook/react' +import { useState } from 'react' +import { MockedProvider } from '@apollo/client/testing' +import { simpleComponentConfig } from '../../../../../libs/storybook' +import { GET_LANGUAGES } from './Drawer' +import { Drawer } from '.' + +const DrawerStory = { + ...simpleComponentConfig, + component: Drawer, + title: 'Journeys-Admin/Editor/VideoLibrary/LanguageFilter/Drawer', + argTypes: { onSelect: { action: 'onSelect' } } +} + +const Template: Story = ({ onSelect }) => { + const [open, setOpen] = useState(true) + const [selectedIds, setSelectedIds] = useState(['en']) + const handleChange = (selectedIds: string[]): void => { + setSelectedIds(selectedIds) + onSelect(selectedIds) + } + + return ( + + setOpen(false)} + onChange={handleChange} + selectedIds={selectedIds} + currentLanguageId="529" + /> + + ) +} + +export const Default = Template.bind({}) + +export default DrawerStory as Meta diff --git a/apps/journeys-admin/src/components/Editor/VideoLibrary/LanguageFilter/Drawer/Drawer.tsx b/apps/journeys-admin/src/components/Editor/VideoLibrary/LanguageFilter/Drawer/Drawer.tsx new file mode 100644 index 00000000000..7e412bb0919 --- /dev/null +++ b/apps/journeys-admin/src/components/Editor/VideoLibrary/LanguageFilter/Drawer/Drawer.tsx @@ -0,0 +1,150 @@ +import List from '@mui/material/List' +import ListItem from '@mui/material/ListItem' +import ListItemButton from '@mui/material/ListItemButton' +import ListItemIcon from '@mui/material/ListItemIcon' +import ListItemText from '@mui/material/ListItemText' +import Checkbox from '@mui/material/Checkbox' +import IconButton from '@mui/material/IconButton' +import { ReactElement, useEffect, useState } from 'react' +import MuiDrawer from '@mui/material/Drawer' +import useMediaQuery from '@mui/material/useMediaQuery' +import { Theme } from '@mui/material/styles' +import AppBar from '@mui/material/AppBar' +import Toolbar from '@mui/material/Toolbar' +import Typography from '@mui/material/Typography' +import { Close } from '@mui/icons-material' +import Button from '@mui/material/Button' +import Box from '@mui/material/Box' +import { gql, useQuery } from '@apollo/client' +import { GetLanguages } from '../../../../../../__generated__/GetLanguages' + +export const DRAWER_WIDTH = 328 + +interface DrawerProps { + open?: boolean + onClose: () => void + onChange: (selectedIds: string[]) => void + selectedIds: string[] + currentLanguageId: string +} + +export const GET_LANGUAGES = gql` + query GetLanguages($languageId: ID) { + languages { + id + name(languageId: $languageId, primary: true) { + value + primary + } + } + } +` + +export function Drawer({ + open, + onClose: handleClose, + onChange: handleChange, + selectedIds: initialSelectedIds, + currentLanguageId +}: DrawerProps): ReactElement { + const smUp = useMediaQuery((theme: Theme) => theme.breakpoints.up('sm')) + const [selectedIds, setSelectedIds] = useState(initialSelectedIds) + const { data } = useQuery(GET_LANGUAGES, { + variables: { languageId: currentLanguageId } + }) + + useEffect(() => { + setSelectedIds(initialSelectedIds) + }, [initialSelectedIds]) + + const handleToggle = (id: string) => () => { + const currentIndex = selectedIds.indexOf(id) + const newSelectedIds = [...selectedIds] + + if (currentIndex === -1) { + newSelectedIds.push(id) + } else { + newSelectedIds.splice(currentIndex, 1) + } + + setSelectedIds(newSelectedIds) + } + + const handleClear = (): void => { + setSelectedIds([]) + } + + const handleApply = (): void => { + handleChange(selectedIds) + handleClose() + } + + return ( + + + + + Language + + + + + + + + {data?.languages?.map(({ id, name }) => ( + + + + + + translation?.primary === false) + ?.value ?? + name.find((translation) => translation?.primary === true) + ?.value + } + secondary={ + name.find((translation) => translation?.primary === true) + ?.value + } + /> + + + ))} + + + + + + + ) +} diff --git a/apps/journeys-admin/src/components/Editor/VideoLibrary/LanguageFilter/Drawer/index.ts b/apps/journeys-admin/src/components/Editor/VideoLibrary/LanguageFilter/Drawer/index.ts new file mode 100644 index 00000000000..6bcbde96c85 --- /dev/null +++ b/apps/journeys-admin/src/components/Editor/VideoLibrary/LanguageFilter/Drawer/index.ts @@ -0,0 +1 @@ +export { Drawer } from './Drawer'