🚸(frontend) rework the meeting tools side panel UX

Explicitly explain that transcription is reserved for public servants. Remove
the temporary beta form: the feature is now available to all public servants,
with restrictions based on domain. Make white-labeling rules explicit and
clarify who to contact for access.

The beta form created frustration, with users registering and never hearing
back from the team.

Improve guidance when a user may be the meeting host but is not logged in, and
therefore cannot activate recording. Add a clear hint and a quick action to log
in. This decision is based on frequent support requests where users could not
understand why recording was unavailable while they were simply not logged in.
This commit is contained in:
lebaudantoine
2025-12-12 19:13:58 +01:00
committed by aleb_the_flash
parent 2fbb476b02
commit d3e6af6f82
13 changed files with 476 additions and 251 deletions

View File

@@ -277,7 +277,6 @@ These are the environmental options available on meet backend.
| FRONTEND_CUSTOM_CSS_URL | URL of an additional CSS file to load in the frontend app. If set, a `<link>` tag with this URL as href is added to the `<head>` of the frontend app | |
| FRONTEND_ANALYTICS | Analytics information | {} |
| FRONTEND_SUPPORT | Crisp frontend support configuration, also you can pass help articles, with `help_article_transcript`, `help_article_recording`, `help_article_more_tools` | {} |
| FRONTEND_TRANSCRIPT | Frontend transcription configuration, you can pass a beta form, with `form_beta_users` | {} |
| FRONTEND_MANIFEST_LINK | Link to the "Learn more" button on the homepage | {} |
| FRONTEND_SILENCE_LIVEKIT_DEBUG | Silence LiveKit debug logs | false |
| FRONTEND_IS_SILENT_LOGIN_ENABLED | Enable silent login feature | true |

View File

@@ -342,9 +342,6 @@ class Base(Configuration):
"use_proconnect_button": values.BooleanValue(
False, environ_name="FRONTEND_USE_PROCONNECT_BUTTON", environ_prefix=None
),
"transcript": values.DictValue(
{}, environ_name="FRONTEND_TRANSCRIPT", environ_prefix=None
),
"manifest_link": values.Value(
None, environ_name="FRONTEND_MANIFEST_LINK", environ_prefix=None
),

View File

