♻️(frontend) introduce a reusable tools sidepanel
tools will be added in the future, let's generalize the sidepanel previously reserved to transcription.
This commit is contained in:
committed by
aleb_the_flash
parent
60321296e5
commit
91562d049c
@@ -9,9 +9,9 @@ import { ParticipantsList } from './controls/Participants/ParticipantsList'
|
||||
import { useSidePanel } from '../hooks/useSidePanel'
|
||||
import { ReactNode } from 'react'
|
||||
import { Chat } from '../prefabs/Chat'
|
||||
import { Transcript } from './Transcript'
|
||||
import { Effects } from './effects/Effects'
|
||||
import { Admin } from './Admin'
|
||||
import { Tools } from './Tools'
|
||||
|
||||
type StyledSidePanelProps = {
|
||||
title: string
|
||||
@@ -114,7 +114,7 @@ export const SidePanel = () => {
|
||||
isEffectsOpen,
|
||||
isChatOpen,
|
||||
isSidePanelOpen,
|
||||
isTranscriptOpen,
|
||||
isToolsOpen,
|
||||
isAdminOpen,
|
||||
} = useSidePanel()
|
||||
const { t } = useTranslation('rooms', { keyPrefix: 'sidePanel' })
|
||||
@@ -137,8 +137,8 @@ export const SidePanel = () => {
|
||||
<Panel isOpen={isChatOpen}>
|
||||
<Chat />
|
||||
</Panel>
|
||||
<Panel isOpen={isTranscriptOpen}>
|
||||
<Transcript />
|
||||
<Panel isOpen={isToolsOpen}>
|
||||
<Tools />
|
||||
</Panel>
|
||||
<Panel isOpen={isAdminOpen}>
|
||||
<Admin />
|
||||
|
||||
95
src/frontend/src/features/rooms/livekit/components/Tools.tsx
Normal file
95
src/frontend/src/features/rooms/livekit/components/Tools.tsx
Normal file
@@ -0,0 +1,95 @@
|
||||
import { A, Div, Text } from '@/primitives'
|
||||
import { css } from '@/styled-system/css'
|
||||
import { Button as RACButton } from 'react-aria-components'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { CRISP_HELP_ARTICLE_MORE_TOOLS } from '@/utils/constants'
|
||||
import { ReactNode } from 'react'
|
||||
|
||||
export interface ToolsButtonProps {
|
||||
icon: ReactNode
|
||||
title: string
|
||||
description: string
|
||||
onPress: () => void
|
||||
}
|
||||
|
||||
const ToolButton = ({
|
||||
icon,
|
||||
title,
|
||||
description,
|
||||
onPress,
|
||||
}: ToolsButtonProps) => {
|
||||
return (
|
||||
<RACButton
|
||||
className={css({
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'start',
|
||||
paddingY: '0.5rem',
|
||||
paddingX: '0.75rem 1.5rem',
|
||||
borderRadius: '5px',
|
||||
gap: '1.25rem',
|
||||
width: 'full',
|
||||
textAlign: 'start',
|
||||
'&[data-hovered]': {
|
||||
backgroundColor: 'primary.50',
|
||||
cursor: 'pointer',
|
||||
},
|
||||
})}
|
||||
onPress={onPress}
|
||||
>
|
||||
<div
|
||||
className={css({
|
||||
height: '50px',
|
||||
minWidth: '50px',
|
||||
borderRadius: '25px',
|
||||
backgroundColor: 'primary.800',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
})}
|
||||
>
|
||||
{icon}
|
||||
</div>
|
||||
<div>
|
||||
<Text margin={false} as="h3">
|
||||
{title}
|
||||
</Text>
|
||||
<Text as="p" variant="smNote" wrap="pretty">
|
||||
{description}
|
||||
</Text>
|
||||
</div>
|
||||
</RACButton>
|
||||
)
|
||||
}
|
||||
|
||||
export const Tools = () => {
|
||||
const { t } = useTranslation('rooms', { keyPrefix: 'moreTools' })
|
||||
return (
|
||||
<Div
|
||||
display="flex"
|
||||
overflowY="scroll"
|
||||
padding="0 0.75rem"
|
||||
flexGrow={1}
|
||||
flexDirection="column"
|
||||
alignItems="start"
|
||||
>
|
||||
<Text
|
||||
variant="note"
|
||||
wrap="balance"
|
||||
className={css({
|
||||
textStyle: 'sm',
|
||||
paddingX: '0.75rem',
|
||||
})}
|
||||
margin="md"
|
||||
>
|
||||
{t('body')}{' '}
|
||||
<A href={CRISP_HELP_ARTICLE_MORE_TOOLS} target="_blank">
|
||||
{t('moreLink')}
|
||||
</A>
|
||||
.
|
||||
</Text>
|
||||
WIP
|
||||
</Div>
|
||||
)
|
||||
}
|
||||
@@ -1,24 +1,19 @@
|
||||
import { ToggleButton } from '@/primitives'
|
||||
import { RiBardLine } from '@remixicon/react'
|
||||
import { RiShapesLine } from '@remixicon/react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useSidePanel } from '../../hooks/useSidePanel'
|
||||
import { useHasTranscriptAccess } from '../../hooks/useHasTranscriptAccess'
|
||||
import { css } from '@/styled-system/css'
|
||||
import { ToggleButtonProps } from '@/primitives/ToggleButton'
|
||||
|
||||
export const TranscriptToggle = ({
|
||||
export const ToolsToggle = ({
|
||||
variant = 'primaryTextDark',
|
||||
onPress,
|
||||
...props
|
||||
}: ToggleButtonProps) => {
|
||||
const { t } = useTranslation('rooms', { keyPrefix: 'controls.transcript' })
|
||||
const { t } = useTranslation('rooms', { keyPrefix: 'controls.tools' })
|
||||
|
||||
const { isTranscriptOpen, toggleTranscript } = useSidePanel()
|
||||
const tooltipLabel = isTranscriptOpen ? 'open' : 'closed'
|
||||
|
||||
const hasTranscriptAccess = useHasTranscriptAccess()
|
||||
|
||||
if (!hasTranscriptAccess) return
|
||||
const { isToolsOpen, toggleTools } = useSidePanel()
|
||||
const tooltipLabel = isToolsOpen ? 'open' : 'closed'
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -32,15 +27,15 @@ export const TranscriptToggle = ({
|
||||
variant={variant}
|
||||
aria-label={t(tooltipLabel)}
|
||||
tooltip={t(tooltipLabel)}
|
||||
isSelected={isTranscriptOpen}
|
||||
isSelected={isToolsOpen}
|
||||
onPress={(e) => {
|
||||
toggleTranscript()
|
||||
toggleTools()
|
||||
onPress?.(e)
|
||||
}}
|
||||
{...props}
|
||||
data-attr="toggle-transcript"
|
||||
data-attr="toggle-tools"
|
||||
>
|
||||
<RiBardLine />
|
||||
<RiShapesLine />
|
||||
</ToggleButton>
|
||||
</div>
|
||||
)
|
||||
@@ -5,7 +5,7 @@ export enum PanelId {
|
||||
PARTICIPANTS = 'participants',
|
||||
EFFECTS = 'effects',
|
||||
CHAT = 'chat',
|
||||
TRANSCRIPT = 'transcript',
|
||||
TOOLS = 'tools',
|
||||
ADMIN = 'admin',
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ export const useSidePanel = () => {
|
||||
const isParticipantsOpen = activePanelId == PanelId.PARTICIPANTS
|
||||
const isEffectsOpen = activePanelId == PanelId.EFFECTS
|
||||
const isChatOpen = activePanelId == PanelId.CHAT
|
||||
const isTranscriptOpen = activePanelId == PanelId.TRANSCRIPT
|
||||
const isToolsOpen = activePanelId == PanelId.TOOLS
|
||||
const isAdminOpen = activePanelId == PanelId.ADMIN
|
||||
const isSidePanelOpen = !!activePanelId
|
||||
|
||||
@@ -36,8 +36,8 @@ export const useSidePanel = () => {
|
||||
layoutStore.activePanelId = isEffectsOpen ? null : PanelId.EFFECTS
|
||||
}
|
||||
|
||||
const toggleTranscript = () => {
|
||||
layoutStore.activePanelId = isTranscriptOpen ? null : PanelId.TRANSCRIPT
|
||||
const toggleTools = () => {
|
||||
layoutStore.activePanelId = isToolsOpen ? null : PanelId.TOOLS
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -45,13 +45,13 @@ export const useSidePanel = () => {
|
||||
toggleParticipants,
|
||||
toggleChat,
|
||||
toggleEffects,
|
||||
toggleTranscript,
|
||||
toggleTools,
|
||||
toggleAdmin,
|
||||
isChatOpen,
|
||||
isParticipantsOpen,
|
||||
isEffectsOpen,
|
||||
isSidePanelOpen,
|
||||
isTranscriptOpen,
|
||||
isToolsOpen,
|
||||
isAdminOpen,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ import { useSidePanel } from '../../hooks/useSidePanel'
|
||||
import { LinkButton } from '@/primitives'
|
||||
import { useSettingsDialog } from '../../components/controls/SettingsDialogContext'
|
||||
import { ResponsiveMenu } from './ResponsiveMenu'
|
||||
import { TranscriptToggle } from '../../components/controls/TranscriptToggle'
|
||||
import { ToolsToggle } from '../../components/controls/ToolsToggle'
|
||||
import { CameraSwitchButton } from '../../components/controls/CameraSwitchButton'
|
||||
|
||||
export function MobileControlBar({
|
||||
@@ -133,7 +133,7 @@ export function MobileControlBar({
|
||||
description={true}
|
||||
onPress={() => setIsMenuOpened(false)}
|
||||
/>
|
||||
<TranscriptToggle
|
||||
<ToolsToggle
|
||||
description={true}
|
||||
onPress={() => setIsMenuOpened(false)}
|
||||
/>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { css } from '@/styled-system/css'
|
||||
import { ChatToggle } from '../../components/controls/ChatToggle'
|
||||
import { ParticipantsToggle } from '../../components/controls/Participants/ParticipantsToggle'
|
||||
import { TranscriptToggle } from '../../components/controls/TranscriptToggle'
|
||||
import { ToolsToggle } from '../../components/controls/ToolsToggle'
|
||||
import { AdminToggle } from '../../components/AdminToggle'
|
||||
import { useSize } from '../../hooks/useResizeObserver'
|
||||
import { useState, RefObject } from 'react'
|
||||
@@ -20,7 +20,7 @@ const NavigationControls = ({
|
||||
<>
|
||||
<ChatToggle onPress={onPress} tooltipType={tooltipType} />
|
||||
<ParticipantsToggle onPress={onPress} tooltipType={tooltipType} />
|
||||
<TranscriptToggle onPress={onPress} tooltipType={tooltipType} />
|
||||
<ToolsToggle onPress={onPress} tooltipType={tooltipType} />
|
||||
<AdminToggle onPress={onPress} tooltipType={tooltipType} />
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
"open": "",
|
||||
"closed": ""
|
||||
},
|
||||
"transcript": {
|
||||
"tools": {
|
||||
"open": "",
|
||||
"closed": ""
|
||||
},
|
||||
@@ -169,20 +169,27 @@
|
||||
"effects": "",
|
||||
"chat": "",
|
||||
"transcript": "",
|
||||
"admin": ""
|
||||
"admin": "",
|
||||
"tools": ""
|
||||
},
|
||||
"content": {
|
||||
"participants": "",
|
||||
"effects": "",
|
||||
"chat": "",
|
||||
"transcript": "",
|
||||
"admin": ""
|
||||
"admin": "",
|
||||
"tools": ""
|
||||
},
|
||||
"closeButton": ""
|
||||
},
|
||||
"chat": {
|
||||
"disclaimer": ""
|
||||
},
|
||||
"moreTools": {
|
||||
"body": "",
|
||||
"moreLink": "",
|
||||
"tools": {}
|
||||
},
|
||||
"transcript": {
|
||||
"start": {
|
||||
"heading": "",
|
||||
|
||||
@@ -103,9 +103,9 @@
|
||||
"open": "Hide everyone",
|
||||
"closed": "See everyone"
|
||||
},
|
||||
"transcript": {
|
||||
"open": "Hide AI assistant",
|
||||
"closed": "Show AI assistant"
|
||||
"tools": {
|
||||
"open": "Hide more tools",
|
||||
"closed": "Show more tools"
|
||||
},
|
||||
"admin": {
|
||||
"open": "Hide admin",
|
||||
@@ -168,20 +168,27 @@
|
||||
"effects": "Effects",
|
||||
"chat": "Messages in the chat",
|
||||
"transcript": "AI Assistant",
|
||||
"admin": "Admin settings"
|
||||
"admin": "Admin settings",
|
||||
"tools": "More tools"
|
||||
},
|
||||
"content": {
|
||||
"participants": "participants",
|
||||
"effects": "effects",
|
||||
"chat": "messages",
|
||||
"transcript": "AI assistant",
|
||||
"admin": "Admin settings"
|
||||
"admin": "admin settings",
|
||||
"tools": "more tools"
|
||||
},
|
||||
"closeButton": "Hide {{content}}"
|
||||
},
|
||||
"chat": {
|
||||
"disclaimer": "The messages are visible to participants only at the time they are sent. All messages are deleted at the end of the call."
|
||||
},
|
||||
"moreTools": {
|
||||
"body": "Access more tools in Visio to enhance your meetings,",
|
||||
"moreLink": "learn more",
|
||||
"tools": {}
|
||||
},
|
||||
"transcript": {
|
||||
"start": {
|
||||
"heading": "Start the Assistant!",
|
||||
|
||||
@@ -103,9 +103,9 @@
|
||||
"open": "Masquer les participants",
|
||||
"closed": "Afficher les participants"
|
||||
},
|
||||
"transcript": {
|
||||
"open": "Masquer l'assistant IA",
|
||||
"closed": "Afficher l'assistant IA"
|
||||
"tools": {
|
||||
"open": "Masquer plus d'outils",
|
||||
"closed": "Afficher plus d'outils"
|
||||
},
|
||||
"admin": {
|
||||
"open": "Masquer l'admin",
|
||||
@@ -168,20 +168,27 @@
|
||||
"effects": "Effets",
|
||||
"chat": "Messages dans l'appel",
|
||||
"transcript": "Assistant IA",
|
||||
"admin": "Commandes de l'organisateur"
|
||||
"admin": "Commandes de l'organisateur",
|
||||
"tools": "Plus d'outils"
|
||||
},
|
||||
"content": {
|
||||
"participants": "les participants",
|
||||
"effects": "les effets",
|
||||
"chat": "les messages",
|
||||
"transcript": "l'assistant IA",
|
||||
"admin": "Commandes de l'organisateur"
|
||||
"admin": "commandes de l'organisateur",
|
||||
"tools": "plus d'outils"
|
||||
},
|
||||
"closeButton": "Masquer {{content}}"
|
||||
},
|
||||
"chat": {
|
||||
"disclaimer": "Les messages sont visibles par les participants uniquement au moment de\nleur envoi. Tous les messages sont supprimés à la fin de l'appel."
|
||||
},
|
||||
"moreTools": {
|
||||
"body": "Accèder à d'avantage d'outils dans Visio pour améliorer vos réunions,",
|
||||
"moreLink": "en savoir plus",
|
||||
"tools": {}
|
||||
},
|
||||
"transcript": {
|
||||
"start": {
|
||||
"heading": "Démarrer l'assistant !",
|
||||
|
||||
@@ -103,9 +103,9 @@
|
||||
"open": "Verberg iedereen",
|
||||
"closed": "Toon iedereen"
|
||||
},
|
||||
"transcript": {
|
||||
"open": "Verberg AI-assistent",
|
||||
"closed": "Toon AI-assistant"
|
||||
"tools": {
|
||||
"open": "Meer tools verbergen",
|
||||
"closed": "Meer tools weergeven"
|
||||
},
|
||||
"admin": {
|
||||
"open": "Verberg beheerder",
|
||||
@@ -168,20 +168,27 @@
|
||||
"effects": "Effecten",
|
||||
"chat": "Berichten in de chat",
|
||||
"transcript": "AI-assistent",
|
||||
"admin": "Beheerdersbediening"
|
||||
"admin": "Beheerdersbediening",
|
||||
"tools": "Meer tools"
|
||||
},
|
||||
"content": {
|
||||
"participants": "deelnemers",
|
||||
"effects": "effecten",
|
||||
"chat": "berichten",
|
||||
"transcript": "AI-assistent",
|
||||
"admin": "Beheerdersbediening"
|
||||
"admin": "beheerdersbediening",
|
||||
"tools": "meer tools"
|
||||
},
|
||||
"closeButton": "Verberg {{content}}"
|
||||
},
|
||||
"chat": {
|
||||
"disclaimer": "De berichten zijn alleen voor de deelnemers zichtbaar op het moment dat ze worden verzonden. Alle berichten worden verwijderd aan het einde van het gesprek."
|
||||
},
|
||||
"moreTools": {
|
||||
"body": "Toegang tot meer tools in Visio om je vergaderingen te verbeteren,",
|
||||
"moreLink": "lees meer",
|
||||
"tools": {}
|
||||
},
|
||||
"transcript": {
|
||||
"start": {
|
||||
"heading": "Start de assistent!",
|
||||
|
||||
@@ -3,3 +3,6 @@ export const GRIST_FEEDBACKS_FORM =
|
||||
|
||||
export const BETA_USERS_FORM_URL =
|
||||
'https://grist.numerique.gouv.fr/o/docs/forms/3fFfvJoTBEQ6ZiMi8zsQwX/17' as const
|
||||
|
||||
export const CRISP_HELP_ARTICLE_MORE_TOOLS =
|
||||
'https://lasuite.crisp.help/fr/article/visio-tools-bvxj23' as const
|
||||
|
||||
Reference in New Issue
Block a user