️ Writeable shared links part 1 (#66)

* Minor fixes and implemented writeable shared links (no security)

* Go t onode 16 for frontend
This commit is contained in:
Romaric Mourgues
2023-06-05 10:06:22 +02:00
committed by GitHub
parent f8d3fc9784
commit 49ec20d60e
12 changed files with 97 additions and 95 deletions
+1 -1
View File
@@ -44,7 +44,7 @@ jobs:
path: tdrive/frontend/build/
publish-frontend:
# needs: build-frontend
# needs: build-frontend
runs-on: ubuntu-20.04
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/qa' || github.ref == 'refs/heads/canary'
steps:
@@ -51,24 +51,6 @@ class CurrentUser extends Observable {
return getUser(Login.currentUserId);
}
updateUserStatus = (newStatus: string[]) => {
return () => {
const { updateStatus } = useCurrentUser();
updateStatus(newStatus);
};
};
async updateStatusIcon(status: string[]) {
const update = {
id: Login.currentUserId,
status_icon: status,
};
Collections.get('users').updateObject(update);
this.updateUserStatus(status);
await UserAPIClient.updateUserStatus(`${status[0]} ${status[1]}`);
}
updateTutorialStatus(key: string, set_false?: unknown) {
const user = this.get();
if (!user) {
@@ -106,7 +106,9 @@ export const useCurrentCompanyRealtime = () => {
* @param user
* @returns CompanyType | undefined
*/
export function useBestCandidateCompany(user: UserType | undefined): CompanyType | undefined {
export function useBestCandidateCompany(
user: UserType | undefined | null,
): CompanyType | undefined {
const routerCompanyId = useRouterCompany();
const storageCompanyId = (LocalStorage.getItem('default_company_id') as string) || null;
@@ -24,6 +24,10 @@ export const setPublicLinkToken = (token: string | null) => {
publicLinkToken = token;
};
export const getPublicLinkToken = () => {
return publicLinkToken;
};
export const setTdriveTabToken = (token: string | null) => {
tdriveTabToken = token;
};
@@ -6,18 +6,17 @@ import { useRecoilState } from 'recoil';
import { CurrentUserState } from '../state/atoms/current-user';
import { useRealtimeRoom } from '@features/global/hooks/use-realtime';
import Languages from '@features/global/services/languages-service';
import { RealtimeApplicationEvent } from '@features/global/types/realtime-types';
import { useSetUserList } from './use-user-list';
import { getPublicLinkToken } from 'app/features/drive/api-client/api-client';
export const useCurrentUser = () => {
console.log("getting current user");
const [user, setUser] = useRecoilState(CurrentUserState);
const { set: setUserList } = useSetUserList('useCurrentUser');
//Depreciated way to get use update from LoginService
LoginService.recoilUpdateUser = setUser;
useEffect(() => {
if (!user) {
if (!user && !getPublicLinkToken()) {
LoginService.init();
LoginService.login({});
}
@@ -29,17 +28,13 @@ export const useCurrentUser = () => {
if (user?.preferences?.locale) Languages.setLanguage(user?.preferences?.locale);
}, [user?.preferences?.locale]);
const updateStatus = async (userStatus: string[]) => {
await UserAPIClient.updateUserStatus(`${userStatus[0]} ${userStatus[1]}`);
await refresh();
};
const refresh = async () => {
await LoginService.updateUser();
if (!getPublicLinkToken()) {
await LoginService.updateUser();
}
};
return { user, refresh, updateStatus };
return { user, refresh };
};
export const useCurrentUserRealtime = () => {
@@ -118,7 +118,7 @@ export default memo(
return (
<UploadZone
overClassName={''}
className="min-h-full"
className="h-full overflow-hidden"
disableClick
parent={''}
multiple={true}
@@ -146,7 +146,7 @@ export default memo(
<div
className={
'flex flex-col grow h-full overflow-auto ' +
'flex flex-col grow h-full overflow-hidden ' +
(loading && (!children?.length || loadingParentChange) ? 'opacity-50 ' : '')
}
>
@@ -167,7 +167,7 @@ export default memo(
</Menu>
</div>
<div className="grow">
<div className="grow overflow-auto">
{folders.length > 0 && (
<>
<Title className="mb-2 block">Folders</Title>
@@ -8,7 +8,7 @@ import { PropertiesModalAtom } from './modals/properties';
import { SelectorModalAtom } from './modals/selector';
import { AccessModalAtom } from './modals/update-access';
import { VersionsModalAtom } from './modals/versions';
import { DriveApiClient } from '@features/drive/api-client/api-client';
import { DriveApiClient, getPublicLinkToken } from '@features/drive/api-client/api-client';
import { useDriveActions } from '@features/drive/hooks/use-drive-actions';
import { getPublicLink } from '@features/drive/hooks/use-drive-item';
import { useDrivePreview } from '@features/drive/hooks/use-drive-preview';
@@ -71,8 +71,8 @@ export const useOnBuildContextMenu = (children: DriveItem[], initialParentId?: s
},
{
type: 'menu',
text: 'Manage access',
hide: access === 'read',
text: 'Manage access and sharing',
hide: access === 'read' || getPublicLinkToken(),
onClick: () => setAccessModalState({ open: true, id: item.id }),
},
{
@@ -95,7 +95,7 @@ const PathItem = ({
href="#"
className="text-sm font-medium text-gray-700 hover:text-blue-600 dark:text-gray-400 dark:hover:text-white"
onClick={evt => {
if (first) {
if (first && user?.id) {
MenusManager.openMenu(
[
{ type: 'menu', text: 'Home', onClick: () => onClick('root') },
@@ -114,7 +114,7 @@ const PathItem = ({
{item?.access_info?.public?.level && item?.access_info?.public?.level !== 'none' && (
<PublicIcon className="h-5 w-5 ml-2" />
)}
{first && (
{first && !!user?.id && (
<span className="ml-2 -mr-1 text-gray-700">
<ChevronDownIcon className="w-4 h-4" />
</span>
@@ -41,7 +41,7 @@ export const PublicLinkManager = ({ id, disabled }: { id: string; disabled?: boo
</div>
<div className="shrink-0">
<AccessLevel
hiddenLevels={['manage', 'write']}
hiddenLevels={['manage']}
disabled={loading || disabled}
level={item?.access_info?.public?.level || null}
onChange={level => {
@@ -6,15 +6,20 @@ import Languages from '@features/global/services/languages-service';
import { addApiUrlIfNeeded } from '@features/global/utils/URLUtils';
import RouterService from '@features/router/services/router-service';
import Drive from '@views/client/body/drive';
import { Button } from 'app/atoms/button/button';
import { Input } from 'app/atoms/input/input-text';
import { Base, Subtitle, Title } from 'app/atoms/text';
import UploadsViewer from 'app/components/file-uploads/uploads-viewer';
import { useDriveItem } from 'app/features/drive/hooks/use-drive-item';
import { useDriveUpload } from 'app/features/drive/hooks/use-drive-upload';
import { useParams } from 'react-router-dom';
import { useSetRecoilState } from 'recoil';
import shortUUID from 'short-uuid';
import Avatar from '../../../../atoms/avatar';
import { setPublicLinkToken } from '../../../../features/drive/api-client/api-client';
import useRouterCompany from '../../../../features/router/hooks/use-router-company';
import { useDriveItem } from 'app/features/drive/hooks/use-drive-item';
import { Base, Subtitle, Title } from 'app/atoms/text';
import { Input } from 'app/atoms/input/input-text';
import { Button } from 'app/atoms/button/button';
import { CreateModalAtom } from './modals/create';
import { CreateModalWithUploadZones } from '../../side-bar/actions';
export default () => {
const companyId = useRouterCompany();
@@ -71,6 +76,8 @@ export default () => {
</AccessChecker>
</div>
<MenusBodyLayer />
<UploadsViewer />
<CreateModalWithUploadZones />
</div>
);
};
@@ -46,7 +46,7 @@ export default React.memo((): JSX.Element => {
<FeatureToggles features={activeFeatureNames}>
<>
<Header openSideMenu={() => setMenuIsOpen(true)} />
<div className="grow flex flex-row grid-cols-2 sm:px-2 sm:pb-2">
<div className="grow flex flex-row grid-cols-2 sm:px-2 sm:pb-2 overflow-hidden">
<div
style={
menuIsOpen
@@ -12,72 +12,84 @@ import { ConfirmDeleteModalAtom } from '../body/drive/modals/confirm-delete';
import { CreateModal, CreateModalAtom } from '../body/drive/modals/create';
import { Button } from '@atoms/button/button';
export default () => {
export const CreateModalWithUploadZones = () => {
const companyId = useRouterCompany();
const uploadZoneRef = useRef<UploadZone | null>(null);
const uploadFolderZoneRef = useRef<UploadZone | null>(null);
const setCreationModalState = useSetRecoilState(CreateModalAtom);
const { uploadTree, uploadFromUrl } = useDriveUpload();
const [parentId, _] = useRecoilState(DriveCurrentFolderAtom('root'));
return (
<>
<UploadZone
overClassName={'!hidden'}
className="hidden"
disableClick
parent={''}
multiple={true}
ref={uploadZoneRef}
driveCollectionKey={'side-menu'}
onAddFiles={async (_, event) => {
const tree = await getFilesTree(event);
setCreationModalState({ parent_id: '', open: false });
uploadTree(tree, {
companyId,
parentId,
});
}}
/>
<UploadZone
overClassName={'!hidden'}
className="hidden"
disableClick
parent={''}
multiple={true}
ref={uploadFolderZoneRef}
directory={true}
driveCollectionKey={'side-menu'}
onAddFiles={async (_, event) => {
const tree = await getFilesTree(event);
setCreationModalState({ parent_id: '', open: false });
uploadTree(tree, {
companyId,
parentId,
});
}}
/>
<CreateModal
selectFolderFromDevice={() => uploadFolderZoneRef.current?.open()}
selectFromDevice={() => uploadZoneRef.current?.open()}
addFromUrl={(url, name) => {
setCreationModalState({ parent_id: '', open: false });
uploadFromUrl(url, name, {
companyId,
parentId,
});
}}
/>
</>
);
};
export default () => {
const [parentId, _] = useRecoilState(DriveCurrentFolderAtom('root'));
const { access, item, inTrash } = useDriveItem(parentId);
const { children: trashChildren } = useDriveItem('trash');
const uploadZoneRef = useRef<UploadZone | null>(null);
const uploadFolderZoneRef = useRef<UploadZone | null>(null);
const setConfirmDeleteModalState = useSetRecoilState(ConfirmDeleteModalAtom);
const setCreationModalState = useSetRecoilState(CreateModalAtom);
const { uploadTree, uploadFromUrl } = useDriveUpload();
const openItemModal = useCallback(() => {
if (item?.id) setCreationModalState({ open: true, parent_id: item.id });
}, [item?.id, setCreationModalState]);
return (
<div className="-m-4">
<div className="-m-4 overflow-hidden">
<AnimatedHeight>
<div className="p-4">
<UploadZone
overClassName={'!hidden'}
className="hidden"
disableClick
parent={''}
multiple={true}
ref={uploadZoneRef}
driveCollectionKey={'side-menu'}
onAddFiles={async (_, event) => {
const tree = await getFilesTree(event);
setCreationModalState({ parent_id: '', open: false });
uploadTree(tree, {
companyId,
parentId,
});
}}
/>
<UploadZone
overClassName={'!hidden'}
className="hidden"
disableClick
parent={''}
multiple={true}
ref={uploadFolderZoneRef}
directory={true}
driveCollectionKey={'side-menu'}
onAddFiles={async (_, event) => {
const tree = await getFilesTree(event);
setCreationModalState({ parent_id: '', open: false });
uploadTree(tree, {
companyId,
parentId,
});
}}
/>
<CreateModal
selectFolderFromDevice={() => uploadFolderZoneRef.current?.open()}
selectFromDevice={() => uploadZoneRef.current?.open()}
addFromUrl={(url, name) => {
setCreationModalState({ parent_id: '', open: false });
uploadFromUrl(url, name, {
companyId,
parentId,
});
}}
/>
<CreateModalWithUploadZones />
{inTrash && access === 'manage' && (
<>