✨(frontend) enhance document editor and header components
- Improved styling for headings in BlockNoteEditor for better visual hierarchy. - Adjusted padding in DocEditor and DocHeader based on device type for responsive design. - Updated DocTitle and ModalExport components to enhance typography and spacing. - Refactored DocToolBox to improve share button functionality and access display. - Enhanced versioning modal with better layout and accessibility features. - Cleaned up unused imports and optimized component structures for maintainability.
This commit is contained in:
committed by
Anthony LC
parent
6ad1e27acf
commit
fc27043e9e
@@ -24,6 +24,49 @@ const cssEditor = (readonly: boolean) => `
|
||||
&, & > .bn-container, & .ProseMirror {
|
||||
height:100%;
|
||||
|
||||
.bn-side-menu[data-block-type=heading][data-level="1"] {
|
||||
height: 50px;
|
||||
}
|
||||
.bn-side-menu[data-block-type=heading][data-level="2"] {
|
||||
height: 43px;
|
||||
}
|
||||
.bn-side-menu[data-block-type=heading][data-level="3"] {
|
||||
height: 35px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.875rem;
|
||||
}
|
||||
h2 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
h3 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
a {
|
||||
color: var(--c--theme--colors--greyscale-500);
|
||||
cursor: pointer;
|
||||
}
|
||||
.bn-block-group
|
||||
.bn-block-group
|
||||
.bn-block-outer:not([data-prev-depth-changed]):before {
|
||||
border-left: none;
|
||||
}
|
||||
}
|
||||
|
||||
.bn-editor {
|
||||
|
||||
color: var(--c--theme--colors--greyscale-700);
|
||||
}
|
||||
.bn-block-outer:not(:first-child) {
|
||||
&:has(h1) {
|
||||
padding-top: 32px;
|
||||
}
|
||||
&:has(h2) {
|
||||
padding-top: 24px;
|
||||
}
|
||||
&:has(h3) {
|
||||
padding-top: 16px;
|
||||
}
|
||||
};
|
||||
|
||||
& .bn-inline-content code {
|
||||
|
||||
@@ -50,7 +50,7 @@ export const DocEditor = ({ doc, versionId }: DocEditorProps) => {
|
||||
</Box>
|
||||
)}
|
||||
<Box $maxWidth="868px" $width="100%" $height="100%">
|
||||
<Box $padding={{ horizontal: '54px' }}>
|
||||
<Box $padding={{ horizontal: isDesktop ? '54px' : 'base' }}>
|
||||
{isVersion ? (
|
||||
<DocVersionHeader title={doc.title} />
|
||||
) : (
|
||||
|
||||
@@ -35,7 +35,7 @@ export const DocHeader = ({ doc }: DocHeaderProps) => {
|
||||
<>
|
||||
<Box
|
||||
$width="100%"
|
||||
$padding={{ top: 'base' }}
|
||||
$padding={{ top: isDesktop ? '4xl' : 'md' }}
|
||||
$gap={spacings['base']}
|
||||
aria-label={t('It is the card information about the document.')}
|
||||
>
|
||||
@@ -72,10 +72,10 @@ export const DocHeader = ({ doc }: DocHeaderProps) => {
|
||||
<Box $direction="row">
|
||||
{isDesktop && (
|
||||
<>
|
||||
<Text $variation="400" $size="s" $weight="bold">
|
||||
<Text $variation="600" $size="s" $weight="bold">
|
||||
{transRole(currentDocRole(doc.abilities))} ·
|
||||
</Text>
|
||||
<Text $variation="400" $size="s">
|
||||
<Text $variation="600" $size="s">
|
||||
{t('Last update: {{update}}', {
|
||||
update: DateTime.fromISO(doc.updated_at).toRelative(),
|
||||
})}
|
||||
@@ -92,7 +92,7 @@ export const DocHeader = ({ doc }: DocHeaderProps) => {
|
||||
<DocToolBox doc={doc} />
|
||||
</Box>
|
||||
</Box>
|
||||
<HorizontalSeparator />
|
||||
<HorizontalSeparator $withPadding={true} />
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -43,6 +43,7 @@ export const DocTitleText = ({ title }: DocTitleTextProps) => {
|
||||
as="h2"
|
||||
$margin={{ all: 'none', left: 'none' }}
|
||||
$size={isMobile ? 'h4' : 'h2'}
|
||||
$variation="1000"
|
||||
>
|
||||
{title}
|
||||
</Text>
|
||||
@@ -113,7 +114,7 @@ const DocTitleInput = ({ doc }: DocTitleProps) => {
|
||||
onBlurCapture={(event) =>
|
||||
handleTitleSubmit(event.target.textContent || '')
|
||||
}
|
||||
$color={colorsTokens()['greyscale-text']}
|
||||
$color={colorsTokens()['greyscale-1000']}
|
||||
$margin={{ left: '-2px', right: '10px' }}
|
||||
$css={css`
|
||||
&[contenteditable='true']:empty:not(:focus):before {
|
||||
|
||||
@@ -4,7 +4,8 @@ import {
|
||||
useModal,
|
||||
useToastProvider,
|
||||
} from '@openfun/cunningham-react';
|
||||
import { useState } from 'react';
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { css } from 'styled-components';
|
||||
|
||||
@@ -17,12 +18,12 @@ import {
|
||||
} from '@/components';
|
||||
import { useAuthStore } from '@/core';
|
||||
import { useCunninghamTheme } from '@/cunningham';
|
||||
import {
|
||||
useEditorStore,
|
||||
usePanelEditorStore,
|
||||
} from '@/features/docs/doc-editor/';
|
||||
import { useEditorStore } from '@/features/docs/doc-editor/';
|
||||
import { Doc, ModalRemoveDoc } from '@/features/docs/doc-management';
|
||||
import { ModalSelectVersion } from '@/features/docs/doc-versioning';
|
||||
import {
|
||||
KEY_LIST_DOC_VERSIONS,
|
||||
ModalSelectVersion,
|
||||
} from '@/features/docs/doc-versioning';
|
||||
import { useResponsiveStore } from '@/stores';
|
||||
|
||||
import { DocShareModal } from '../../doc-share/component/DocShareModal';
|
||||
@@ -35,6 +36,8 @@ interface DocToolBoxProps {
|
||||
|
||||
export const DocToolBox = ({ doc }: DocToolBoxProps) => {
|
||||
const { t } = useTranslation();
|
||||
const hasAccesses = doc.nb_accesses > 1;
|
||||
const queryClient = useQueryClient();
|
||||
const { spacingsTokens, colorsTokens } = useCunninghamTheme();
|
||||
|
||||
const spacings = spacingsTokens();
|
||||
@@ -44,7 +47,6 @@ export const DocToolBox = ({ doc }: DocToolBoxProps) => {
|
||||
const [isModalPDFOpen, setIsModalPDFOpen] = useState(false);
|
||||
const selectHistoryModal = useModal();
|
||||
const modalShare = useModal();
|
||||
const { setIsPanelOpen, setIsPanelTableContentOpen } = usePanelEditorStore();
|
||||
|
||||
const { isSmallMobile, isDesktop } = useResponsiveStore();
|
||||
const { authenticated } = useAuthStore();
|
||||
@@ -80,14 +82,7 @@ export const DocToolBox = ({ doc }: DocToolBoxProps) => {
|
||||
},
|
||||
show: isDesktop,
|
||||
},
|
||||
{
|
||||
label: t('Table of contents'),
|
||||
icon: 'summarize',
|
||||
callback: () => {
|
||||
setIsPanelOpen(true);
|
||||
setIsPanelTableContentOpen(true);
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
label: t('Copy as {{format}}', { format: 'Markdown' }),
|
||||
icon: 'content_copy',
|
||||
@@ -135,6 +130,16 @@ export const DocToolBox = ({ doc }: DocToolBoxProps) => {
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (selectHistoryModal.isOpen) {
|
||||
return;
|
||||
}
|
||||
|
||||
void queryClient.resetQueries({
|
||||
queryKey: [KEY_LIST_DOC_VERSIONS],
|
||||
});
|
||||
}, [selectHistoryModal.isOpen, queryClient]);
|
||||
|
||||
return (
|
||||
<Box
|
||||
$margin={{ left: 'auto' }}
|
||||
@@ -143,21 +148,55 @@ export const DocToolBox = ({ doc }: DocToolBoxProps) => {
|
||||
$gap="0.5rem 1.5rem"
|
||||
$wrap={isSmallMobile ? 'wrap' : 'nowrap'}
|
||||
>
|
||||
<Box $direction="row" $margin={{ left: 'auto' }} $gap={spacings['2xs']}>
|
||||
<Box
|
||||
$direction="row"
|
||||
$align="center"
|
||||
$margin={{ left: 'auto' }}
|
||||
$gap={spacings['2xs']}
|
||||
>
|
||||
{authenticated && !isSmallMobile && (
|
||||
<Button
|
||||
color="primary-text"
|
||||
onClick={() => {
|
||||
modalShare.open();
|
||||
}}
|
||||
size={isSmallMobile ? 'small' : 'medium'}
|
||||
>
|
||||
{t('Share')}
|
||||
</Button>
|
||||
<>
|
||||
{!hasAccesses && (
|
||||
<Button
|
||||
color="tertiary-text"
|
||||
onClick={() => {
|
||||
modalShare.open();
|
||||
}}
|
||||
size={isSmallMobile ? 'small' : 'medium'}
|
||||
>
|
||||
{t('Share')}
|
||||
</Button>
|
||||
)}
|
||||
{hasAccesses && (
|
||||
<Box
|
||||
$css={css`
|
||||
.c__button--medium {
|
||||
height: 32px;
|
||||
padding: 10px var(--c--theme--spacings--xs);
|
||||
gap: 7px;
|
||||
}
|
||||
`}
|
||||
>
|
||||
<Button
|
||||
color="tertiary"
|
||||
aria-label="Share button"
|
||||
icon={
|
||||
<Icon iconName="group" $theme="primary" $variation="800" />
|
||||
}
|
||||
onClick={() => {
|
||||
modalShare.open();
|
||||
}}
|
||||
size={isSmallMobile ? 'small' : 'medium'}
|
||||
>
|
||||
{doc.nb_accesses}
|
||||
</Button>
|
||||
</Box>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{!isSmallMobile && (
|
||||
<Button
|
||||
color="primary-text"
|
||||
color="tertiary-text"
|
||||
icon={
|
||||
<Icon iconName="download" $theme="primary" $variation="800" />
|
||||
}
|
||||
@@ -171,15 +210,18 @@ export const DocToolBox = ({ doc }: DocToolBoxProps) => {
|
||||
<IconOptions
|
||||
isHorizontal
|
||||
$theme="primary"
|
||||
$radius={spacings['3xs']}
|
||||
$css={
|
||||
isSmallMobile
|
||||
$padding={{ all: 'xs' }}
|
||||
$css={css`
|
||||
&:hover {
|
||||
background-color: ${colors['greyscale-100']};
|
||||
}
|
||||
${isSmallMobile
|
||||
? css`
|
||||
padding: 10px;
|
||||
border: 1px solid ${colors['greyscale-300']};
|
||||
`
|
||||
: ''
|
||||
}
|
||||
: ''}
|
||||
`}
|
||||
aria-label={t('Open the document options')}
|
||||
/>
|
||||
</DropdownMenu>
|
||||
|
||||
@@ -130,7 +130,6 @@ export const ModalPDF = ({ onClose, doc }: ModalPDFProps) => {
|
||||
data-testid="modal-export"
|
||||
isOpen
|
||||
closeOnClickOutside
|
||||
hideCloseButton
|
||||
onClose={() => onClose()}
|
||||
rightActions={
|
||||
<>
|
||||
@@ -155,7 +154,7 @@ export const ModalPDF = ({ onClose, doc }: ModalPDFProps) => {
|
||||
}
|
||||
size={ModalSize.MEDIUM}
|
||||
title={
|
||||
<Text $size="h6" $align="flex-start">
|
||||
<Text $size="h6" $variation="1000" $align="flex-start">
|
||||
{t('Download')}
|
||||
</Text>
|
||||
}
|
||||
@@ -163,9 +162,9 @@ export const ModalPDF = ({ onClose, doc }: ModalPDFProps) => {
|
||||
<Box
|
||||
$margin={{ bottom: 'xl' }}
|
||||
aria-label={t('Content modal to export the document')}
|
||||
$gap="1.5rem"
|
||||
$gap="1rem"
|
||||
>
|
||||
<Text $variation="600">
|
||||
<Text $variation="600" $size="sm">
|
||||
{t(
|
||||
'Upload your docs to a Microsoft Word, Open Office or PDF document.',
|
||||
)}
|
||||
|
||||
@@ -38,7 +38,7 @@ export function useUpdateDoc({
|
||||
mutationFn: updateDoc,
|
||||
onSuccess: (data) => {
|
||||
listInvalideQueries?.forEach((queryKey) => {
|
||||
void queryClient.resetQueries({
|
||||
void queryClient.invalidateQueries({
|
||||
queryKey: [queryKey],
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import {
|
||||
Alert,
|
||||
Button,
|
||||
Modal,
|
||||
ModalSize,
|
||||
@@ -48,41 +47,36 @@ export const ModalRemoveDoc = ({ onClose, doc }: ModalRemoveDocProps) => {
|
||||
isOpen
|
||||
closeOnClickOutside
|
||||
hideCloseButton
|
||||
leftActions={
|
||||
<Button
|
||||
aria-label={t('Close the modal')}
|
||||
color="secondary"
|
||||
fullWidth
|
||||
onClick={() => onClose()}
|
||||
>
|
||||
{t('Cancel')}
|
||||
</Button>
|
||||
}
|
||||
onClose={() => onClose()}
|
||||
rightActions={
|
||||
<Button
|
||||
aria-label={t('Confirm deletion')}
|
||||
color="danger"
|
||||
fullWidth
|
||||
onClick={() =>
|
||||
removeDoc({
|
||||
docId: doc.id,
|
||||
})
|
||||
}
|
||||
>
|
||||
{t('Confirm deletion')}
|
||||
</Button>
|
||||
<>
|
||||
<Button
|
||||
aria-label={t('Close the modal')}
|
||||
color="secondary"
|
||||
fullWidth
|
||||
onClick={() => onClose()}
|
||||
>
|
||||
{t('Cancel')}
|
||||
</Button>
|
||||
<Button
|
||||
aria-label={t('Confirm deletion')}
|
||||
color="danger"
|
||||
fullWidth
|
||||
onClick={() =>
|
||||
removeDoc({
|
||||
docId: doc.id,
|
||||
})
|
||||
}
|
||||
>
|
||||
{t('Delete')}
|
||||
</Button>
|
||||
</>
|
||||
}
|
||||
size={ModalSize.MEDIUM}
|
||||
size={ModalSize.SMALL}
|
||||
title={
|
||||
<Box $align="center" $gap="1rem">
|
||||
<Text $isMaterialIcon $size="48px" $theme="primary" $variation="600">
|
||||
delete_forever
|
||||
</Text>
|
||||
<Text as="h2" $size="h3" $margin="none">
|
||||
{t('Deleting the document "{{title}}"', { title: doc.title })}
|
||||
</Text>
|
||||
</Box>
|
||||
<Text $size="h6" as="h6" $margin={{ all: '0' }} $align="flex-start">
|
||||
{t('Delete a doc')}
|
||||
</Text>
|
||||
}
|
||||
>
|
||||
<Box
|
||||
@@ -90,13 +84,11 @@ export const ModalRemoveDoc = ({ onClose, doc }: ModalRemoveDocProps) => {
|
||||
aria-label={t('Content modal to delete document')}
|
||||
>
|
||||
{!isError && (
|
||||
<Alert canClose={false} type={VariantType.WARNING}>
|
||||
<Text>
|
||||
{t('Are you sure you want to delete the document "{{title}}"?', {
|
||||
title: doc.title,
|
||||
})}
|
||||
</Text>
|
||||
</Alert>
|
||||
<Text $size="sm" $variation="600">
|
||||
{t('Are you sure you want to delete the document "{{title}}"?', {
|
||||
title: doc.title,
|
||||
})}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
{isError && <TextErrors causes={error.cause} />}
|
||||
|
||||
@@ -2,7 +2,8 @@ import { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { css } from 'styled-components';
|
||||
|
||||
import { Box, Icon, Text } from '@/components';
|
||||
import { Box, BoxButton, Icon, Text } from '@/components';
|
||||
import { useCunninghamTheme } from '@/cunningham';
|
||||
import { useEditorStore, useHeadingStore } from '@/features/docs/doc-editor';
|
||||
import { MAIN_LAYOUT_ID } from '@/layouts/conf';
|
||||
|
||||
@@ -11,6 +12,8 @@ import { Heading } from './Heading';
|
||||
export const TableContent = () => {
|
||||
const { headings } = useHeadingStore();
|
||||
const { editor } = useEditorStore();
|
||||
const { spacingsTokens } = useCunninghamTheme();
|
||||
const spacing = spacingsTokens();
|
||||
|
||||
const [headingIdHighlight, setHeadingIdHighlight] = useState<string>();
|
||||
|
||||
@@ -58,33 +61,33 @@ export const TableContent = () => {
|
||||
};
|
||||
}, [headings, setHeadingIdHighlight]);
|
||||
|
||||
const onOpen = () => {
|
||||
setIsHover(true);
|
||||
setTimeout(() => {
|
||||
const element = document.getElementById(`heading-${headingIdHighlight}`);
|
||||
|
||||
element?.scrollIntoView({
|
||||
behavior: 'instant',
|
||||
inline: 'center',
|
||||
block: 'center',
|
||||
});
|
||||
}, 0); // 300ms is the transition time of the box
|
||||
};
|
||||
|
||||
const onClose = () => {
|
||||
setIsHover(false);
|
||||
};
|
||||
|
||||
if (!editor) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Box
|
||||
onMouseEnter={() => {
|
||||
setIsHover(true);
|
||||
setTimeout(() => {
|
||||
const element = document.getElementById(
|
||||
`heading-${headingIdHighlight}`,
|
||||
);
|
||||
|
||||
element?.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
inline: 'center',
|
||||
block: 'center',
|
||||
});
|
||||
}, 250); // 300ms is the transition time of the box
|
||||
}}
|
||||
onMouseLeave={() => {
|
||||
setIsHover(false);
|
||||
}}
|
||||
id="summaryContainer"
|
||||
$effect="show"
|
||||
$width="40px"
|
||||
$height="40px"
|
||||
$width={!isHover ? '40px' : '200px'}
|
||||
$height={!isHover ? '40px' : 'auto'}
|
||||
$maxHeight="calc(50vh - 60px)"
|
||||
$zIndex={1000}
|
||||
$align="center"
|
||||
$padding="xs"
|
||||
@@ -94,51 +97,69 @@ export const TableContent = () => {
|
||||
overflow: hidden;
|
||||
border-radius: var(--c--theme--spacings--3xs);
|
||||
background: var(--c--theme--colors--greyscale-000);
|
||||
|
||||
&:hover {
|
||||
overflow-y: auto;
|
||||
${isHover &&
|
||||
css`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
gap: var(--c--theme--spacings--2xs);
|
||||
width: 200px;
|
||||
height: auto;
|
||||
max-height: calc(100vh - 60px - 15vh);
|
||||
}
|
||||
`}
|
||||
`}
|
||||
>
|
||||
{!isHover && (
|
||||
<Box $justify="center" $align="center">
|
||||
<BoxButton onClick={onOpen} $justify="center" $align="center">
|
||||
<Icon iconName="list" $theme="primary" $variation="800" />
|
||||
</Box>
|
||||
</BoxButton>
|
||||
)}
|
||||
{isHover && (
|
||||
<Box $width="100%">
|
||||
<Box
|
||||
$width="100%"
|
||||
$overflow="hidden"
|
||||
$css={css`
|
||||
user-select: none;
|
||||
`}
|
||||
>
|
||||
<Box
|
||||
$margin={{ bottom: '20px' }}
|
||||
$margin={{ bottom: '10px' }}
|
||||
$direction="row"
|
||||
$justify="space-between"
|
||||
$align="center"
|
||||
>
|
||||
<Text $weight="bold" $variation="800" $theme="primary">
|
||||
<Text $weight="500" $size="sm" $variation="800" $theme="primary">
|
||||
{t('Summary')}
|
||||
</Text>
|
||||
<Icon iconName="list" $theme="primary" $variation="800" />
|
||||
<BoxButton
|
||||
onClick={onClose}
|
||||
$justify="center"
|
||||
$align="center"
|
||||
$css={css`
|
||||
transform: rotate(180deg);
|
||||
`}
|
||||
>
|
||||
<Icon iconName="menu_open" $theme="primary" $variation="800" />
|
||||
</BoxButton>
|
||||
</Box>
|
||||
<Box
|
||||
$gap={spacing['3xs']}
|
||||
$css={css`
|
||||
overflow-y: auto;
|
||||
`}
|
||||
>
|
||||
{headings?.map(
|
||||
(heading) =>
|
||||
heading.contentText && (
|
||||
<Heading
|
||||
editor={editor}
|
||||
headingId={heading.id}
|
||||
level={heading.props.level}
|
||||
text={heading.contentText}
|
||||
key={heading.id}
|
||||
isHighlight={headingIdHighlight === heading.id}
|
||||
/>
|
||||
),
|
||||
)}
|
||||
</Box>
|
||||
{headings?.map(
|
||||
(heading) =>
|
||||
heading.contentText && (
|
||||
<Heading
|
||||
editor={editor}
|
||||
headingId={heading.id}
|
||||
level={heading.props.level}
|
||||
text={heading.contentText}
|
||||
key={heading.id}
|
||||
isHighlight={headingIdHighlight === heading.id}
|
||||
/>
|
||||
),
|
||||
)}
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
@@ -52,7 +52,8 @@ export const ModalSelectVersion = ({
|
||||
aria-label="version history modal"
|
||||
className="noPadding"
|
||||
$direction="row"
|
||||
$height="calc(100vh - 50px);"
|
||||
$height="100%"
|
||||
$maxHeight="calc(100vh - 2em - 12px)"
|
||||
$overflow="hidden"
|
||||
>
|
||||
<Box
|
||||
@@ -64,7 +65,11 @@ export const ModalSelectVersion = ({
|
||||
flex: 1;
|
||||
`}
|
||||
>
|
||||
<Box $width="100%" $padding="base" $align="center">
|
||||
<Box
|
||||
$width="100%"
|
||||
$padding={{ horizontal: 'base', vertical: 'xl' }}
|
||||
$align="center"
|
||||
>
|
||||
{selectedVersionId && (
|
||||
<DocEditor doc={doc} versionId={selectedVersionId} />
|
||||
)}
|
||||
@@ -81,7 +86,7 @@ export const ModalSelectVersion = ({
|
||||
$direction="column"
|
||||
$justify="space-between"
|
||||
$width="250px"
|
||||
$height="calc(100vh - 2em - 30px);"
|
||||
$height="calc(100vh - 2em - 12px)"
|
||||
$css={css`
|
||||
overflow-y: hidden;
|
||||
border-left: 1px solid var(--c--theme--colors--greyscale-200);
|
||||
@@ -105,7 +110,7 @@ export const ModalSelectVersion = ({
|
||||
`}
|
||||
$padding="sm"
|
||||
>
|
||||
<Text $size="h6" $weight="bold">
|
||||
<Text $size="h6" $variation="1000" $weight="bold">
|
||||
{t('History')}
|
||||
</Text>
|
||||
<Button
|
||||
@@ -123,7 +128,7 @@ export const ModalSelectVersion = ({
|
||||
/>
|
||||
</Box>
|
||||
<Box
|
||||
$padding="base"
|
||||
$padding="xs"
|
||||
$css={css`
|
||||
border-top: 1px solid var(--c--theme--colors--greyscale-200);
|
||||
`}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Loader } from '@openfun/cunningham-react';
|
||||
import { DateTime } from 'luxon';
|
||||
import { useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { APIError } from '@/api';
|
||||
@@ -105,11 +104,9 @@ export const VersionList = ({
|
||||
docId: doc.id,
|
||||
});
|
||||
|
||||
const versions = useMemo(() => {
|
||||
return data?.pages.reduce((acc, page) => {
|
||||
return acc.concat(page.versions);
|
||||
}, [] as Versions[]);
|
||||
}, [data?.pages]);
|
||||
const versions = data?.pages.reduce((acc, page) => {
|
||||
return acc.concat(page.versions);
|
||||
}, [] as Versions[]);
|
||||
|
||||
return (
|
||||
<Box $css="overflow-y: auto; overflow-x: hidden;">
|
||||
|
||||
Reference in New Issue
Block a user