@@ -17,9 +17,6 @@ export interface ApiConfig {
feedback: {
url: string
}
transcript: {
form_beta_users: string
}
silence_livekit_debug_logs?: boolean
is_silent_login_enabled?: boolean
custom_css_url?: string

View File

@@ -1,10 +1,9 @@
import { styled } from '@/styled-system/jsx'
import { css } from '@/styled-system/css'
import { Button, LinkButton } from '@/primitives'
import { Button } from '@/primitives'
import { RiArrowLeftSLine, RiArrowRightSLine } from '@remixicon/react'
import { useMemo, useState } from 'react'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useConfig } from '@/api/useConfig'
const Heading = styled('h2', {
base: {
@@ -165,14 +164,7 @@ export const IntroSlider = () => {
const [slideIndex, setSlideIndex] = useState(0)
const { t } = useTranslation('home', { keyPrefix: 'introSlider' })
const { data } = useConfig()
const filteredSlides = useMemo(
() => (data?.transcript?.form_beta_users ? SLIDES : SLIDES.slice(0, 2)),
[data]
)
const NUMBER_SLIDES = filteredSlides.length
const NUMBER_SLIDES = SLIDES.length
return (
<Container>
@@ -198,24 +190,12 @@ export const IntroSlider = () => {
</ButtonVerticalCenter>
</ButtonContainer>
<SlideContainer>
{filteredSlides.map((slide, index) => (
{SLIDES.map((slide, index) => (
<Slide visible={index == slideIndex} key={index}>
<Image src={slide.src} alt={t(`${slide.key}.imgAlt`)} />
<TextAnimation visible={index == slideIndex}>
<Heading>{t(`${slide.key}.title`)}</Heading>
<Body>{t(`${slide.key}.body`)}</Body>
{slide.isAvailableInBeta && (
<LinkButton
href={data?.transcript.form_beta_users}
target="_blank"
tooltip={t('beta.tooltip')}
variant={'primary'}
size={'sm'}
style={{ marginTop: '1rem', width: 'fit-content' }}
>
{t('beta.text')}
</LinkButton>
)}
</TextAnimation>
</Slide>
))}
@@ -241,7 +221,7 @@ export const IntroSlider = () => {
display: { base: 'none', xsm: 'block' },
})}
>
{filteredSlides.map((_, index) => (
{SLIDES.map((_, index) => (
<Dot key={index} selected={index == slideIndex} />
))}
</div>

View File

@@ -5,6 +5,7 @@ import { useRoomId } from '@/features/rooms/livekit/hooks/useRoomId'
import { useRoomContext } from '@livekit/components-react'
import {
RecordingMode,
useHasFeatureWithoutAdminRights,
useIsRecordingTransitioning,
useStartRecording,
useStopRecording,
@@ -25,6 +26,9 @@ import { Spinner } from '@/primitives/Spinner'
import { useConfig } from '@/api/useConfig'
import humanizeDuration from 'humanize-duration'
import i18n from 'i18next'
import { FeatureFlags } from '@/features/analytics/enums'
import { LoginButton } from '@/components/LoginButton'
import { useUser } from '@/features/auth'
export const ScreenRecordingSidePanel = () => {
const { data } = useConfig()
@@ -34,6 +38,13 @@ export const ScreenRecordingSidePanel = () => {
const [isErrorDialogOpen, setIsErrorDialogOpen] = useState('')
const hasFeatureWithoutAdminRights = useHasFeatureWithoutAdminRights(
RecordingMode.ScreenRecording,
FeatureFlags.ScreenRecording
)
const { isLoggedIn } = useUser()
const { notifyParticipants } = useNotifyParticipants()
const roomId = useRoomId()
@@ -117,6 +128,97 @@ export const ScreenRecordingSidePanel = () => {
[isLoading, isRecordingTransitioning, statuses, isRoomConnected]
)
if (hasFeatureWithoutAdminRights) {
return (
<Div
display="flex"
overflowY="scroll"
padding="0 1.5rem"
flexGrow={1}
flexDirection="column"
alignItems="center"
>
<img
src="/assets/intro-slider/4.png"
alt={''}
className={css({
minHeight: '309px',
height: '309px',
marginBottom: '1rem',
'@media (max-height: 700px)': {
height: 'auto',
minHeight: 'auto',
maxHeight: '45%',
marginBottom: '0.3rem',
},
'@media (max-height: 530px)': {
height: 'auto',
minHeight: 'auto',
maxHeight: '40%',
marginBottom: '0.1rem',
},
})}
/>
<Text>{t('notAdminOrOwner.heading')}</Text>
<Text
variant="note"
wrap="balance"
centered
className={css({
textStyle: 'sm',
marginBottom: '2.5rem',
marginTop: '0.25rem',
'@media (max-height: 700px)': {
marginBottom: '1rem',
},
})}
>
{t('notAdminOrOwner.body')}
<br />
{data?.support?.help_article_recording && (
<A href={data.support.help_article_recording} target="_blank">
{t('notAdminOrOwner.linkMore')}
</A>
)}
</Text>
{!isLoggedIn && (
<div
className={css({
backgroundColor: 'primary.50',
borderRadius: '5px',
paddingY: '1rem',
paddingX: '1rem',
marginTop: '1rem',
display: 'flex',
flexDirection: 'column',
})}
>
<H
lvl={3}
className={css({
display: 'flex',
alignItems: 'center',
marginBottom: '0.35rem',
})}
>
{t('notAdminOrOwner.login.heading')}
</H>
<Text variant="smNote" wrap="balance">
{t('notAdminOrOwner.login.body')}
</Text>
<div
className={css({
marginTop: '1rem',
})}
>
<LoginButton proConnectHint={false} />
</div>
</div>
)}
</Div>
)
}
return (
<Div
display="flex"

View File

@@ -1,4 +1,4 @@
import { A, Button, Dialog, Div, H, LinkButton, P, Text } from '@/primitives'
import { A, Button, Dialog, Div, H, P, Text } from '@/primitives'
import { css } from '@/styled-system/css'
import { useRoomId } from '@/features/rooms/livekit/hooks/useRoomId'
@@ -27,10 +27,14 @@ import { Spinner } from '@/primitives/Spinner'
import { useConfig } from '@/api/useConfig'
import humanizeDuration from 'humanize-duration'
import i18n from 'i18next'
import { useUser } from '@/features/auth'
import { LoginButton } from '@/components/LoginButton'
export const TranscriptSidePanel = () => {
const { data } = useConfig()
const { isLoggedIn } = useUser()
const [isLoading, setIsLoading] = useState(false)
const { t } = useTranslation('rooms', { keyPrefix: 'transcript' })
@@ -127,6 +131,184 @@ export const TranscriptSidePanel = () => {
[isLoading, isRecordingTransitioning, statuses, isRoomConnected]
)
if (hasFeatureWithoutAdminRights) {
return (
<Div
display="flex"
overflowY="scroll"
padding="0 1.5rem"
flexGrow={1}
flexDirection="column"
alignItems="center"
>
<img
src="/assets/intro-slider/3.png"
alt={''}
className={css({
minHeight: '309px',
height: '309px',
marginBottom: '1rem',
'@media (max-height: 700px)': {
height: 'auto',
minHeight: 'auto',
maxHeight: '45%',
marginBottom: '0.3rem',
},
'@media (max-height: 530px)': {
height: 'auto',
minHeight: 'auto',
maxHeight: '40%',
marginBottom: '0.1rem',
},
})}
/>
<Text>{t('notAdminOrOwner.heading')}</Text>
<Text
variant="note"
wrap="balance"
centered
className={css({
textStyle: 'sm',
marginBottom: '2.5rem',
marginTop: '0.25rem',
'@media (max-height: 700px)': {
marginBottom: '1rem',
},
})}
>
{t('notAdminOrOwner.body')}
<br />
{data?.support?.help_article_transcript && (
<A href={data.support.help_article_transcript} target="_blank">
{t('notAdminOrOwner.linkMore')}
</A>
)}
</Text>
{!isLoggedIn && (
<div
className={css({
backgroundColor: 'primary.50',
borderRadius: '5px',
paddingY: '1rem',
paddingX: '1rem',
marginTop: '1rem',
display: 'flex',
flexDirection: 'column',
})}
>
<H
lvl={3}
className={css({
display: 'flex',
alignItems: 'center',
marginBottom: '0.35rem',
})}
>
{t('notAdminOrOwner.login.heading')}
</H>
<Text variant="smNote" wrap="balance">
{t('notAdminOrOwner.login.body')}
</Text>
<div
className={css({
marginTop: '1rem',
})}
>
<LoginButton proConnectHint={false} />
</div>
</div>
)}
</Div>
)
}
if (!hasTranscriptAccess) {
return (
<Div
display="flex"
overflowY="scroll"
padding="0 1.5rem"
flexGrow={1}
flexDirection="column"
alignItems="center"
>
<img
src="/assets/intro-slider/3.png"
alt={''}
className={css({
minHeight: '309px',
height: '309px',
marginBottom: '1rem',
'@media (max-height: 700px)': {
height: 'auto',
minHeight: 'auto',
maxHeight: '45%',
marginBottom: '0.3rem',
},
'@media (max-height: 530px)': {
height: 'auto',
minHeight: 'auto',
maxHeight: '40%',
marginBottom: '0.1rem',
},
})}
/>
<Text>{t('premium.heading')}</Text>
<Text
variant="note"
centered
className={css({
textStyle: 'sm',
marginBottom: '2.5rem',
marginTop: '0.25rem',
'@media (max-height: 700px)': {
marginBottom: '1rem',
},
})}
>
{t('premium.body')}{' '}
{data?.support?.help_article_transcript && (
<A href={data.support.help_article_transcript} target="_blank">
{t('linkMore')}
</A>
)}
</Text>
{!isLoggedIn && (
<div
className={css({
backgroundColor: 'primary.50',
borderRadius: '5px',
paddingY: '1rem',
paddingX: '1rem',
marginTop: '1rem',
display: 'flex',
flexDirection: 'column',
})}
>
<H
lvl={3}
className={css({
display: 'flex',
alignItems: 'center',
marginBottom: '0.35rem',
})}
>
{t('premium.login.heading')}
</H>
<Text variant="smNote">{t('premium.login.body')}</Text>
<div
className={css({
marginTop: '1rem',
})}
>
<LoginButton proConnectHint={false} />
</div>
</div>
)}
</Div>
)
}
return (
<Div
display="flex"
@@ -157,194 +339,123 @@ export const TranscriptSidePanel = () => {
},
})}
/>
{!hasTranscriptAccess ? (
<>
{hasFeatureWithoutAdminRights ? (
<>
<Text>{t('notAdminOrOwner.heading')}</Text>
<Text
variant="note"
wrap="balance"
centered
className={css({
textStyle: 'sm',
marginBottom: '2.5rem',
marginTop: '0.25rem',
'@media (max-height: 700px)': {
marginBottom: '1rem',
},
})}
>
{t('notAdminOrOwner.body')}
<br />
{data?.support?.help_article_transcript && (
<A
href={data.support.help_article_transcript}
target="_blank"
>
{t('notAdminOrOwner.linkMore')}
</A>
)}
</Text>
</>
) : (
<>
<Text>{t('beta.heading')}</Text>
<Text
variant="note"
wrap={'pretty'}
centered
className={css({
textStyle: 'sm',
marginBottom: '2.5rem',
marginTop: '0.25rem',
'@media (max-height: 700px)': {
marginBottom: '1rem',
},
})}
>
{t('beta.body')}{' '}
{data?.support?.help_article_transcript && (
<A
href={data.support.help_article_transcript}
target="_blank"
>
{t('start.linkMore')}
</A>
)}
</Text>
{data?.transcript.form_beta_users && (
<LinkButton
<>
{statuses.isStarted ? (
<>
<H lvl={3} margin={false}>
{t('stop.heading')}
</H>
<Text
variant="note"
wrap={'pretty'}
centered
className={css({
textStyle: 'sm',
marginBottom: '2.5rem',
marginTop: '0.25rem',
'@media (max-height: 700px)': {
marginBottom: '1rem',
},
})}
>
{t('stop.body')}
</Text>
<Button
isDisabled={isDisabled}
onPress={() => handleTranscript()}
data-attr="stop-transcript"
size="sm"
variant="tertiary"
>
{t('stop.button')}
</Button>
</>
) : (
<>
{statuses.isStopping || isPendingToStop ? (
<>
<H lvl={3} margin={false}>
{t('stopping.heading')}
</H>
<Text
variant="note"
wrap={'pretty'}
centered
className={css({
textStyle: 'sm',
maxWidth: '90%',
marginBottom: '2.5rem',
marginTop: '0.25rem',
'@media (max-height: 700px)': {
marginBottom: '1rem',
},
})}
>
{t('stopping.body')}
</Text>
<Spinner />
</>
) : (
<>
<H lvl={3} margin={false}>
{t('start.heading')}
</H>
<Text
variant="note"
wrap="balance"
centered
className={css({
textStyle: 'sm',
maxWidth: '90%',
marginBottom: '2.5rem',
marginTop: '0.25rem',
'@media (max-height: 700px)': {
marginBottom: '1rem',
},
})}
>
{t('start.body', {
duration_message: data?.recording?.max_duration
? t('durationMessage', {
max_duration: humanizeDuration(
data?.recording?.max_duration,
{
language: i18n.language,
}
),
})
: '',
})}{' '}
{data?.support?.help_article_transcript && (
<A
href={data.support.help_article_transcript}
target="_blank"
>
{t('start.linkMore')}
</A>
)}
</Text>
<Button
isDisabled={isDisabled}
onPress={() => handleTranscript()}
data-attr="start-transcript"
size="sm"
variant="tertiary"
href={data?.transcript.form_beta_users}
target="_blank"
>
{t('beta.button')}
</LinkButton>
)}
</>
)}
</>
) : (
<>
{statuses.isStarted ? (
<>
<H lvl={3} margin={false}>
{t('stop.heading')}
</H>
<Text
variant="note"
wrap={'pretty'}
centered
className={css({
textStyle: 'sm',
marginBottom: '2.5rem',
marginTop: '0.25rem',
'@media (max-height: 700px)': {
marginBottom: '1rem',
},
})}
>
{t('stop.body')}
</Text>
<Button
isDisabled={isDisabled}
onPress={() => handleTranscript()}
data-attr="stop-transcript"
size="sm"
variant="tertiary"
>
{t('stop.button')}
</Button>
</>
) : (
<>
{statuses.isStopping || isPendingToStop ? (
<>
<H lvl={3} margin={false}>
{t('stopping.heading')}
</H>
<Text
variant="note"
wrap={'pretty'}
centered
className={css({
textStyle: 'sm',
maxWidth: '90%',
marginBottom: '2.5rem',
marginTop: '0.25rem',
'@media (max-height: 700px)': {
marginBottom: '1rem',
},
})}
>
{t('stopping.body')}
</Text>
<Spinner />
</>
) : (
<>
<H lvl={3} margin={false}>
{t('start.heading')}
</H>
<Text
variant="note"
wrap="balance"
centered
className={css({
textStyle: 'sm',
maxWidth: '90%',
marginBottom: '2.5rem',
marginTop: '0.25rem',
'@media (max-height: 700px)': {
marginBottom: '1rem',
},
})}
>
{t('start.body', {
duration_message: data?.recording?.max_duration
? t('durationMessage', {
max_duration: humanizeDuration(
data?.recording?.max_duration,
{
language: i18n.language,
}
),
})
: '',
})}{' '}
{data?.support?.help_article_transcript && (
<A
href={data.support.help_article_transcript}
target="_blank"
>
{t('start.linkMore')}
</A>
)}
</Text>
<Button
isDisabled={isDisabled}
onPress={() => handleTranscript()}
data-attr="start-transcript"
size="sm"
variant="tertiary"
>
{statuses.isStarting || isPendingToStart ? (
<>
<Spinner size={20} />
{t('start.loading')}
</>
) : (
t('start.button')
)}
</Button>
</>
)}
</>
)}
</>
)}
{statuses.isStarting || isPendingToStart ? (
<>
<Spinner size={20} />
{t('start.loading')}
</>
) : (
t('start.button')
)}
</Button>
</>
)}
</>
)}
</>
<Dialog
isOpen={!!isErrorDialogOpen}
role="alertdialog"

View File

@@ -7,11 +7,9 @@ import { SubPanelId, useSidePanel } from '../hooks/useSidePanel'
import {
useIsRecordingModeEnabled,
RecordingMode,
useHasRecordingAccess,
TranscriptSidePanel,
ScreenRecordingSidePanel,
} from '@/features/recording'
import { FeatureFlags } from '@/features/analytics/enums'
import { useConfig } from '@/api/useConfig'
export interface ToolsButtonProps {
@@ -104,9 +102,8 @@ export const Tools = () => {
RecordingMode.Transcript
)
const hasScreenRecordingAccess = useHasRecordingAccess(
RecordingMode.ScreenRecording,
FeatureFlags.ScreenRecording
const isScreenRecordingEnabled = useIsRecordingModeEnabled(
RecordingMode.ScreenRecording
)
switch (activeSubPanelId) {
@@ -155,7 +152,7 @@ export const Tools = () => {
onPress={() => openTranscript()}
/>
)}
{hasScreenRecordingAccess && (
{isScreenRecordingEnabled && (
<ToolButton
icon={<span className="material-symbols">mode_standby</span>}
title={t('tools.screenRecording.title')}

View File

@@ -320,7 +320,11 @@
"notAdminOrOwner": {
"heading": "Zugriff eingeschränkt",
"body": "Aus Sicherheitsgründen kann nur der Ersteller oder ein Administrator des Meetings eine Transkription (Beta) starten.",
"linkMore": "Mehr erfahren"
"linkMore": "Mehr erfahren",
"login": {
"heading": "Anmeldung erforderlich",
"body": "Nur der Ersteller des Meetings oder ein Administrator kann die Transkription starten. Melden Sie sich an, um Ihre Berechtigungen zu überprüfen."
}
},
"stop": {
"heading": "Transkription läuft...",
@@ -331,10 +335,13 @@
"heading": "Daten werden gespeichert…",
"body": "Sie können das Meeting verlassen, wenn Sie möchten; die Aufzeichnung wird automatisch beendet."
},
"beta": {
"heading": "Werde Beta-Tester",
"body": "Zeichne dein Meeting auf. Du erhältst eine Zusammenfassung per E-Mail nach dem Meeting.",
"button": "Anmelden"
"premium": {
"heading": "Premium-Funktion",
"body": "Diese Funktion ist öffentlichen Bediensteten vorbehalten. Wenn Ihre E-Mail-Adresse nicht autorisiert ist, kontaktieren Sie bitte den Support, um Zugriff zu erhalten.",
"login": {
"heading": "Anmeldung erforderlich",
"body": "Nur der Ersteller des Meetings oder ein Administrator kann die Transkription starten. Melden Sie sich an, um Ihre Berechtigungen zu überprüfen."
}
},
"alert": {
"title": "Transkription fehlgeschlagen",
@@ -356,8 +363,12 @@
},
"notAdminOrOwner": {
"heading": "Zugriff eingeschränkt",
"body": "Aus Sicherheitsgründen kann nur der Ersteller oder ein Administrator des Meetings eine videoaufnahme (Beta) starten.",
"linkMore": "Mehr erfahren"
"body": "Aus Sicherheitsgründen kann nur der Ersteller oder ein Administrator des Meetings eine Videoaufnahme (Beta) starten.",
"linkMore": "Mehr erfahren",
"login": {
"heading": "Anmeldung erforderlich",
"body": "Nur der Ersteller der Besprechung oder ein Administrator kann die Aufzeichnung starten. Melden Sie sich an, um Ihre Berechtigungen zu überprüfen."
}
},
"stopping": {
"heading": "Daten werden gespeichert…",

View File

@@ -320,7 +320,11 @@
"notAdminOrOwner": {
"heading": "Restricted Access",
"body": "For security reasons, only the meeting creator or an admin can start a transcription (beta).",
"linkMore": "Learn more"
"linkMore": "Learn more",
"login": {
"heading": "Login Required",
"body": "Only the meeting creator or an admin can start a transcription. Log in to verify your permissions."
}
},
"stop": {
"heading": "Transcription in progress...",
@@ -331,10 +335,13 @@
"heading": "Saving your data…",
"body": "You can leave the meeting if you wish; the recording will finish automatically."
},
"beta": {
"heading": "Become a beta tester",
"body": "Record your meeting for later. You will receive a summary by email once the meeting is finished.",
"button": "Sign up"
"premium": {
"heading": "Premium feature",
"body": "This feature is reserved for public agents. If your email address is not authorized, please contact support to get access.",
"login": {
"heading": "You are not logged in!",
"body": "You must be logged in to use this feature. Please log in, then try again."
}
},
"alert": {
"title": "Transcription Failed",
@@ -357,7 +364,11 @@
"notAdminOrOwner": {
"heading": "Restricted Access",
"body": "For security reasons, only the meeting creator or an admin can start a recording (beta).",
"linkMore": "Learn more"
"linkMore": "Learn more",
"login": {
"heading": "Login Required",
"body": "Only the meeting creator or an admin can start screen recording. Log in to verify your permissions."
}
},
"stopping": {
"heading": "Saving your data…",

View File

@@ -320,7 +320,11 @@
"notAdminOrOwner": {
"heading": "Accès restreint",
"body": "Pour des raisons de sécurité, seul le créateur ou un administrateur de la réunion peut lancer une transcription (beta).",
"linkMore": "En savoir plus"
"linkMore": "En savoir plus",
"login": {
"heading": "Connexion requise",
"body": "Seul le créateur de la réunion ou un administrateur peut démarrer la transcription. Connectez-vous pour vérifier vos autorisations."
}
},
"stop": {
"heading": "Transcription en cours …",
@@ -331,10 +335,13 @@
"heading": "Sauvegarde de vos données…",
"body": "Vous pouvez quitter la réunion si vous le souhaitez, la sauvegarde se terminera automatiquement."
},
"beta": {
"heading": "Devenez beta testeur",
"body": "Enregistrer votre réunion pour plus tard. Vous recevrez un compte-rendu par email une fois la réunion terminée.",
"button": "Inscrivez-vous"
"premium": {
"heading": "Fonctionnalité premium",
"body": "Cette fonctionnalité est réservée aux agents publics. Si votre adresse email nest pas autorisée, contactez le support pour obtenir l'accès.",
"login": {
"heading": "Vous n'êtes pas connecté !",
"body": "Vous devez être connecté pour utiliser cette fonctionnalité. Connectez-vous, puis réessayez."
}
},
"alert": {
"title": "Échec de transcription",
@@ -357,7 +364,11 @@
"notAdminOrOwner": {
"heading": "Accès restreint",
"body": "Pour des raisons de sécurité, seul le créateur ou un administrateur de la réunion peut lancer un enregistrement (beta).",
"linkMore": "En savoir plus"
"linkMore": "En savoir plus",
"login": {
"heading": "Connexion requise",
"body": "Seul le créateur de la réunion ou un administrateur peut démarrer l'enregistrement. Connectez-vous pour vérifier vos autorisations."
}
},
"stopping": {
"heading": "Sauvegarde de vos données…",

View File

@@ -320,7 +320,11 @@
"notAdminOrOwner": {
"heading": "Toegang beperkt",
"body": "Om veiligheidsredenen kan alleen de maker of een beheerder van de vergadering een transcriptie starten (beta).",
"linkMore": "Meer informatie"
"linkMore": "Meer informatie",
"login": {
"heading": "Inloggen vereist",
"body": "Alleen de maker van de vergadering of een beheerder kan de transcriptie starten. Log in om uw machtigingen te controleren."
}
},
"stop": {
"heading": "Transcriptie bezig...",
@@ -331,10 +335,13 @@
"heading": "Uw gegevens worden opgeslagen…",
"body": "U kunt de vergadering verlaten als u dat wilt; de opname wordt automatisch voltooid."
},
"beta": {
"heading": "Word betatester",
"body": "Neem uw vergadering op voor later. U ontvangt een samenvatting per e-mail zodra de vergadering is afgelopen.",
"button": "Aanmelden"
"premium": {
"heading": "Premiumfunctie",
"body": "Deze functie is voorbehouden aan openbare medewerkers. Als uw e-mailadres niet is toegestaan, neem dan contact op met de support om toegang te krijgen.",
"login": {
"heading": "Inloggen vereist",
"body": "Alleen de maker van de vergadering of een beheerder kan de transcriptie starten. Log in om uw machtigingen te controleren."
}
},
"alert": {
"title": "Transcriptie mislukt",
@@ -357,7 +364,11 @@
"notAdminOrOwner": {
"heading": "Toegang beperkt",
"body": "Om veiligheidsredenen kan alleen de maker of een beheerder van de vergadering een opname starten (beta).",
"linkMore": "Meer informatie"
"linkMore": "Meer informatie",
"login": {
"heading": "Inloggen vereist",
"body": "Alleen de maker van de vergadering of een beheerder kan de opname starten. Log in om uw machtigingen te controleren."
}
},
"stopping": {
"heading": "Uw gegevens worden opgeslagen…",

View File

@@ -52,7 +52,6 @@ backend:
ALLOW_UNREGISTERED_ROOMS: False
FRONTEND_SILENCE_LIVEKIT_DEBUG: False
FRONTEND_SUPPORT: "{'id': '58ea6697-8eba-4492-bc59-ad6562585041', 'help_article_transcript': 'https://lasuite.crisp.help/fr/article/visio-transcript-1sjq43x', 'help_article_recording': 'https://lasuite.crisp.help/fr/article/visio-enregistrement-wgc8o0', 'help_article_more_tools': 'https://lasuite.crisp.help/fr/article/visio-tools-bvxj23'}"
FRONTEND_TRANSCRIPT: "{'form_beta_users': 'https://grist.numerique.gouv.fr/o/docs/forms/3fFfvJoTBEQ6ZiMi8zsQwX/17'}"
FRONTEND_FEEDBACK: "{'url': 'https://grist.numerique.gouv.fr/o/docs/cbMv4G7pLY3Z/USER-RESEARCH-or-LA-SUITE/f/26'}"
FRONTEND_CUSTOM_CSS_URL: './assets/dinum-styles.css'
FRONTEND_USE_FRENCH_GOV_FOOTER: True

View File

@@ -54,7 +54,6 @@ backend:
ALLOW_UNREGISTERED_ROOMS: False
FRONTEND_SILENCE_LIVEKIT_DEBUG: False
FRONTEND_SUPPORT: "{'id': '58ea6697-8eba-4492-bc59-ad6562585041', 'help_article_transcript': 'https://lasuite.crisp.help/fr/article/visio-transcript-1sjq43x', 'help_article_recording': 'https://lasuite.crisp.help/fr/article/visio-enregistrement-wgc8o0', 'help_article_more_tools': 'https://lasuite.crisp.help/fr/article/visio-tools-bvxj23'}"
FRONTEND_TRANSCRIPT: "{'form_beta_users': 'https://grist.numerique.gouv.fr/o/docs/forms/3fFfvJoTBEQ6ZiMi8zsQwX/17'}"
FRONTEND_FEEDBACK: "{'url': 'https://grist.numerique.gouv.fr/o/docs/cbMv4G7pLY3Z/USER-RESEARCH-or-LA-SUITE/f/26'}"
FRONTEND_MANIFEST_LINK: "https://docs.numerique.gouv.fr/docs/1ef86abf-f7e0-46ce-b6c7-8be8b8af4c3d/"
FRONTEND_IDLE_DISCONNECT_WARNING_DELAY: 9000