This commit is contained in:
Nathan Panchout
2025-02-27 08:50:50 +01:00
parent a571f9bc6e
commit 8849470d05
14 changed files with 118 additions and 38 deletions
+1
View File
@@ -1,3 +1,4 @@
const config = {
themes: {
default: {
@@ -229,6 +229,8 @@ export const TreeView = <T,>({
initialOpenState={initialOpenState}
selection={selectedNodeId}
disableEdit={true}
selectionFollowsFocus={true}
disableMultiSelection={true}
rowHeight={32}
overscanCount={20}
padding={25}
@@ -43,6 +43,7 @@ export const createTreeStore = <T>(
}
refreshCallback?.(nodeId)
.then((data) => {
console.log('data', data);
state.updateNode(nodeId, { ...node, ...data });
})
.catch((error) => {
@@ -1,3 +1,4 @@
/* eslint-disable jsx-a11y/no-static-element-interactions */
import { Command } from 'cmdk';
import { ReactNode, useRef } from 'react';
@@ -48,7 +49,12 @@ export const QuickSearch = ({
return (
<>
<QuickSearchStyle />
<div className="quick-search-container">
<div
className="quick-search-container"
onKeyDown={(e) => {
e.stopPropagation();
}}
>
<Command label={label} shouldFilter={false} ref={ref}>
{showInput && (
<QuickSearchInput
@@ -57,6 +57,9 @@ export const QuickSearchInput = ({
/* eslint-disable-next-line jsx-a11y/no-autofocus */
autoFocus={true}
aria-label={t('Quick search input')}
onClick={(e) => {
e.stopPropagation();
}}
value={inputValue}
role="combobox"
placeholder={placeholder ?? t('Search')}
@@ -56,6 +56,8 @@ export const DocToolBox = ({ doc }: DocToolBoxProps) => {
const { toast } = useToastProvider();
const copyDocLink = useCopyDocLink(doc.id);
const options: DropdownMenuOption[] = [
...(isSmallMobile
? [
@@ -1,9 +1,11 @@
import { Button, Modal, ModalSize } from '@openfun/cunningham-react';
import { Button, Input, Modal, ModalSize } from '@openfun/cunningham-react';
import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Box, Text } from '@/components';
import { useTreeStore } from '@/components/common/tree/treeStore';
import { useUpdateDoc } from '../api';
import { Doc } from '../types';
interface ModalRenameDocProps {
@@ -13,7 +15,25 @@ interface ModalRenameDocProps {
export const ModalRenameDoc = ({ onClose, doc }: ModalRenameDocProps) => {
const { t } = useTranslation();
const { updateNode } = useTreeStore();
const { mutate: updateDoc } = useUpdateDoc();
const [title, setTitle] = useState(doc.title);
const onRename = () => {
updateDoc(
{
id: doc.id,
title,
},
{
onSuccess: (doc) => {
updateNode(doc.id, doc);
onClose();
},
},
);
};
return (
<Modal
closeOnClickOutside
@@ -35,27 +55,28 @@ export const ModalRenameDoc = ({ onClose, doc }: ModalRenameDocProps) => {
>
{t('Cancel')}
</Button>
<Button
aria-label={t('Confirm rename')}
fullWidth
onClick={() => console.log('rename', title)}
>
<Button aria-label={t('Confirm rename')} fullWidth onClick={onRename}>
{t('Rename')}
</Button>
</>
}
>
<Box $padding={{ top: 'base' }}>
<input
<Input
onClick={(e) => {
e.stopPropagation();
e.preventDefault();
}}
defaultValue={title}
// label={t('Nom du document')}
onKeyDown={(e) => {
e.stopPropagation();
if (e.key === 'Enter') {
onRename();
}
}}
value={title}
label={t('Document name')}
onChange={(e) => {
e.stopPropagation();
e.preventDefault();
setTitle(e.target.value);
}}
/>
@@ -43,6 +43,7 @@ export interface Doc {
link_reach: LinkReach;
link_role: LinkRole;
nb_accesses: number;
depth: number;
created_at: string;
updated_at: string;
numchild: number;
@@ -9,6 +9,7 @@ import { css } from 'styled-components';
import { APIError } from '@/api';
import { Box } from '@/components';
import { useTreeStore } from '@/components/common/tree/treeStore';
import { useCunninghamTheme } from '@/cunningham';
import { User } from '@/features/auth';
import { Doc, Role } from '@/features/docs';
@@ -39,6 +40,7 @@ export const DocShareAddMemberList = ({
afterInvite,
}: Props) => {
const { t } = useTranslation();
const { refreshNode } = useTreeStore();
const { toast } = useToastProvider();
const [isLoading, setIsLoading] = useState(false);
const { spacingsTokens, colorsTokens } = useCunninghamTheme();
@@ -94,14 +96,24 @@ export const DocShareAddMemberList = ({
};
return isInvitationMode
? createInvitation({
...payload,
email: user.email,
})
: createDocAccess({
...payload,
memberId: user.id,
});
? createInvitation(
{
...payload,
email: user.email,
},
{
onSuccess: () => refreshNode(doc.id),
},
)
: createDocAccess(
{
...payload,
memberId: user.id,
},
{
onSuccess: () => refreshNode(doc.id),
},
);
});
const settledPromises = await Promise.allSettled(promises);
@@ -7,6 +7,7 @@ import {
DropdownMenuOption,
IconOptions,
} from '@/components';
import { useTreeStore } from '@/components/common/tree/treeStore';
import { useCunninghamTheme } from '@/cunningham';
import { Access, Doc, Role } from '@/features/docs/doc-management/';
import { useResponsiveStore } from '@/stores';
@@ -23,6 +24,7 @@ type Props = {
};
export const DocShareMemberItem = ({ doc, access }: Props) => {
const { t } = useTranslation();
const { refreshNode } = useTreeStore();
const { isLastOwner, isOtherOwner } = useWhoAmI(access);
const { toast } = useToastProvider();
const { isDesktop } = useResponsiveStore();
@@ -48,15 +50,21 @@ export const DocShareMemberItem = ({ doc, access }: Props) => {
});
const onUpdate = (newRole: Role) => {
updateDocAccess({
docId: doc.id,
role: newRole,
accessId: access.id,
});
updateDocAccess(
{
docId: doc.id,
role: newRole,
accessId: access.id,
},
{ onSuccess: () => refreshNode(doc.id) },
);
};
const onRemove = () => {
removeDocAccess({ accessId: access.id, docId: doc.id });
removeDocAccess(
{ accessId: access.id, docId: doc.id },
{ onSuccess: () => refreshNode(doc.id) },
);
};
const moreActions: DropdownMenuOption[] = [
@@ -153,7 +153,12 @@ export const DocTree = ({ docId }: Props) => {
</Box>
</Box>
</SeparatedSection>
<Box $padding={{ all: 'sm' }} $margin={{ top: '-35px' }} $width="100%">
<Box
$padding={{ all: 'sm' }}
$margin={{ top: '-35px' }}
$width="100%"
tabIndex={-1}
>
{initialOpenState && treeDataStore.length > 0 && (
<TreeView
initialOpenState={initialOpenState}
@@ -1,7 +1,7 @@
import { ReactNode } from 'react';
import { css } from 'styled-components';
import { Box, Text } from '@/components';
import { Box, Icon, Text } from '@/components';
import { useCunninghamTheme } from '@/cunningham';
import { Doc } from '@/features/docs/doc-management';
@@ -13,7 +13,7 @@ const ItemTextCss = css`
white-space: initial;
display: -webkit-box;
line-clamp: 1;
width: 100%;
/* width: 100%; */
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
`;
@@ -39,11 +39,12 @@ export const LightDocItem = ({
$align="center"
$css={css`
.light-doc-item-actions {
display: ${showActions ? 'flex' : 'none'};
opacity: 0;
display: 'flex';
}
&:hover {
.light-doc-item-actions {
display: flex;
opacity: 1;
}
}
`}
@@ -52,9 +53,24 @@ export const LightDocItem = ({
<Logo />
</Box>
<Text $css={ItemTextCss} $size="sm">
{doc.title}
</Text>
<Box
$direction="row"
$align="center"
$css={css`
display: flex;
flex-direction: row;
width: 100%;
gap: 0.5rem;
align-items: center;
`}
>
<Text $css={ItemTextCss} $size="sm">
{doc.title}
</Text>
{doc.nb_accesses - doc.depth > 1 && (
<Icon isFilled iconName="group" $size="16px" $variation="400" />
)}
</Box>
{rightContent && (
<Box
$direction="row"
@@ -48,7 +48,6 @@ export const LeftPanel = () => {
width: 100%;
min-width: 300px;
overflow: hidden;
border-right: 1px solid ${colors['greyscale-200']};
`}
>
<Box
@@ -20,9 +20,7 @@ const calculateDefaultSize = (targetWidth: number, isDesktop: boolean) => {
return 0;
}
const windowWidth = window.innerWidth;
console.log('windowWidth', windowWidth);
return (targetWidth / windowWidth) * 100;
// On limite le pourcentage entre 20 et 40 pour éviter des panneaux trop petits ou trop grands
};
export function MainLayout({
@@ -83,7 +81,12 @@ export function MainLayout({
>
<LeftPanel />
</Panel>
<PanelResizeHandle />
<PanelResizeHandle
style={{
width: '1px',
backgroundColor: colors['greyscale-200'],
}}
/>
<Panel>
<Box
as="main"