From bf4fcfeefcf1fccedf197d7bd74e589ba372ca56 Mon Sep 17 00:00:00 2001 From: Xavier Abad Date: Tue, 20 Jan 2026 09:49:20 +0100 Subject: [PATCH 1/6] refactor(share): extract components --- .../components/ShareDialog/ShareDialog.tsx | 300 +++--------------- .../GeneralView/InvitedUsersList.tsx | 72 +++++ .../GeneralView/ProtectWithPassword.tsx | 58 ++++ .../GeneralView/UserRoleSelection.tsx | 151 +++++++++ .../ShareDialog/components/Header.tsx | 49 +++ 5 files changed, 376 insertions(+), 254 deletions(-) create mode 100644 src/app/drive/components/ShareDialog/components/GeneralView/InvitedUsersList.tsx create mode 100644 src/app/drive/components/ShareDialog/components/GeneralView/ProtectWithPassword.tsx create mode 100644 src/app/drive/components/ShareDialog/components/GeneralView/UserRoleSelection.tsx create mode 100644 src/app/drive/components/ShareDialog/components/Header.tsx diff --git a/src/app/drive/components/ShareDialog/ShareDialog.tsx b/src/app/drive/components/ShareDialog/ShareDialog.tsx index 92d99cb4df..408fcc3783 100644 --- a/src/app/drive/components/ShareDialog/ShareDialog.tsx +++ b/src/app/drive/components/ShareDialog/ShareDialog.tsx @@ -1,31 +1,16 @@ import { Popover } from '@headlessui/react'; import { SharingMeta } from '@internxt/sdk/dist/drive/share/types'; import { UserSettings } from '@internxt/sdk/dist/shared/types/userSettings'; -import { - ArrowLeft, - CaretDown, - Check, - CheckCircle, - Globe, - Link, - Question, - UserPlus, - Users, - X, -} from '@phosphor-icons/react'; +import { CaretDown, CheckCircle, UserPlus } from '@phosphor-icons/react'; import { useTranslationContext } from 'app/i18n/provider/TranslationProvider'; -import { SharePasswordDisableDialog } from 'app/share/components/SharePasswordDisableDialog/SharePasswordDisableDialog'; -import { SharePasswordInputDialog } from 'app/share/components/SharePasswordInputDialog/SharePasswordInputDialog'; import { MAX_SHARED_NAME_LENGTH } from '../../../../views/Shared/SharedView'; -import { Avatar, Button, Checkbox, Loader, Modal } from '@internxt/ui'; -import { DELAY_SHOW_MS } from 'components/TooltipElement'; +import { Avatar, Button, Modal } from '@internxt/ui'; import { RootState } from 'app/store'; import { useAppDispatch, useAppSelector } from 'app/store/hooks'; import { Role } from 'app/store/slices/sharedLinks/types'; import { uiActions } from 'app/store/slices/ui'; import { MouseEvent, useCallback, useEffect, useRef, useState } from 'react'; import { connect } from 'react-redux'; -import { Tooltip } from 'react-tooltip'; import errorService from 'services/error.service'; import localStorageService from 'services/local-storage.service'; import notificationsService, { ToastType } from 'app/notifications/services/notifications.service'; @@ -36,11 +21,8 @@ import { sharedThunks } from 'app/store/slices/sharedLinks'; import workspacesSelectors from 'app/store/slices/workspaces/workspaces.selectors'; import { DriveItemData } from 'app/drive/types'; import ShareInviteDialog from '../ShareInviteDialog/ShareInviteDialog'; -import StopSharingItemDialog from '../StopSharingItemDialog/StopSharingItemDialog'; import './ShareDialog.scss'; import envService from 'services/env.service'; -import { User } from './components/User'; -import { InvitedUsersSkeletonLoader } from './components/InvitedUsersSkeletonLoader'; import { AccessMode, InvitedUserProps, @@ -53,7 +35,14 @@ import { } from './types'; import navigationService from 'services/navigation.service'; import { Service } from '@internxt/sdk/dist/drive/payments/types/tiers'; +import { SharePasswordInputDialog } from 'app/share/components/SharePasswordInputDialog/SharePasswordInputDialog'; import { UpgradeDialog } from '../UpgradeDialog/UpgradeDialog'; +import { SharePasswordDisableDialog } from 'app/share/components/SharePasswordDisableDialog/SharePasswordDisableDialog'; +import StopSharingItemDialog from '../StopSharingItemDialog/StopSharingItemDialog'; +import { ProtectWithPassword } from './components/GeneralView/ProtectWithPassword'; +import { UserRoleSelection } from './components/GeneralView/UserRoleSelection'; +import { InvitedUsersList } from './components/GeneralView/InvitedUsersList'; +import { Header } from './components/Header'; const isRequestPending = (status: RequestStatus): boolean => status !== REQUEST_STATUS.DENIED && status !== REQUEST_STATUS.ACCEPTED; @@ -97,7 +86,6 @@ const getLocalUserData = () => { return ownerData; }; -// TODO: THIS IS TEMPORARY, REMOVE WHEN NEED TO SHOW OTHER ROLES const filterEditorAndReader = (users: Role[]): Role[] => { return users.filter((user) => user.name === 'EDITOR' || user.name === 'READER'); }; @@ -142,6 +130,7 @@ const ShareDialog = (props: ShareDialogProps): JSX.Element => { item: itemToShare?.item as AdvancedSharedItem, userEmail: props?.user?.email, }); + const isProtectWithPasswordOptionAvailable = accessMode === 'public' && !isLoading && isUserOwner; const closeSelectedUserPopover = () => setSelectedUserListIndex(null); const resetDialogData = () => { @@ -209,7 +198,7 @@ const ShareDialog = (props: ShareDialogProps): JSX.Element => { })); setInvitedUsers(invitedUsersListParsed); - } catch (error) { + } catch { // the server throws an error when there are no users with shared item, // that means that the local user is the owner as there is nobody else with this shared file. if (isUserOwner) { @@ -293,7 +282,7 @@ const ShareDialog = (props: ShareDialogProps): JSX.Element => { try { await copyTextToClipboard(`${envService.getVariable('hostname')}/shared/?folderuuid=${itemToShare?.item.uuid}`); notificationsService.show({ text: translate('shared-links.toast.copy-to-clipboard'), type: ToastType.Success }); - } catch (error) { + } catch { notificationsService.show({ text: translate('modals.shareModal.errors.copy-to-clipboard'), type: ToastType.Error, @@ -328,7 +317,7 @@ const ShareDialog = (props: ShareDialogProps): JSX.Element => { closeSelectedUserPopover(); }; - const onRemoveUser = async (user) => { + const onRemoveUser = async (user: InvitedUserProps) => { if (user) { const hasBeenRemoved = await dispatch( sharedThunks.removeUserFromSharedFolder({ @@ -498,42 +487,6 @@ const ShareDialog = (props: ShareDialogProps): JSX.Element => { } }; - const Header = (headerProps: ViewProps): JSX.Element => { - const headers = { - general: ( - <> - - {translate('modals.shareModal.title', { name: itemToShare?.item.name })} - -
- (isLoading ? null : onClose())} size={22} /> -
- - ), - invite: ( -
- setView('general')} size={24} /> - - {translate('modals.shareModal.invite.title')} - -
- ), - requests: ( -
- setView('general')} size={24} /> - - {translate('modals.shareModal.requests.title')} - -
- ), - }; - - return headers[headerProps.view]; - }; - const View = (viewProps: ViewProps): JSX.Element => { const view = { general: ( @@ -568,205 +521,45 @@ const ShareDialog = (props: ShareDialogProps): JSX.Element => { )} + {/* List of users invited to the shared item */} -
- {invitedUsers.length === 0 && isLoading ? ( - <> - {Array.from({ length: 4 }, (_, i) => ( - - ))} - - ) : ( - invitedUsers - .sort((a, b) => { - if (a.email === props.user.email && b.email !== props.user.email) return -1; - return 0; - }) - .map((user, index) => ( - - )) - )} -
+
- {accessMode === 'public' && !isLoading && isUserOwner && ( -
-
-
- -

- {translate('modals.shareModal.protectSharingModal.protect')} -

- {isPasswordSharingAvailable ? ( - <> - - -

- {translate('modals.shareModal.protectSharingModal.protectTooltipText')} -

-
- - ) : ( -
-

{translate('actions.locked')}

-
- )} -
-
- {isPasswordProtected && ( - - )} -
+ {isProtectWithPasswordOptionAvailable && ( + setOpenPasswordInput(true)} + onPasswordCheckboxChange={onPasswordCheckboxChange} + /> )} -
-
-

{translate('modals.shareModal.general.generalAccess')}

- - - {({ open }) => ( - <> - - - - - - {({ close }) => ( - <> - {/* Public */} - - {/* Restricted */} - {!isWorkspace && ( - - )} - {/* Stop sharing */} - {(currentUserFolderRole === 'owner' || isUserOwner || props?.isDriveItem) && ( - - )} - - )} - - - )} - -
- -
+ setOpenPasswordInput(false)} @@ -798,7 +591,6 @@ const ShareDialog = (props: ShareDialogProps): JSX.Element => { onConfirmHandler={onDisablePassword} /> - {/* Stop sharing confirmation dialog */} setShowStopSharingConfirmation(false)} @@ -926,7 +718,7 @@ const ShareDialog = (props: ShareDialogProps): JSX.Element => { return (
-
+
diff --git a/src/app/drive/components/ShareDialog/components/GeneralView/InvitedUsersList.tsx b/src/app/drive/components/ShareDialog/components/GeneralView/InvitedUsersList.tsx new file mode 100644 index 0000000000..e945f014dd --- /dev/null +++ b/src/app/drive/components/ShareDialog/components/GeneralView/InvitedUsersList.tsx @@ -0,0 +1,72 @@ +import { useTranslationContext } from 'app/i18n/provider/TranslationProvider'; +import { User } from '../User'; +import { InvitedUsersSkeletonLoader } from '../InvitedUsersSkeletonLoader'; +import { InvitedUserProps } from '../../types'; + +interface InvitedUsersListProps { + userList; + invitedUsers: InvitedUserProps[]; + areInvitedUsersLoading: boolean; + user; + openUserOptions: (e: any, user: InvitedUserProps, selectedIndex: number | null) => void; + userOptionsY: number; + selectedUserListIndex: number | null; + onRemoveUser: (user: InvitedUserProps) => void; + currentUserFolderRole?: string; + userOptionsEmail?: InvitedUserProps; + handleUserRoleChange: (email: string, role: string) => Promise; +} + +export const InvitedUsersList = ({ + currentUserFolderRole, + userList, + invitedUsers, + areInvitedUsersLoading, + user, + openUserOptions, + selectedUserListIndex, + userOptionsY, + onRemoveUser, + userOptionsEmail, + handleUserRoleChange, +}: InvitedUsersListProps) => { + const { translate } = useTranslationContext(); + const invitedUsersSorted = invitedUsers.toSorted((a, b) => { + if (a.email === user.email && b.email !== user.email) return -1; + return 0; + }); + const isListLoading = invitedUsers.length === 0 && areInvitedUsersLoading; + + return ( +
+ {isListLoading ? ( + <> + {Array.from({ length: 4 }, (_, i) => ( + + ))} + + ) : ( + invitedUsersSorted.map((invitedUser, index) => ( + + )) + )} +
+ ); +}; diff --git a/src/app/drive/components/ShareDialog/components/GeneralView/ProtectWithPassword.tsx b/src/app/drive/components/ShareDialog/components/GeneralView/ProtectWithPassword.tsx new file mode 100644 index 0000000000..d9464d596d --- /dev/null +++ b/src/app/drive/components/ShareDialog/components/GeneralView/ProtectWithPassword.tsx @@ -0,0 +1,58 @@ +import { Button, Checkbox } from '@internxt/ui'; +import { Question } from '@phosphor-icons/react'; +import { useTranslationContext } from 'app/i18n/provider/TranslationProvider'; +import { DELAY_SHOW_MS } from 'components'; +import { Tooltip } from 'react-tooltip'; + +interface ProtectWithPasswordProps { + isPasswordProtected: boolean; + onPasswordCheckboxChange: () => void; + isPasswordSharingAvailable: boolean; + onChangePassword: () => void; +} + +export const ProtectWithPassword = ({ + isPasswordProtected, + onPasswordCheckboxChange, + isPasswordSharingAvailable, + onChangePassword, +}: ProtectWithPasswordProps) => { + const { translate } = useTranslationContext(); + + return ( +
+
+
+ +

+ {translate('modals.shareModal.protectSharingModal.protect')} +

+ {isPasswordSharingAvailable ? ( + <> + + +

+ {translate('modals.shareModal.protectSharingModal.protectTooltipText')} +

+
+ + ) : ( +
+

{translate('actions.locked')}

+
+ )} +
+
+ {isPasswordProtected && ( + + )} +
+ ); +}; diff --git a/src/app/drive/components/ShareDialog/components/GeneralView/UserRoleSelection.tsx b/src/app/drive/components/ShareDialog/components/GeneralView/UserRoleSelection.tsx new file mode 100644 index 0000000000..697d33b2b2 --- /dev/null +++ b/src/app/drive/components/ShareDialog/components/GeneralView/UserRoleSelection.tsx @@ -0,0 +1,151 @@ +import { Popover } from '@headlessui/react'; +import { Button, Loader } from '@internxt/ui'; +import { CaretDown, Check, Globe, Link, Users } from '@phosphor-icons/react'; +import { useTranslationContext } from 'app/i18n/provider/TranslationProvider'; +import { AccessMode } from '../../types'; + +export const LoadingState = ({ isLoading }: { isLoading: boolean }) => { + return ( +
+ {isLoading ? : } +
+ ); +}; + +interface UserRoleSelectionProps { + accessMode: AccessMode; + isLoading: boolean; + isUserOwner: boolean; + isWorkspace: boolean; + isRestrictedSharingAvailable: boolean; + isStopSharingAvailable: boolean; + onCopyLink: () => void; + changeAccess: (accessMode: AccessMode) => void; + setShowStopSharingConfirmation: (show: boolean) => void; +} + +export const UserRoleSelection = ({ + accessMode, + changeAccess, + isLoading, + isUserOwner, + isWorkspace, + isRestrictedSharingAvailable, + isStopSharingAvailable, + onCopyLink, + setShowStopSharingConfirmation, +}: UserRoleSelectionProps) => { + const { translate } = useTranslationContext(); + + return ( +
+
+

{translate('modals.shareModal.general.generalAccess')}

+ + + {({ open }) => ( + <> + + + + + + {({ close }) => ( + <> + {/* Public */} + + {/* Restricted */} + {!isWorkspace && ( + + )} + {/* Stop sharing */} + {isStopSharingAvailable && ( + + )} + + )} + + + )} + +
+ + +
+ ); +}; diff --git a/src/app/drive/components/ShareDialog/components/Header.tsx b/src/app/drive/components/ShareDialog/components/Header.tsx new file mode 100644 index 0000000000..aa7dc581f6 --- /dev/null +++ b/src/app/drive/components/ShareDialog/components/Header.tsx @@ -0,0 +1,49 @@ +import { useTranslationContext } from 'app/i18n/provider/TranslationProvider'; +import { ArrowLeft, X } from '@phosphor-icons/react'; +import { Views } from '../types'; + +interface HeaderProps { + itemToShare; + isLoading: boolean; + headerView: Views; + setView: (view: Views) => void; + onClose: () => void; +} + +export const Header = ({ headerView, isLoading, itemToShare, onClose, setView }: HeaderProps): JSX.Element => { + const { translate } = useTranslationContext(); + + const headers = { + general: ( + <> + + {translate('modals.shareModal.title', { name: itemToShare?.item.name })} + +
+ (isLoading ? null : onClose())} size={22} /> +
+ + ), + invite: ( +
+ setView('general')} size={24} /> + + {translate('modals.shareModal.invite.title')} + +
+ ), + requests: ( +
+ setView('general')} size={24} /> + + {translate('modals.shareModal.requests.title')} + +
+ ), + }; + + return headers[headerView]; +}; From 17ff96037816eee8450df1ca30528c10bcb6c082 Mon Sep 17 00:00:00 2001 From: Xavier Abad Date: Tue, 20 Jan 2026 17:33:21 +0100 Subject: [PATCH 2/6] fix: types and useless exports --- .../components/GeneralView/InvitedUsersList.tsx | 12 +++++++++--- .../components/GeneralView/UserRoleSelection.tsx | 2 +- .../components/ShareDialog/components/Header.tsx | 3 ++- src/app/store/slices/storage/storage.model.ts | 11 +++-------- src/app/store/slices/storage/types.ts | 10 ++++++++++ 5 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/app/drive/components/ShareDialog/components/GeneralView/InvitedUsersList.tsx b/src/app/drive/components/ShareDialog/components/GeneralView/InvitedUsersList.tsx index e945f014dd..4bdc26b15c 100644 --- a/src/app/drive/components/ShareDialog/components/GeneralView/InvitedUsersList.tsx +++ b/src/app/drive/components/ShareDialog/components/GeneralView/InvitedUsersList.tsx @@ -1,14 +1,20 @@ +import { RefObject, MouseEvent } from 'react'; import { useTranslationContext } from 'app/i18n/provider/TranslationProvider'; import { User } from '../User'; import { InvitedUsersSkeletonLoader } from '../InvitedUsersSkeletonLoader'; import { InvitedUserProps } from '../../types'; +import { UserSettings } from '@internxt/sdk/dist/shared/types/userSettings'; interface InvitedUsersListProps { - userList; + userList: RefObject; invitedUsers: InvitedUserProps[]; areInvitedUsersLoading: boolean; - user; - openUserOptions: (e: any, user: InvitedUserProps, selectedIndex: number | null) => void; + user: UserSettings; + openUserOptions: ( + e: MouseEvent, + user: InvitedUserProps, + selectedIndex: number | null, + ) => void; userOptionsY: number; selectedUserListIndex: number | null; onRemoveUser: (user: InvitedUserProps) => void; diff --git a/src/app/drive/components/ShareDialog/components/GeneralView/UserRoleSelection.tsx b/src/app/drive/components/ShareDialog/components/GeneralView/UserRoleSelection.tsx index 697d33b2b2..432a327b9e 100644 --- a/src/app/drive/components/ShareDialog/components/GeneralView/UserRoleSelection.tsx +++ b/src/app/drive/components/ShareDialog/components/GeneralView/UserRoleSelection.tsx @@ -4,7 +4,7 @@ import { CaretDown, Check, Globe, Link, Users } from '@phosphor-icons/react'; import { useTranslationContext } from 'app/i18n/provider/TranslationProvider'; import { AccessMode } from '../../types'; -export const LoadingState = ({ isLoading }: { isLoading: boolean }) => { +const LoadingState = ({ isLoading }: { isLoading: boolean }) => { return (
{isLoading ? : } diff --git a/src/app/drive/components/ShareDialog/components/Header.tsx b/src/app/drive/components/ShareDialog/components/Header.tsx index aa7dc581f6..5387a9410f 100644 --- a/src/app/drive/components/ShareDialog/components/Header.tsx +++ b/src/app/drive/components/ShareDialog/components/Header.tsx @@ -1,9 +1,10 @@ import { useTranslationContext } from 'app/i18n/provider/TranslationProvider'; import { ArrowLeft, X } from '@phosphor-icons/react'; import { Views } from '../types'; +import { ItemToShare } from 'app/store/slices/storage/types'; interface HeaderProps { - itemToShare; + itemToShare: ItemToShare | null; isLoading: boolean; headerView: Views; setView: (view: Views) => void; diff --git a/src/app/store/slices/storage/storage.model.ts b/src/app/store/slices/storage/storage.model.ts index ad61d0efdf..08be63edab 100644 --- a/src/app/store/slices/storage/storage.model.ts +++ b/src/app/store/slices/storage/storage.model.ts @@ -1,8 +1,7 @@ -import { ShareLink } from '@internxt/sdk/dist/drive/share/types'; -import { AdvancedSharedItem, SharedNamePath } from 'app/share/types'; +import { SharedNamePath } from 'app/share/types'; import { OrderDirection, OrderSettings } from '../../../core/types'; import { DriveItemData, FileViewMode, FolderPath, FolderPathDialog } from 'app/drive/types'; -import { IRoot } from './types'; +import { IRoot, ItemToShare } from './types'; export interface StorageFilters { text: string; @@ -24,11 +23,7 @@ export interface StorageState { filters: StorageFilters; order: OrderSettings; selectedItems: DriveItemData[]; - itemToShare: { - share?: ShareLink; - sharings?: { type: string; id: string }[]; - item: DriveItemData | (AdvancedSharedItem & { user: { email: string } }); - } | null; + itemToShare: ItemToShare | null; itemsToDelete: DriveItemData[]; itemsToMove: DriveItemData[]; itemToRename: DriveItemData | null; diff --git a/src/app/store/slices/storage/types.ts b/src/app/store/slices/storage/types.ts index 9bb300c2f5..f812b4e594 100644 --- a/src/app/store/slices/storage/types.ts +++ b/src/app/store/slices/storage/types.ts @@ -1,3 +1,7 @@ +import { ShareLink } from '@internxt/sdk/dist/drive/storage/types'; +import { DriveItemData } from 'app/drive/types'; +import { AdvancedSharedItem } from 'app/share/types'; + export interface IRoot { name: string; folderId: string | null; @@ -5,3 +9,9 @@ export interface IRoot { childrenFolders: IRoot[]; fullPathEdited: string; } + +export interface ItemToShare { + share?: ShareLink; + sharings?: { type: string; id: string }[]; + item: DriveItemData | (AdvancedSharedItem & { user: { email: string } }); +} From b0fec17a026d26c8e35a329c457a33f88ae35c8b Mon Sep 17 00:00:00 2001 From: Xavier Abad Date: Tue, 20 Jan 2026 17:44:31 +0100 Subject: [PATCH 3/6] fix: extract props to interface --- .../ShareDialog/components/User.tsx | 36 ++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/app/drive/components/ShareDialog/components/User.tsx b/src/app/drive/components/ShareDialog/components/User.tsx index 795e683b5a..5009c7ab20 100644 --- a/src/app/drive/components/ShareDialog/components/User.tsx +++ b/src/app/drive/components/ShareDialog/components/User.tsx @@ -4,6 +4,24 @@ import { MouseEvent } from 'react'; import { UserOptions } from './UserOptions'; import { InvitedUserProps } from '../types'; +interface UserProps { + user: InvitedUserProps; + listPosition: number | null; + translate: (key: string, props?: Record) => string; + openUserOptions: ( + event: MouseEvent, + user: InvitedUserProps, + listPosition: number | null, + ) => void; + selectedUserListIndex: number | null; + userOptionsY: number; + onRemoveUser: (user: InvitedUserProps) => void; + userOptionsEmail?: InvitedUserProps; + onChangeRole: (email: string, roleName: string) => void; + disableUserOptionsPanel: boolean; + disableRoleChange: boolean; +} + export const User = ({ user, listPosition, @@ -16,23 +34,7 @@ export const User = ({ onChangeRole, disableUserOptionsPanel, disableRoleChange, -}: { - user: InvitedUserProps; - listPosition: number | null; - translate: (key: string, props?: Record) => string; - openUserOptions: ( - event: MouseEvent, - user: InvitedUserProps, - listPosition: number | null, - ) => void; - selectedUserListIndex; - userOptionsY; - onRemoveUser; - userOptionsEmail; - onChangeRole: (email: string, roleName: string) => void; - disableUserOptionsPanel: boolean; - disableRoleChange: boolean; -}) => ( +}: UserProps) => (
Date: Wed, 21 Jan 2026 09:27:43 +0100 Subject: [PATCH 4/6] refactor: remove useless code --- .../components/ShareDialog/ShareDialog.tsx | 128 +----------------- 1 file changed, 2 insertions(+), 126 deletions(-) diff --git a/src/app/drive/components/ShareDialog/ShareDialog.tsx b/src/app/drive/components/ShareDialog/ShareDialog.tsx index 408fcc3783..fc5ee0297a 100644 --- a/src/app/drive/components/ShareDialog/ShareDialog.tsx +++ b/src/app/drive/components/ShareDialog/ShareDialog.tsx @@ -1,10 +1,9 @@ -import { Popover } from '@headlessui/react'; import { SharingMeta } from '@internxt/sdk/dist/drive/share/types'; import { UserSettings } from '@internxt/sdk/dist/shared/types/userSettings'; -import { CaretDown, CheckCircle, UserPlus } from '@phosphor-icons/react'; +import { UserPlus } from '@phosphor-icons/react'; import { useTranslationContext } from 'app/i18n/provider/TranslationProvider'; import { MAX_SHARED_NAME_LENGTH } from '../../../../views/Shared/SharedView'; -import { Avatar, Button, Modal } from '@internxt/ui'; +import { Button, Modal } from '@internxt/ui'; import { RootState } from 'app/store'; import { useAppDispatch, useAppSelector } from 'app/store/hooks'; import { Role } from 'app/store/slices/sharedLinks/types'; @@ -251,29 +250,6 @@ const ShareDialog = (props: ShareDialogProps): JSX.Element => { } }; - const onAcceptRequest = (email: string, roleName: UserRole) => { - // TODO -> Accept user access request - setAccessRequests((prevRequests) => - prevRequests.map((request) => { - if (request.email === email) { - return { ...request, status: REQUEST_STATUS.ACCEPTED }; - } - return request; - }), - ); - }; - - const handleDenyRequest = (email: string) => { - setAccessRequests((prevRequests) => - prevRequests.map((request) => { - if (request.email === email) { - return { ...request, status: REQUEST_STATUS.DENIED }; - } - return request; - }), - ); - }; - const onClose = (): void => { dispatch(uiActions.setIsShareDialogOpen(false)); }; @@ -610,106 +586,6 @@ const ShareDialog = (props: ShareDialogProps): JSX.Element => { roles={inviteDialogRoles} /> ), - requests: ( -
- {accessRequests.length > 0 ? ( - accessRequests.map((request, index) => ( -
0 && isRequestPending(request.status) && 'border-t border-gray-5 pt-3' - } ${!isRequestPending(request.status) && 'hide-request'}`} - key={request.email + index} - > -
- - -
-

- {request.name} {request.lastname} -

-

- {request.email} -

-
- -
- - {({ open }) => ( - <> - - - - - - {({ close }) => ( - <> - {/* Reader */} - - - {/* Editor */} - - - )} - - - )} - - -
-
- - {request.message ? ( -
- {request.message.split('\n').map((line) => ( -

{line}

- ))} -
- ) : ( - <> - )} -
- )) - ) : ( -
-
- - {translate('modals.shareModal.requests.empty')} -
-
- )} -
- ), }; return view[viewProps.view]; From fffbff7b572c56a463a38c6b8b7132e6dcaa3d2f Mon Sep 17 00:00:00 2001 From: Xavier Abad Date: Wed, 21 Jan 2026 09:32:40 +0100 Subject: [PATCH 5/6] fix: revert request remoival change --- .../components/ShareDialog/ShareDialog.tsx | 128 +++++++++++++++++- 1 file changed, 126 insertions(+), 2 deletions(-) diff --git a/src/app/drive/components/ShareDialog/ShareDialog.tsx b/src/app/drive/components/ShareDialog/ShareDialog.tsx index fc5ee0297a..408fcc3783 100644 --- a/src/app/drive/components/ShareDialog/ShareDialog.tsx +++ b/src/app/drive/components/ShareDialog/ShareDialog.tsx @@ -1,9 +1,10 @@ +import { Popover } from '@headlessui/react'; import { SharingMeta } from '@internxt/sdk/dist/drive/share/types'; import { UserSettings } from '@internxt/sdk/dist/shared/types/userSettings'; -import { UserPlus } from '@phosphor-icons/react'; +import { CaretDown, CheckCircle, UserPlus } from '@phosphor-icons/react'; import { useTranslationContext } from 'app/i18n/provider/TranslationProvider'; import { MAX_SHARED_NAME_LENGTH } from '../../../../views/Shared/SharedView'; -import { Button, Modal } from '@internxt/ui'; +import { Avatar, Button, Modal } from '@internxt/ui'; import { RootState } from 'app/store'; import { useAppDispatch, useAppSelector } from 'app/store/hooks'; import { Role } from 'app/store/slices/sharedLinks/types'; @@ -250,6 +251,29 @@ const ShareDialog = (props: ShareDialogProps): JSX.Element => { } }; + const onAcceptRequest = (email: string, roleName: UserRole) => { + // TODO -> Accept user access request + setAccessRequests((prevRequests) => + prevRequests.map((request) => { + if (request.email === email) { + return { ...request, status: REQUEST_STATUS.ACCEPTED }; + } + return request; + }), + ); + }; + + const handleDenyRequest = (email: string) => { + setAccessRequests((prevRequests) => + prevRequests.map((request) => { + if (request.email === email) { + return { ...request, status: REQUEST_STATUS.DENIED }; + } + return request; + }), + ); + }; + const onClose = (): void => { dispatch(uiActions.setIsShareDialogOpen(false)); }; @@ -586,6 +610,106 @@ const ShareDialog = (props: ShareDialogProps): JSX.Element => { roles={inviteDialogRoles} /> ), + requests: ( +
+ {accessRequests.length > 0 ? ( + accessRequests.map((request, index) => ( +
0 && isRequestPending(request.status) && 'border-t border-gray-5 pt-3' + } ${!isRequestPending(request.status) && 'hide-request'}`} + key={request.email + index} + > +
+ + +
+

+ {request.name} {request.lastname} +

+

+ {request.email} +

+
+ +
+ + {({ open }) => ( + <> + + + + + + {({ close }) => ( + <> + {/* Reader */} + + + {/* Editor */} + + + )} + + + )} + + +
+
+ + {request.message ? ( +
+ {request.message.split('\n').map((line) => ( +

{line}

+ ))} +
+ ) : ( + <> + )} +
+ )) + ) : ( +
+
+ + {translate('modals.shareModal.requests.empty')} +
+
+ )} +
+ ), }; return view[viewProps.view]; From 0e27a4224a735dd7f12eb15b043ffcfd52c83e99 Mon Sep 17 00:00:00 2001 From: Xavier Abad Date: Wed, 21 Jan 2026 09:34:32 +0100 Subject: [PATCH 6/6] refactor(shared): remove requests dialog and its logic --- .../components/ShareDialog/ShareDialog.tsx | 166 +----------------- 1 file changed, 3 insertions(+), 163 deletions(-) diff --git a/src/app/drive/components/ShareDialog/ShareDialog.tsx b/src/app/drive/components/ShareDialog/ShareDialog.tsx index 408fcc3783..0f411c548a 100644 --- a/src/app/drive/components/ShareDialog/ShareDialog.tsx +++ b/src/app/drive/components/ShareDialog/ShareDialog.tsx @@ -1,10 +1,9 @@ -import { Popover } from '@headlessui/react'; import { SharingMeta } from '@internxt/sdk/dist/drive/share/types'; import { UserSettings } from '@internxt/sdk/dist/shared/types/userSettings'; -import { CaretDown, CheckCircle, UserPlus } from '@phosphor-icons/react'; +import { UserPlus } from '@phosphor-icons/react'; import { useTranslationContext } from 'app/i18n/provider/TranslationProvider'; import { MAX_SHARED_NAME_LENGTH } from '../../../../views/Shared/SharedView'; -import { Avatar, Button, Modal } from '@internxt/ui'; +import { Button, Modal } from '@internxt/ui'; import { RootState } from 'app/store'; import { useAppDispatch, useAppSelector } from 'app/store/hooks'; import { Role } from 'app/store/slices/sharedLinks/types'; @@ -23,16 +22,7 @@ import { DriveItemData } from 'app/drive/types'; import ShareInviteDialog from '../ShareInviteDialog/ShareInviteDialog'; import './ShareDialog.scss'; import envService from 'services/env.service'; -import { - AccessMode, - InvitedUserProps, - REQUEST_STATUS, - RequestProps, - RequestStatus, - UserRole, - ViewProps, - Views, -} from './types'; +import { AccessMode, InvitedUserProps, UserRole, ViewProps, Views } from './types'; import navigationService from 'services/navigation.service'; import { Service } from '@internxt/sdk/dist/drive/payments/types/tiers'; import { SharePasswordInputDialog } from 'app/share/components/SharePasswordInputDialog/SharePasswordInputDialog'; @@ -44,9 +34,6 @@ import { UserRoleSelection } from './components/GeneralView/UserRoleSelection'; import { InvitedUsersList } from './components/GeneralView/InvitedUsersList'; import { Header } from './components/Header'; -const isRequestPending = (status: RequestStatus): boolean => - status !== REQUEST_STATUS.DENIED && status !== REQUEST_STATUS.ACCEPTED; - const cropSharedName = (name: string) => { if (name.length > MAX_SHARED_NAME_LENGTH) { return name.substring(0, 32).concat('...'); @@ -118,7 +105,6 @@ const ShareDialog = (props: ShareDialogProps): JSX.Element => { const [isRestrictedSharingDialogOpen, setIsRestrictedSharingDialogOpen] = useState(false); const [isRestrictedPasswordDialogOpen, setIsRestrictedPasswordDialogOpen] = useState(false); - const [accessRequests, setAccessRequests] = useState([]); const [userOptionsEmail, setUserOptionsEmail] = useState(); const [userOptionsY, setUserOptionsY] = useState(0); const [view, setView] = useState('general'); @@ -139,7 +125,6 @@ const ShareDialog = (props: ShareDialogProps): JSX.Element => { setShowStopSharingConfirmation(false); setIsLoading(false); setInvitedUsers([]); - setAccessRequests([]); setUserOptionsEmail(undefined); setUserOptionsY(0); setView('general'); @@ -167,17 +152,6 @@ const ShareDialog = (props: ShareDialogProps): JSX.Element => { if (roles.length > 0 && isOpen) loadShareInfo(); }, [roles, isOpen]); - useEffect(() => { - const removeDeniedRequests = () => { - setAccessRequests((prevRequests) => prevRequests.filter((request) => isRequestPending(request.status))); - }; - - let timer; - if (accessRequests.some((req) => !isRequestPending(req.status))) timer = setTimeout(removeDeniedRequests, 500); - - return () => clearTimeout(timer); - }, [accessRequests]); - useEffect(() => { const currentInvitedUser = invitedUsers.find((user) => user.email === props.user.email); setCurrentUserFolderRole(currentInvitedUser?.roleName); @@ -251,29 +225,6 @@ const ShareDialog = (props: ShareDialogProps): JSX.Element => { } }; - const onAcceptRequest = (email: string, roleName: UserRole) => { - // TODO -> Accept user access request - setAccessRequests((prevRequests) => - prevRequests.map((request) => { - if (request.email === email) { - return { ...request, status: REQUEST_STATUS.ACCEPTED }; - } - return request; - }), - ); - }; - - const handleDenyRequest = (email: string) => { - setAccessRequests((prevRequests) => - prevRequests.map((request) => { - if (request.email === email) { - return { ...request, status: REQUEST_STATUS.DENIED }; - } - return request; - }), - ); - }; - const onClose = (): void => { dispatch(uiActions.setIsShareDialogOpen(false)); }; @@ -500,17 +451,6 @@ const ShareDialog = (props: ShareDialogProps): JSX.Element => { {translate('modals.shareModal.list.peopleWithAccess')}
- {accessRequests.length > 0 && ( - - )} {currentUserFolderRole !== 'reader' && !isWorkspace ? ( - - - - {({ close }) => ( - <> - {/* Reader */} - - - {/* Editor */} - - - )} - - - )} - - -
-
- - {request.message ? ( -
- {request.message.split('\n').map((line) => ( -

{line}

- ))} -
- ) : ( - <> - )} -
- )) - ) : ( -
-
- - {translate('modals.shareModal.requests.empty')} -
-
- )} -
- ), }; return view[viewProps.view];