diff --git a/src/frontend/apps/impress/src/features/docs/doc-management/components/DocVisibility.tsx b/src/frontend/apps/impress/src/features/docs/doc-management/components/DocVisibility.tsx deleted file mode 100644 index fb0da949..00000000 --- a/src/frontend/apps/impress/src/features/docs/doc-management/components/DocVisibility.tsx +++ /dev/null @@ -1,144 +0,0 @@ -import { - Radio, - RadioGroup, - Select, - VariantType, - useToastProvider, -} from '@openfun/cunningham-react'; -import { useTranslation } from 'react-i18next'; - -import { Box, Card, IconBG } from '@/components'; -import { useCunninghamTheme } from '@/cunningham'; - -import { KEY_DOC, KEY_LIST_DOC, useUpdateDocLink } from '../api'; -import { Doc, LinkReach, LinkRole } from '../types'; - -interface DocVisibilityProps { - doc: Doc; -} - -export const DocVisibility = ({ doc }: DocVisibilityProps) => { - const { t } = useTranslation(); - const { toast } = useToastProvider(); - const { colorsTokens } = useCunninghamTheme(); - const api = useUpdateDocLink({ - onSuccess: () => { - toast( - t('The document visibility has been updated.'), - VariantType.SUCCESS, - { - duration: 4000, - }, - ); - }, - listInvalideQueries: [KEY_LIST_DOC, KEY_DOC], - }); - - const transLinkReach = { - [LinkReach.RESTRICTED]: { - label: t('Restricted'), - description: t('Only for people with access'), - }, - [LinkReach.AUTHENTICATED]: { - label: t('Authenticated'), - description: t('Only for authenticated users'), - }, - [LinkReach.PUBLIC]: { - label: t('Public'), - description: t('Anyone on the internet with the link can view'), - }, - }; - - const linkRoleList = [ - { - label: t('Read only'), - value: LinkRole.READER, - }, - { - label: t('Can read and edit'), - value: LinkRole.EDITOR, - }, - ]; - - const showLinkRoleOptions = doc.link_reach !== LinkReach.RESTRICTED; - - return ( - - - - - ({ - label: transRole(role), - value: role, - disabled: currentRole !== Role.OWNER && role === Role.OWNER, - }))} - onChange={(evt) => setRole(evt.target.value as Role)} - disabled={disabled} - value={defaultRole} - /> - ); -}; diff --git a/src/frontend/apps/impress/src/features/docs/members/members-add/components/SearchUsers.tsx b/src/frontend/apps/impress/src/features/docs/members/members-add/components/SearchUsers.tsx deleted file mode 100644 index 5d6a172a..00000000 --- a/src/frontend/apps/impress/src/features/docs/members/members-add/components/SearchUsers.tsx +++ /dev/null @@ -1,161 +0,0 @@ -import { useCallback, useMemo, useRef, useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import { InputActionMeta, Options } from 'react-select'; -import AsyncSelect from 'react-select/async'; - -import { useCunninghamTheme } from '@/cunningham'; -import { Doc } from '@/features/docs/doc-management'; -import { isValidEmail } from '@/utils'; - -import { KEY_LIST_USER, useUsers } from '../api/useUsers'; -import { OptionSelect, OptionType } from '../types'; - -export type OptionsSelect = Options; - -interface SearchUsersProps { - doc: Doc; - selectedUsers: OptionsSelect; - setSelectedUsers: (value: OptionsSelect) => void; - disabled?: boolean; -} - -export const SearchUsers = ({ - doc, - selectedUsers, - setSelectedUsers, - disabled, -}: SearchUsersProps) => { - const { colorsTokens } = useCunninghamTheme(); - const { t } = useTranslation(); - const [input, setInput] = useState(''); - const [userQuery, setUserQuery] = useState(''); - const resolveOptionsRef = useRef<((value: OptionsSelect) => void) | null>( - null, - ); - const { data } = useUsers( - { query: userQuery, docId: doc.id }, - { - enabled: !!userQuery, - queryKey: [KEY_LIST_USER, { query: userQuery }], - }, - ); - - const options = data?.results; - - const optionsSelect = useMemo(() => { - if (!resolveOptionsRef.current || !options) { - return; - } - - const optionsFiltered = options.filter( - (user) => - !selectedUsers?.find( - (selectedUser) => selectedUser.value.email === user.email, - ), - ); - - let users: OptionsSelect = optionsFiltered.map((user) => ({ - value: user, - label: user.email, - type: OptionType.NEW_MEMBER, - })); - - if (userQuery && isValidEmail(userQuery)) { - const isFoundUser = !!optionsFiltered.find( - (user) => user.email === userQuery, - ); - const isFoundEmail = !!selectedUsers.find( - (selectedUser) => selectedUser.value.email === userQuery, - ); - - if (!isFoundUser && !isFoundEmail) { - users = [ - ...users, - { - value: { email: userQuery }, - label: userQuery, - type: OptionType.INVITATION, - }, - ]; - } - } - - resolveOptionsRef.current(users); - resolveOptionsRef.current = null; - - return users; - }, [options, selectedUsers, userQuery]); - - const loadOptions = (): Promise => { - return new Promise((resolve) => { - resolveOptionsRef.current = resolve; - }); - }; - - const timeout = useRef(null); - const onInputChangeHandle = useCallback( - (newValue: string, actionMeta: InputActionMeta) => { - if ( - actionMeta.action === 'input-blur' || - actionMeta.action === 'menu-close' - ) { - return; - } - - setInput(newValue); - if (timeout.current) { - clearTimeout(timeout.current); - } - - timeout.current = setTimeout(() => { - setUserQuery(newValue); - }, 1000); - }, - [], - ); - - return ( - ({ - ...base, - fontSize: '14px', - color: disabled - ? colorsTokens()['greyscale-300'] - : colorsTokens()['primary-600'], - }), - control: (base) => ({ - ...base, - minHeight: '45px', - borderColor: disabled - ? colorsTokens()['greyscale-300'] - : colorsTokens()['primary-600'], - backgroundColor: 'white', - }), - input: (base) => ({ - ...base, - minHeight: '45px', - fontSize: '14px', - }), - }} - isDisabled={disabled} - aria-label={t('Find a member to add to the document')} - isMulti - loadOptions={loadOptions} - defaultOptions={optionsSelect} - onInputChange={onInputChangeHandle} - inputValue={input} - placeholder={t('Search by email')} - noOptionsMessage={() => - input - ? t("We didn't find a mail matching, try to be more accurate") - : t('Invite new members to {{title}}', { title: doc.title }) - } - onChange={(value) => { - setInput(''); - setUserQuery(''); - setSelectedUsers(value); - }} - /> - ); -}; diff --git a/src/frontend/apps/impress/src/features/docs/members/members-add/components/index.ts b/src/frontend/apps/impress/src/features/docs/members/members-add/components/index.ts deleted file mode 100644 index b0e7a660..00000000 --- a/src/frontend/apps/impress/src/features/docs/members/members-add/components/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './AddMembers'; -export * from './ChooseRole'; diff --git a/src/frontend/apps/impress/src/features/docs/members/members-add/index.ts b/src/frontend/apps/impress/src/features/docs/members/members-add/index.ts deleted file mode 100644 index 0ef46430..00000000 --- a/src/frontend/apps/impress/src/features/docs/members/members-add/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './api'; -export * from './components'; diff --git a/src/frontend/apps/impress/src/features/docs/members/members-list/api/index.ts b/src/frontend/apps/impress/src/features/docs/members/members-list/api/index.ts deleted file mode 100644 index 385fe981..00000000 --- a/src/frontend/apps/impress/src/features/docs/members/members-list/api/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './useDeleteDocAccess'; -export * from './useDocAccesses'; -export * from './useUpdateDocAccess'; diff --git a/src/frontend/apps/impress/src/features/docs/members/members-list/components/MemberItem.tsx b/src/frontend/apps/impress/src/features/docs/members/members-list/components/MemberItem.tsx deleted file mode 100644 index a5c2eca5..00000000 --- a/src/frontend/apps/impress/src/features/docs/members/members-list/components/MemberItem.tsx +++ /dev/null @@ -1,166 +0,0 @@ -import { - Alert, - Button, - Loader, - VariantType, - useToastProvider, -} from '@openfun/cunningham-react'; -import { useRouter } from 'next/router'; -import React, { useState } from 'react'; -import { useTranslation } from 'react-i18next'; - -import { Box, IconBG, Text, TextErrors } from '@/components'; -import { Access, Doc, Role } from '@/features/docs/doc-management'; -import { ChooseRole } from '@/features/docs/members/members-add/'; -import { useResponsiveStore } from '@/stores'; - -import { useDeleteDocAccess, useUpdateDocAccess } from '../api'; -import { useWhoAmI } from '../hooks/useWhoAmI'; - -interface MemberItemProps { - role: Role; - currentRole: Role; - access: Access; - doc: Doc; -} - -export const MemberItem = ({ - doc, - role, - access, - currentRole, -}: MemberItemProps) => { - const { isMyself, isLastOwner, isOtherOwner } = useWhoAmI(access); - const { t } = useTranslation(); - const { isSmallMobile, screenWidth } = useResponsiveStore(); - const [localRole, setLocalRole] = useState(role); - const { toast } = useToastProvider(); - const { push } = useRouter(); - const { mutate: updateDocAccess, error: errorUpdate } = useUpdateDocAccess({ - onSuccess: () => { - toast(t('The role has been updated'), VariantType.SUCCESS, { - duration: 4000, - }); - }, - }); - - const { mutate: removeDocAccess, error: errorDelete } = useDeleteDocAccess({ - onSuccess: () => { - toast( - t('The member has been removed from the document'), - VariantType.SUCCESS, - { - duration: 4000, - }, - ); - - if (isMyself) { - void push('/'); - } - }, - }); - - const isNotAllowed = - isOtherOwner || isLastOwner || !doc.abilities.accesses_manage; - - if (!access.user) { - return ( - - - - ); - } - - return ( - - - - - - {access.user.full_name && {access.user.full_name}} - {access.user.email} - - - - { - setLocalRole(role); - updateDocAccess({ - docId: doc.id, - accessId: access.id, - role, - }); - }} - /> - - {doc.abilities.accesses_manage && ( - -