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'