🌐Translations for the latest features (#78)
* 🌐Translations for the latest features
Also:
- Rename “Home” to Shared drive
- Hide banner with suggestion of downloading desktop app
- Fix Upload button on main screen
- Add separate buttons for the manage access and share by link
This commit is contained in:
@@ -35,5 +35,6 @@ export default (): React.ReactElement => {
|
||||
});
|
||||
}, []);
|
||||
|
||||
return showBanner ? <DownloadBanner onBannerClose={removeBanner} download={download} /> : <></>;
|
||||
return <></>;
|
||||
// return showBanner ? <DownloadBanner onBannerClose={removeBanner} download={download} /> : <></>;
|
||||
};
|
||||
|
||||
+2
-3
@@ -41,11 +41,10 @@ export default ({ pendingFilesState, visible }: PropsType) => {
|
||||
|
||||
const momentTimeRemaining = moment(new Date().getTime() + timeRemainingInMs).fromNow();
|
||||
|
||||
// TODO translation
|
||||
if (momentTimeRemaining !== 'Invalid date') {
|
||||
return `Will end ${momentTimeRemaining}...`;
|
||||
return Languages.t('components.pending_file_list.estimation.end') + `Will end ${momentTimeRemaining}...`;
|
||||
} else {
|
||||
return `Waiting for time approximations...`;
|
||||
return Languages.t('components.pending_file_list.estimation.approximations');
|
||||
}
|
||||
}, [getOnePendingFile, pendingFilesState]);
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ export default class UploadZone extends React.Component<PropsType, StateType> {
|
||||
}
|
||||
|
||||
open() {
|
||||
console.log("OPEN");
|
||||
if (this.props.disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -71,6 +71,23 @@ class CurrentUser extends Observable {
|
||||
Api.post('/ajax/users/account/set_tutorial_status', data, () => {});
|
||||
}
|
||||
|
||||
async updateLanguage(lng: string) {
|
||||
await Languages.setLanguage(lng)
|
||||
.then(() => console.log("Language set to " + lng));
|
||||
|
||||
const preferences = {
|
||||
... this.get().preferences,
|
||||
language: lng,
|
||||
locale: lng,
|
||||
}
|
||||
await UserAPIClient
|
||||
.setUserPreferences(preferences)
|
||||
.then(() => console.log("User preferences set to: " + preferences))
|
||||
.then(() => console.log(preferences))
|
||||
.then(() => window.location.reload())
|
||||
.catch(e => "Error setting user preferences " + e);
|
||||
}
|
||||
|
||||
updateUserName(username: string) {
|
||||
const that = this;
|
||||
const update = {
|
||||
|
||||
@@ -29,6 +29,7 @@ import { VersionsModal } from './modals/versions';
|
||||
import { SharedFilesTable } from './shared-files-table';
|
||||
import RouterServices from '@features/router/services/router-service';
|
||||
import useRouteState from 'app/features/router/hooks/use-route-state';
|
||||
import Languages from "features/global/services/languages-service";
|
||||
|
||||
export const DriveCurrentFolderAtom = atomFamily<
|
||||
string,
|
||||
@@ -170,12 +171,12 @@ export default memo(
|
||||
<div className="grow" />
|
||||
|
||||
{access !== 'read' && (
|
||||
<BaseSmall>{formatBytes(item?.size || 0)} used in this folder</BaseSmall>
|
||||
<BaseSmall>{formatBytes(item?.size || 0)} { Languages.t('scenes.app.drive.used')}</BaseSmall>
|
||||
)}
|
||||
<Menu menu={() => onBuildContextMenu(details)}>
|
||||
{' '}
|
||||
<Button theme="secondary" className="ml-4 flex flex-row items-center">
|
||||
<span>{selectedCount > 1 ? `${selectedCount} items` : 'More'} </span>
|
||||
<span>{selectedCount > 1 ? `${selectedCount} items` : Languages.t('scenes.app.drive.context_menu')} </span>
|
||||
|
||||
<ChevronDownIcon className="h-4 w-4 ml-2 -mr-1" />
|
||||
</Button>
|
||||
@@ -185,7 +186,7 @@ export default memo(
|
||||
<div className="grow overflow-auto">
|
||||
{folders.length > 0 && (
|
||||
<>
|
||||
<Title className="mb-2 block">Folders</Title>
|
||||
<Title className="mb-2 block">{Languages.t('scenes.app.drive.folders')}</Title>
|
||||
|
||||
{folders.map((child, index) => (
|
||||
<FolderRow
|
||||
@@ -209,19 +210,19 @@ export default memo(
|
||||
</>
|
||||
)}
|
||||
|
||||
<Title className="mb-2 block">Documents</Title>
|
||||
<Title className="mb-2 block">{Languages.t('scenes.app.drive.documents')}</Title>
|
||||
|
||||
{documents.length === 0 && !loading && (
|
||||
<div className="mt-4 text-center border-2 border-dashed rounded-md p-8">
|
||||
<Subtitle className="block mb-2">Nothing here.</Subtitle>
|
||||
<Subtitle className="block mb-2">{Languages.t('scenes.app.drive.nothing')}</Subtitle>
|
||||
{!inTrash && access != 'read' && (
|
||||
<>
|
||||
<Base>
|
||||
Drag and drop files to upload them or click on the 'Add document' button.
|
||||
{Languages.t('scenes.app.drive.drag_and_drop')}
|
||||
</Base>
|
||||
<br />
|
||||
<Button onClick={() => openItemModal()} theme="primary" className="mt-4">
|
||||
Add document or folder
|
||||
{Languages.t('scenes.app.drive.add_doc')}
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -16,6 +16,7 @@ import { DriveItemSelectedList } from '@features/drive/state/store';
|
||||
import { DriveItem, DriveItemDetails } from '@features/drive/types';
|
||||
import { ToasterService } from '@features/global/services/toaster-service';
|
||||
import { copyToClipboard } from '@features/global/utils/CopyClipboard';
|
||||
import Languages from "features/global/services/languages-service";
|
||||
|
||||
/**
|
||||
* This will build the context menu in different contexts
|
||||
@@ -55,53 +56,59 @@ export const useOnBuildContextMenu = (children: DriveItem[], initialParentId?: s
|
||||
const newMenuActions = [
|
||||
{
|
||||
type: 'menu',
|
||||
text: 'Preview',
|
||||
text: Languages.t('components.item_context_menu.preview'),
|
||||
hide: item.is_directory,
|
||||
onClick: () => preview(item),
|
||||
},
|
||||
{
|
||||
type: 'menu',
|
||||
text: 'Download',
|
||||
text: Languages.t('components.item_context_menu.download'),
|
||||
onClick: () => download(item.id),
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
type: 'menu',
|
||||
text: 'Rename',
|
||||
text: Languages.t('components.item_context_menu.rename'),
|
||||
hide: access === 'read',
|
||||
onClick: () => setPropertiesModalState({ open: true, id: item.id }),
|
||||
},
|
||||
{
|
||||
type: 'menu',
|
||||
text: 'Manage access and sharing',
|
||||
text: Languages.t('components.item_context_menu.manage_access'),
|
||||
hide: access === 'read' || getPublicLinkToken(),
|
||||
onClick: () => setAccessModalState({ open: true, id: item.id }),
|
||||
},
|
||||
{
|
||||
type: 'menu',
|
||||
text: 'Copy public link',
|
||||
text: Languages.t('components.item_context_menu.share'),
|
||||
hide: access === 'read' || getPublicLinkToken(),
|
||||
onClick: () => setAccessModalState({ open: true, id: item.id }),
|
||||
},
|
||||
{
|
||||
type: 'menu',
|
||||
text: Languages.t('components.item_context_menu.copy_link'),
|
||||
hide: !item.access_info.public?.level || item.access_info.public?.level === 'none',
|
||||
onClick: () => {
|
||||
copyToClipboard(getPublicLink(item || parent?.item));
|
||||
ToasterService.success('Public link copied to clipboard');
|
||||
ToasterService.success(Languages.t('components.item_context_menu.copy_link.success'));
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'menu',
|
||||
text: 'Versions',
|
||||
text: Languages.t('components.item_context_menu.versions'),
|
||||
hide: item.is_directory,
|
||||
onClick: () => setVersionModal({ open: true, id: item.id }),
|
||||
},
|
||||
{
|
||||
type: 'menu',
|
||||
text: 'Move',
|
||||
text: Languages.t('components.item_context_menu.move'),
|
||||
hide: access === 'read',
|
||||
onClick: () =>
|
||||
setSelectorModalState({
|
||||
open: true,
|
||||
parent_id: inTrash ? 'root' : item.parent_id,
|
||||
mode: 'move',
|
||||
title: `Move '${item.name}'`,
|
||||
title: Languages.t('components.item_context_menu.move.modal_header') + ` '${item.name}'`,
|
||||
onSelected: async ids => {
|
||||
await update(
|
||||
{
|
||||
@@ -116,14 +123,14 @@ export const useOnBuildContextMenu = (children: DriveItem[], initialParentId?: s
|
||||
{ type: 'separator', hide: access !== 'manage' },
|
||||
{
|
||||
type: 'menu',
|
||||
text: 'Move to trash',
|
||||
text: Languages.t('components.item_context_menu.move_to_trash'),
|
||||
className: 'error',
|
||||
hide: inTrash || access !== 'manage',
|
||||
onClick: () => setConfirmTrashModalState({ open: true, items: [item] }),
|
||||
},
|
||||
{
|
||||
type: 'menu',
|
||||
text: 'Delete',
|
||||
text: Languages.t('components.item_context_menu.delete'),
|
||||
className: 'error',
|
||||
hide: !inTrash || access !== 'manage',
|
||||
onClick: () => setConfirmDeleteModalState({ open: true, items: [item] }),
|
||||
@@ -139,13 +146,13 @@ export const useOnBuildContextMenu = (children: DriveItem[], initialParentId?: s
|
||||
const newMenuActions: any[] = [
|
||||
{
|
||||
type: 'menu',
|
||||
text: 'Move ' + selectedCount + ' items',
|
||||
text: Languages.t('components.item_context_menu.move_multiple'),
|
||||
hide: parent.access === 'read',
|
||||
onClick: () =>
|
||||
setSelectorModalState({
|
||||
open: true,
|
||||
parent_id: inTrash ? 'root' : parent.item!.id,
|
||||
title: 'Move ' + selectedCount + ' items',
|
||||
title: Languages.t('components.item_context_menu.move_multiple.modal_header'),
|
||||
mode: 'move',
|
||||
onSelected: async ids => {
|
||||
for (const item of checked) {
|
||||
@@ -163,19 +170,19 @@ export const useOnBuildContextMenu = (children: DriveItem[], initialParentId?: s
|
||||
},
|
||||
{
|
||||
type: 'menu',
|
||||
text: 'Download ' + selectedCount + ' items',
|
||||
text: Languages.t('components.item_context_menu.download_multiple'),
|
||||
onClick: () =>
|
||||
selectedCount === 1 ? download(checked[0].id) : downloadZip(checked.map(c => c.id)),
|
||||
},
|
||||
{
|
||||
type: 'menu',
|
||||
text: 'Clear selection',
|
||||
text: Languages.t('components.item_context_menu.clear_selection'),
|
||||
onClick: () => setChecked({}),
|
||||
},
|
||||
{ type: 'separator', hide: parent.access === 'read' },
|
||||
{
|
||||
type: 'menu',
|
||||
text: 'Delete ' + selectedCount + ' items',
|
||||
text: Languages.t('components.item_context_menu.delete_multiple'),
|
||||
hide: !inTrash || parent.access !== 'manage',
|
||||
className: 'error',
|
||||
onClick: () => {
|
||||
@@ -187,7 +194,7 @@ export const useOnBuildContextMenu = (children: DriveItem[], initialParentId?: s
|
||||
},
|
||||
{
|
||||
type: 'menu',
|
||||
text: 'Move ' + selectedCount + ' items to trash',
|
||||
text: Languages.t('components.item_context_menu.to_trash_multiple'),
|
||||
hide: inTrash || parent.access !== 'manage',
|
||||
className: 'error',
|
||||
onClick: async () =>
|
||||
@@ -207,13 +214,13 @@ export const useOnBuildContextMenu = (children: DriveItem[], initialParentId?: s
|
||||
? [
|
||||
{
|
||||
type: 'menu',
|
||||
text: 'Exit trash',
|
||||
text: Languages.t('components.item_context_menu.trash.exit'),
|
||||
onClick: () => setParentId('root'),
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
type: 'menu',
|
||||
text: 'Empty trash',
|
||||
text: Languages.t('components.item_context_menu.trash.empty'),
|
||||
className: 'error',
|
||||
hide: parent.item!.id != 'trash' || parent.access !== 'manage',
|
||||
onClick: () => {
|
||||
@@ -227,7 +234,7 @@ export const useOnBuildContextMenu = (children: DriveItem[], initialParentId?: s
|
||||
: [
|
||||
{
|
||||
type: 'menu',
|
||||
text: 'Add document or folder',
|
||||
text: Languages.t('components.item_context_menu.add_documents'),
|
||||
hide: inTrash || parent.access === 'read',
|
||||
onClick: () =>
|
||||
parent?.item?.id &&
|
||||
@@ -235,25 +242,25 @@ export const useOnBuildContextMenu = (children: DriveItem[], initialParentId?: s
|
||||
},
|
||||
{
|
||||
type: 'menu',
|
||||
text: 'Download folder',
|
||||
text: Languages.t('components.item_context_menu.download_folder'),
|
||||
hide: inTrash,
|
||||
onClick: () => downloadZip([parent.item!.id]),
|
||||
},
|
||||
{
|
||||
type: 'menu',
|
||||
text: 'Copy public link',
|
||||
text: Languages.t('components.item_context_menu.copy_link'),
|
||||
hide:
|
||||
!parent?.item?.access_info?.public?.level ||
|
||||
parent?.item?.access_info?.public?.level === 'none',
|
||||
onClick: () => {
|
||||
copyToClipboard(getPublicLink(item || parent?.item));
|
||||
ToasterService.success('Public link copied to clipboard');
|
||||
ToasterService.success(Languages.t('components.item_context_menu.copy_link.success'));
|
||||
},
|
||||
},
|
||||
{ type: 'separator', hide: inTrash || parent.access === 'read' },
|
||||
{
|
||||
type: 'menu',
|
||||
text: 'Go to trash',
|
||||
text: Languages.t('components.item_context_menu.go_to_trash'),
|
||||
hide: inTrash || parent.access === 'read',
|
||||
onClick: () => setParentId('trash'),
|
||||
},
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useEffect, useState } from 'react';
|
||||
import { PublicIcon } from './components/public-icon';
|
||||
import MenusManager from '@components/menus/menus-manager.jsx';
|
||||
import { useCurrentUser } from 'app/features/users/hooks/use-current-user';
|
||||
import Languages from "features/global/services/languages-service";
|
||||
|
||||
export default ({
|
||||
path: livePath,
|
||||
@@ -98,8 +99,8 @@ const PathItem = ({
|
||||
if (first && user?.id) {
|
||||
MenusManager.openMenu(
|
||||
[
|
||||
{ type: 'menu', text: 'Home', onClick: () => onClick('root') },
|
||||
{ type: 'menu', text: 'My Drive', onClick: () => onClick('user_' + user?.id) },
|
||||
{ type: 'menu', text: Languages.t('components.side_menu.home'), onClick: () => onClick('root') },
|
||||
{ type: 'menu', text: Languages.t('components.side_menu.my_drive'), onClick: () => onClick('user_' + user?.id) },
|
||||
],
|
||||
{ x: evt.clientX, y: evt.clientY },
|
||||
'center',
|
||||
|
||||
@@ -5,6 +5,7 @@ import { Button } from '@atoms/button/button';
|
||||
import { Input } from '@atoms/input/input-text';
|
||||
import { Info } from '@atoms/text';
|
||||
import { useDriveActions } from '@features/drive/hooks/use-drive-actions';
|
||||
import Languages from "features/global/services/languages-service";
|
||||
|
||||
export const CreateFolder = () => {
|
||||
const [name, setName] = useState<string>('');
|
||||
@@ -14,11 +15,11 @@ export const CreateFolder = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Info>Choose a name for the new folder.</Info>
|
||||
<Info>{ Languages.t('components.create_folder_modal.hint')}</Info>
|
||||
|
||||
<Input
|
||||
disabled={loading}
|
||||
placeholder="Folder name"
|
||||
placeholder={ Languages.t('components.create_folder_modal.placeholder')}
|
||||
className="w-full mt-4"
|
||||
onChange={(e: any) => setName(e.target.value)}
|
||||
/>
|
||||
|
||||
@@ -6,6 +6,7 @@ import { useState } from 'react';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { CreateModalAtom } from '.';
|
||||
import FileUploadService from 'features/files/services/file-upload-service';
|
||||
import Languages from "features/global/services/languages-service";
|
||||
|
||||
export const CreateLink = () => {
|
||||
const [name, setName] = useState<string>('');
|
||||
@@ -48,11 +49,9 @@ export const CreateLink = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Info>Create a link</Info>
|
||||
|
||||
<Input
|
||||
disabled={loading}
|
||||
placeholder="Link name"
|
||||
placeholder={ Languages.t('components.create_link_modal.hint')}
|
||||
className="w-full mt-4"
|
||||
onChange={e => setName(e.target.value)}
|
||||
/>
|
||||
@@ -73,7 +72,7 @@ export const CreateLink = () => {
|
||||
setState({ ...state, open: false });
|
||||
}}
|
||||
>
|
||||
Create link
|
||||
{ Languages.t('components.create_link_modal.button')}
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -17,6 +17,7 @@ import { atom, useRecoilState } from 'recoil';
|
||||
import { slideXTransition, slideXTransitionReverted } from 'src/utils/transitions';
|
||||
import { CreateFolder } from './create-folder';
|
||||
import { CreateLink } from './create-link';
|
||||
import Languages from "features/global/services/languages-service";
|
||||
|
||||
export type CreateModalAtomType = {
|
||||
open: boolean;
|
||||
@@ -58,7 +59,7 @@ export const CreateModal = ({
|
||||
<ChevronLeftIcon className="w-6 h-6" />
|
||||
</A>
|
||||
)}
|
||||
<span className="ml-2">Create document or folder</span>
|
||||
<span className="ml-2">{Languages.t('components.create_modal.create_folder_or_doc')}</span>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
@@ -80,22 +81,22 @@ export const CreateModal = ({
|
||||
<div className="-m-2">
|
||||
<CreateModalOption
|
||||
icon={<FolderAddIcon className="w-5 h-5" />}
|
||||
text="Create a folder"
|
||||
text={Languages.t('components.create_modal.create_folder')}
|
||||
onClick={() => setState({ ...state, type: 'folder' })}
|
||||
/>
|
||||
<CreateModalOption
|
||||
icon={<DocumentDownloadIcon className="w-5 h-5" />}
|
||||
text="Upload files from device"
|
||||
text={Languages.t('components.create_modal.upload_files')}
|
||||
onClick={() => selectFromDevice()}
|
||||
/>
|
||||
<CreateModalOption
|
||||
icon={<FolderDownloadIcon className="w-5 h-5" />}
|
||||
text="Upload folders from device"
|
||||
text={Languages.t('components.create_modal.upload_folders')}
|
||||
onClick={() => selectFolderFromDevice()}
|
||||
/>
|
||||
<CreateModalOption
|
||||
icon={<LinkIcon className="w-5 h-5" />}
|
||||
text="Create a link file"
|
||||
text={Languages.t('components.create_modal.create_link')}
|
||||
onClick={() => setState({ ...state, type: 'link' })}
|
||||
/>
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ export default ({ sidebar }: { sidebar?: boolean }): JSX.Element => {
|
||||
type: 'menu',
|
||||
icon: 'user',
|
||||
text: Languages.t('scenes.app.channelsbar.currentuser.title'),
|
||||
hide: InitService.server_infos?.configuration?.accounts?.type === 'remote',
|
||||
//hide: InitService.server_infos?.configuration?.accounts?.type === 'remote',
|
||||
onClick: () => {
|
||||
ModalManagerDepreciated.open(<AccountParameter />, true, 'account_parameters');
|
||||
},
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Base, Title } from '@atoms/text';
|
||||
import { useDriveItem } from '@features/drive/hooks/use-drive-item';
|
||||
import { formatBytes } from '@features/drive/utils';
|
||||
import Languages from "features/global/services/languages-service";
|
||||
|
||||
export default () => {
|
||||
const { access, item } = useDriveItem('root');
|
||||
@@ -12,7 +13,7 @@ export default () => {
|
||||
<div className="w-full">
|
||||
<Title>
|
||||
{formatBytes(item?.size || 0)}
|
||||
<Base> used, </Base> <Base>{formatBytes(trash?.size || 0)} in trash</Base>
|
||||
<Base> { Languages.t('components.disk_usage.used')} </Base> <Base>{formatBytes(trash?.size || 0)} {Languages.t('components.disk_usage.in_trash')}</Base>
|
||||
</Title>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -40,7 +40,7 @@ export default (): JSX.Element => {
|
||||
}
|
||||
icon={() => <AdjustmentsIcon className="w-5 h-5 text-zinc-500" />}
|
||||
onClick={() => {
|
||||
ToasterService.info('This feature is coming soon 🚀');
|
||||
ToasterService.info(Languages.t('components.searchpopup.soon'));
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -40,7 +40,7 @@ export default React.memo((): JSX.Element => {
|
||||
page = (
|
||||
<DesktopRedirect>
|
||||
<div className="fade_in bg-zinc-100 dark:bg-black flex flex-col gap-2 h-full">
|
||||
<DownloadAppBanner />
|
||||
<DownloadAppBanner/>
|
||||
<NewVersionComponent />
|
||||
|
||||
<FeatureToggles features={activeFeatureNames}>
|
||||
|
||||
@@ -56,552 +56,32 @@ export default class UserParameter extends Component {
|
||||
open() {
|
||||
this.fileinput.click();
|
||||
}
|
||||
changeThumbnail(event) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
||||
var that = this;
|
||||
event.preventDefault();
|
||||
getFilesTree(event, function (tree) {
|
||||
var first = tree[Object.keys(tree)[0]];
|
||||
if (first.constructor.name !== 'Object') {
|
||||
//A file
|
||||
var reader = new FileReader();
|
||||
reader.onload = function (e) {
|
||||
that.thumbnail.style.backgroundImage = "url('" + e.target.result + "')";
|
||||
};
|
||||
that.setState({ thumbnail: first });
|
||||
reader.readAsDataURL(first);
|
||||
}
|
||||
});
|
||||
}
|
||||
canEditAccount() {
|
||||
return (
|
||||
this.state.currentUserService.get().identity_provider !== 'openid' &&
|
||||
this.state.currentUserService.get().identity_provider !== 'cas'
|
||||
);
|
||||
}
|
||||
|
||||
displayScene() {
|
||||
if (this.state.page === 1) {
|
||||
return (
|
||||
<form className="" autoComplete="off">
|
||||
<div className="title">{this.state.i18n.t('scenes.apps.account.title')}</div>
|
||||
{this.canEditAccount() && (
|
||||
<>
|
||||
{InitService.server_infos?.configuration?.accounts?.type === 'remote' && (
|
||||
<>
|
||||
<Text.Info>{Languages.t('scenes.apps.account.on_console')}</Text.Info>
|
||||
<Button
|
||||
className="mt-4"
|
||||
icon={ExternalLinkIcon}
|
||||
onClick={() =>
|
||||
window.open(InitService.getConsoleLink('account_management_url'), '_blank')
|
||||
}
|
||||
>
|
||||
{Languages.t('scenes.app.popup.workspaceparameter.edit_from_console')}
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
{InitService.server_infos?.configuration?.accounts?.type !== 'remote' && (
|
||||
<>
|
||||
<div className="group_section">
|
||||
<div className="subtitle">
|
||||
{this.state.i18n.t('scenes.apps.account.identity')}
|
||||
</div>
|
||||
|
||||
<Attribute
|
||||
label={this.state.i18n.t('scenes.apps.account.identity')}
|
||||
description={this.state.i18n.t('scenes.apps.account.identity.description')}
|
||||
<div className="group_section">
|
||||
<Attribute
|
||||
label={this.state.i18n.t('scenes.apps.account.languages.menu_title')}
|
||||
description={this.state.i18n.t('scenes.apps.account.languages.text')}
|
||||
>
|
||||
<div className="parameters_form">
|
||||
<select
|
||||
value={this.state.i18n.language}
|
||||
onChange={ev => currentUserService.updateLanguage(ev.target.value)}
|
||||
>
|
||||
<div
|
||||
className="parameters_form thumbnail_container"
|
||||
style={{ paddingTop: 16 }}
|
||||
>
|
||||
<div
|
||||
onClick={() => {
|
||||
this.fileinput.click();
|
||||
}}
|
||||
>
|
||||
<input
|
||||
ref={node => (this.fileinput = node)}
|
||||
type="file"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: '-10000px',
|
||||
left: '-10000px',
|
||||
width: '100px',
|
||||
}}
|
||||
onChange={e => this.changeThumbnail(e)}
|
||||
/>
|
||||
<div
|
||||
ref={ref => (this.thumbnail = ref)}
|
||||
className="thumbnail"
|
||||
style={{
|
||||
'background-image':
|
||||
"url('" +
|
||||
userService.getThumbnail(
|
||||
Collections.get('users').find(userService.getCurrentUserId()),
|
||||
) +
|
||||
"')",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="smalltext">
|
||||
{this.state.i18n.t('scenes.apps.account.thumbnail.max_weight')}
|
||||
<br />
|
||||
<a
|
||||
className="red"
|
||||
href="#"
|
||||
onClick={() => {
|
||||
this.setState({ thumbnail: 'null' });
|
||||
currentUserService.updateidentity(
|
||||
this.state.last_name,
|
||||
this.state.first_name,
|
||||
'null',
|
||||
);
|
||||
}}
|
||||
>
|
||||
{this.state.i18n.t('general.remove')}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="parameters_form" style={{ paddingTop: 16 }}>
|
||||
<Input
|
||||
placeholder={this.state.i18n.t('scenes.apps.account.account.first_name')}
|
||||
className={
|
||||
'name ' +
|
||||
(this.state.currentUserService.errorUsernameExist ? 'error' : '')
|
||||
}
|
||||
type="text"
|
||||
value={this.state.first_name}
|
||||
onKeyDown={e => {
|
||||
if (e.keyCode === 13) {
|
||||
currentUserService.updateidentity(
|
||||
this.state.last_name,
|
||||
this.state.first_name,
|
||||
this.state.thumbnail,
|
||||
);
|
||||
}
|
||||
}}
|
||||
onChange={ev => this.setState({ first_name: ev.target.value })}
|
||||
/>
|
||||
<Input
|
||||
placeholder={this.state.i18n.t('scenes.apps.account.account.last_name')}
|
||||
className={
|
||||
'name ' +
|
||||
(this.state.currentUserService.errorUsernameExist ? 'error' : '')
|
||||
}
|
||||
type="text"
|
||||
value={this.state.last_name}
|
||||
onKeyDown={e => {
|
||||
if (e.keyCode === 13) {
|
||||
currentUserService.updateidentity(
|
||||
this.state.last_name,
|
||||
this.state.first_name,
|
||||
this.state.thumbnail,
|
||||
);
|
||||
}
|
||||
}}
|
||||
onChange={ev => this.setState({ last_name: ev.target.value })}
|
||||
/>
|
||||
<ButtonWithTimeout
|
||||
href="#"
|
||||
className="small buttonValidation"
|
||||
disabled={this.state.currentUserService.loading}
|
||||
onClick={() =>
|
||||
currentUserService.updateidentity(
|
||||
this.state.last_name,
|
||||
this.state.first_name,
|
||||
this.state.thumbnail,
|
||||
)
|
||||
}
|
||||
loading={this.state.currentUserService.loading}
|
||||
value={this.state.i18n.t('general.update')}
|
||||
/>
|
||||
</div>
|
||||
</Attribute>
|
||||
<option value="en">English</option>
|
||||
<option value="fr">Français</option>
|
||||
<option value="ru">Русский</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className="group_section">
|
||||
<div className="subtitle">
|
||||
{this.state.i18n.t('scenes.apps.account.preference')}
|
||||
</div>
|
||||
|
||||
<Attribute
|
||||
label={this.state.i18n.t('scenes.apps.account.languages.menu_title')}
|
||||
description={this.state.i18n.t('scenes.apps.account.languages.text')}
|
||||
>
|
||||
<div className="parameters_form">
|
||||
<select
|
||||
value={this.state.i18n.language}
|
||||
onChange={ev => Languages.setLanguage(ev.target.value)}
|
||||
>
|
||||
<option value="de">Deutsch</option>
|
||||
<option value="es">Español</option>
|
||||
<option value="en">English</option>
|
||||
<option value="fr">Français</option>
|
||||
<option value="ja">日本語</option>
|
||||
<option value="ru">Русский</option>
|
||||
</select>
|
||||
</div>
|
||||
</Attribute>
|
||||
</div>
|
||||
|
||||
<div className="group_section">
|
||||
<div className="subtitle">
|
||||
{this.state.i18n.t('scenes.apps.account.account.menu_title')}
|
||||
</div>
|
||||
|
||||
<Attribute
|
||||
label={this.state.i18n.t('scenes.apps.account.account.username')}
|
||||
description={this.state.i18n.t('scenes.apps.account.account.change_username')}
|
||||
>
|
||||
<div className="parameters_form">
|
||||
<Input
|
||||
className={
|
||||
this.state.currentUserService.errorUsernameExist ? 'error' : ''
|
||||
}
|
||||
type="text"
|
||||
value={this.state.username}
|
||||
onKeyDown={e => {
|
||||
if (e.keyCode === 13) {
|
||||
currentUserService.updateUserName(this.state.username);
|
||||
}
|
||||
}}
|
||||
onChange={ev => this.setState({ username: ev.target.value })}
|
||||
/>
|
||||
|
||||
{this.state.currentUserService.errorUsernameExist && (
|
||||
<span className="text error">
|
||||
{this.state.i18n.t(
|
||||
'scenes.login.create_account.username_already_exist',
|
||||
)}
|
||||
</span>
|
||||
)}
|
||||
|
||||
<ButtonWithTimeout
|
||||
href="#"
|
||||
className="small buttonValidation"
|
||||
disabled={this.state.currentUserService.loading}
|
||||
onClick={() => currentUserService.updateUserName(this.state.username)}
|
||||
loading={this.state.currentUserService.loading}
|
||||
value={this.state.i18n.t('general.update')}
|
||||
/>
|
||||
</div>
|
||||
</Attribute>
|
||||
|
||||
<Attribute
|
||||
label={this.state.i18n.t('scenes.apps.account.account.emails')}
|
||||
description={this.state.i18n.t(
|
||||
'scenes.apps.account.account.emails.description',
|
||||
)}
|
||||
>
|
||||
<div className="parameters_form mails_container">
|
||||
{(
|
||||
Collections.get('users').find(userService.getCurrentUserId()).mails || []
|
||||
).map(mail => {
|
||||
return (
|
||||
<div className="mail">
|
||||
<div className="address">{mail.email}</div>
|
||||
{mail.main && (
|
||||
<div className="main_mail">
|
||||
{this.state.i18n.t('scenes.apps.account.account.main_email')}
|
||||
</div>
|
||||
)}
|
||||
{!mail.main && (
|
||||
// eslint-disable-next-line jsx-a11y/anchor-is-valid
|
||||
<a
|
||||
className={currentUserService.loading ? 'isDisabled' : ''}
|
||||
onClick={() => currentUserService.makeMainMail(mail.id)}
|
||||
>
|
||||
{this.state.i18n.t('scenes.apps.account.account.make_main')}
|
||||
</a>
|
||||
)}
|
||||
{!mail.main && (
|
||||
// eslint-disable-next-line jsx-a11y/anchor-is-valid
|
||||
<a
|
||||
className={
|
||||
'red ' + (currentUserService.loading ? 'isDisabled' : '')
|
||||
}
|
||||
onClick={() => currentUserService.removeMail(mail.id)}
|
||||
>
|
||||
{this.state.i18n.t('general.remove')}
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
||||
{this.state.subMenuOpened < 1 && (
|
||||
// eslint-disable-next-line jsx-a11y/anchor-is-valid
|
||||
<a href="#" onClick={() => this.setState({ subMenuOpened: 1 })}>
|
||||
{this.state.i18n.t(
|
||||
'scenes.app.workspaces.welcome_page.add_secondary_emails',
|
||||
)}
|
||||
</a>
|
||||
)}
|
||||
|
||||
{this.state.subMenuOpened >= 1 && (
|
||||
<div className="parameters_form new_secondary_mail">
|
||||
<Input
|
||||
disabled={this.state.subMenuOpened === 2}
|
||||
className={
|
||||
'new_mail_input' +
|
||||
(this.state.subMenuOpened === 1 &&
|
||||
this.state.loginService.error_secondary_mail_already
|
||||
? 'error'
|
||||
: '')
|
||||
}
|
||||
type="text"
|
||||
onKeyDown={e => {
|
||||
if (e.keyCode === 13 && this.state.mail.length > 0) {
|
||||
this.state.loginService.addNewMail(
|
||||
this.state.mail,
|
||||
thot => thot.setState({ subMenuOpened: 2 }),
|
||||
this,
|
||||
);
|
||||
}
|
||||
}}
|
||||
placeholder={this.state.i18n.t(
|
||||
'scenes.app.workspaces.welcome_page.new_email',
|
||||
)}
|
||||
value={this.state.mail}
|
||||
onChange={evt => this.setState({ mail: evt.target.value })}
|
||||
/>
|
||||
{this.state.subMenuOpened === 1 &&
|
||||
this.state.loginService.error_secondary_mail_already && (
|
||||
<span id="errorUsernameExist" className={'text error'}>
|
||||
{this.state.i18n.t('scenes.login.create_account.email_used')}
|
||||
</span>
|
||||
)}
|
||||
|
||||
{this.state.subMenuOpened === 2 && (
|
||||
<Input
|
||||
type="text"
|
||||
onKeyDown={e => {
|
||||
if (e.keyCode === 13 && this.state.code.length > 0) {
|
||||
this.state.loginService.verifySecondMail(
|
||||
this.state.mail,
|
||||
this.state.code,
|
||||
thot => {
|
||||
thot.setState({ subMenuOpened: 0, mail: '', code: '' });
|
||||
},
|
||||
this,
|
||||
);
|
||||
}
|
||||
}}
|
||||
placeholder={'123-456-789'}
|
||||
onChange={evt => this.setState({ code: evt.target.value })}
|
||||
className={
|
||||
'new_mail_input_code' +
|
||||
(this.state.loginService.error_code || this.state.error_code
|
||||
? 'error'
|
||||
: '')
|
||||
}
|
||||
style={{ maxWidth: '200px', textAlign: 'center', marginTop: 10 }}
|
||||
/>
|
||||
)}
|
||||
{this.state.subMenuOpened === 2 &&
|
||||
(this.state.loginService.error_code || this.state.error_code) && (
|
||||
<span
|
||||
id="errorUsernameExist"
|
||||
className={'text error'}
|
||||
style={{ display: 'block' }}
|
||||
>
|
||||
{this.state.i18n.t(
|
||||
'scenes.apps.account.account.email_add_modal.invalid_code',
|
||||
)}
|
||||
</span>
|
||||
)}
|
||||
|
||||
{this.state.subMenuOpened === 1 && (
|
||||
<div className="form_bottom">
|
||||
<a
|
||||
href="#"
|
||||
className="cancel"
|
||||
onClick={() => this.setState({ subMenuOpened: 0 })}
|
||||
>
|
||||
{this.state.i18n.t('general.cancel')}
|
||||
</a>
|
||||
<ButtonWithTimeout
|
||||
href="#"
|
||||
className="small buttonValidation"
|
||||
disabled={this.state.loginService.loading}
|
||||
onClick={() =>
|
||||
this.state.loginService.addNewMail(
|
||||
this.state.mail,
|
||||
thot => thot.setState({ subMenuOpened: 2 }),
|
||||
this,
|
||||
)
|
||||
}
|
||||
value={this.state.i18n.t(
|
||||
'scenes.app.workspaces.welcome_page.add_new_email',
|
||||
)}
|
||||
loading={this.state.loginService.loading}
|
||||
loadingTimeout={1500}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{this.state.subMenuOpened === 2 && (
|
||||
<div className="form_bottom">
|
||||
<a
|
||||
href="#"
|
||||
className="cancel"
|
||||
onClick={() => this.setState({ subMenuOpened: 0 })}
|
||||
>
|
||||
{this.state.i18n.t('general.cancel')}
|
||||
</a>
|
||||
<ButtonWithTimeout
|
||||
href="#"
|
||||
className="small buttonValidation"
|
||||
disabled={this.state.loginService.loading}
|
||||
onClick={() =>
|
||||
this.state.loginService.verifySecondMail(
|
||||
this.state.mail,
|
||||
this.state.code,
|
||||
thot => {
|
||||
thot.setState({ subMenuOpened: 0, mail: '', code: '' });
|
||||
},
|
||||
this,
|
||||
)
|
||||
}
|
||||
value={this.state.i18n.t(
|
||||
'scenes.apps.account.account.email_add_modal.confirm',
|
||||
)}
|
||||
loading={this.state.loginService.loading}
|
||||
loadingTimeout={1500}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<span className="smalltext">
|
||||
{this.state.i18n.t('scenes.apps.account.account.description_main')}
|
||||
</span>
|
||||
</div>
|
||||
</Attribute>
|
||||
|
||||
<Attribute
|
||||
label={this.state.i18n.t('scenes.apps.account.account.password')}
|
||||
description={this.state.i18n.t(
|
||||
'scenes.apps.account.account.password.description',
|
||||
)}
|
||||
>
|
||||
<div className="parameters_form">
|
||||
<Input
|
||||
disabled={this.state.currentUserService.loading}
|
||||
placeholder={this.state.i18n.t(
|
||||
'scenes.apps.account.account.password_modal.old_password',
|
||||
)}
|
||||
className={this.state.currentUserService.badOldPassword ? 'error' : ''}
|
||||
type="password"
|
||||
value={this.state.oldPassword}
|
||||
onKeyDown={e => {
|
||||
if (e.keyCode === 13) {
|
||||
currentUserService.updatePassword(
|
||||
this.state.oldPassword,
|
||||
this.state.password,
|
||||
this.state.password1,
|
||||
);
|
||||
}
|
||||
}}
|
||||
onChange={ev => this.setState({ oldPassword: ev.target.value })}
|
||||
/>
|
||||
{this.state.currentUserService.badOldPassword && (
|
||||
<span className="text error">
|
||||
{this.state.i18n.t(
|
||||
'scenes.apps.account.account.password_modal.bad_old_password',
|
||||
)}
|
||||
</span>
|
||||
)}
|
||||
|
||||
<Input
|
||||
disabled={this.state.currentUserService.loading}
|
||||
placeholder={this.state.i18n.t(
|
||||
'scenes.apps.account.account.password_modal.password',
|
||||
)}
|
||||
className={this.state.currentUserService.badNewPassword ? 'error' : ''}
|
||||
type="password"
|
||||
value={this.state.password}
|
||||
onKeyDown={e => {
|
||||
if (e.keyCode === 13) {
|
||||
currentUserService.updatePassword(
|
||||
this.state.oldPassword,
|
||||
this.state.password,
|
||||
this.state.password1,
|
||||
);
|
||||
}
|
||||
}}
|
||||
onChange={ev => this.setState({ password: ev.target.value })}
|
||||
/>
|
||||
|
||||
<Input
|
||||
disabled={this.state.currentUserService.loading}
|
||||
placeholder={this.state.i18n.t(
|
||||
'scenes.apps.account.account.password_modal.password',
|
||||
)}
|
||||
className={this.state.currentUserService.badNewPassword ? 'error' : ''}
|
||||
type="password"
|
||||
value={this.state.password1}
|
||||
onKeyDown={e => {
|
||||
if (e.keyCode === 13) {
|
||||
currentUserService.updatePassword(
|
||||
this.state.oldPassword,
|
||||
this.state.password,
|
||||
this.state.password1,
|
||||
);
|
||||
}
|
||||
}}
|
||||
onChange={ev => this.setState({ password1: ev.target.value })}
|
||||
/>
|
||||
{this.state.currentUserService.badNewPassword && (
|
||||
<span className="text error">
|
||||
{this.state.i18n.t(
|
||||
'scenes.apps.account.account.password_modal.bad_password',
|
||||
)}
|
||||
</span>
|
||||
)}
|
||||
|
||||
<ButtonWithTimeout
|
||||
href="#"
|
||||
className="small buttonValidation"
|
||||
disabled={this.state.currentUserService.loading}
|
||||
onClick={() =>
|
||||
currentUserService.updatePassword(
|
||||
this.state.oldPassword,
|
||||
this.state.password,
|
||||
this.state.password1,
|
||||
)
|
||||
}
|
||||
loading={this.state.currentUserService.loading}
|
||||
value={this.state.i18n.t('general.update')}
|
||||
/>
|
||||
</div>
|
||||
</Attribute>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</Attribute>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
if (this.state.page === 2) {
|
||||
return (
|
||||
<div className="">
|
||||
<div className="title">
|
||||
{Languages.t(
|
||||
'scenes.app.popup.userparameter.personnal_workspaces_title',
|
||||
[],
|
||||
'Vos espaces de travail',
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="group_section" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
setPage(page) {
|
||||
@@ -618,7 +98,6 @@ export default class UserParameter extends Component {
|
||||
{
|
||||
type: 'menu',
|
||||
text: this.state.i18n.t('scenes.apps.account.title'),
|
||||
emoji: ':dark_sunglasses:',
|
||||
selected: this.state.page === 1 ? 'selected' : '',
|
||||
onClick: () => {
|
||||
this.setPage(1);
|
||||
|
||||
+635
@@ -0,0 +1,635 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
/* eslint-disable react/jsx-key */
|
||||
import { Component } from 'react';
|
||||
|
||||
import { getFilesTree } from '@components/uploads/file-tree-utils';
|
||||
import Collections from '@deprecated/CollectionsV1/Collections/Collections.js';
|
||||
import popupManager from '@deprecated/popupManager/popupManager.js';
|
||||
import currentUserService from '@deprecated/user/CurrentUser';
|
||||
import LoginService from '@features/auth/login-service';
|
||||
import InitService from '@features/global/services/init-service';
|
||||
import Languages from '@features/global/services/languages-service';
|
||||
import userService from '@features/users/services/current-user-service';
|
||||
import { ExternalLinkIcon } from '@heroicons/react/outline';
|
||||
import ButtonWithTimeout from 'components/buttons/button-with-timeout.jsx';
|
||||
import Input from 'components/inputs/input.jsx';
|
||||
import MenuList from 'components/menus/menu-component.jsx';
|
||||
import Attribute from 'components/parameters/attribute.tsx';
|
||||
import { Button } from '../../../../atoms/button/button';
|
||||
import * as Text from '../../../../atoms/text';
|
||||
import './UserParameter.scss';
|
||||
|
||||
export default class UserParameter extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
var user = Collections.get('users').find(userService.getCurrentUserId());
|
||||
this.state = {
|
||||
login: LoginService,
|
||||
i18n: Languages,
|
||||
users_repository: Collections.get('users'),
|
||||
currentUserService: currentUserService,
|
||||
page: popupManager.popupStates['user_parameters'] || props.defaultPage || 1,
|
||||
attributeOpen: 0,
|
||||
subMenuOpened: 0,
|
||||
username: user ? user.username : '',
|
||||
last_name: user ? user.last_name : '',
|
||||
first_name: user ? user.first_name : '',
|
||||
thumbnail: false,
|
||||
};
|
||||
Collections.get('users').addListener(this);
|
||||
Collections.get('users').listenOnly(this, [
|
||||
Collections.get('users').find(userService.getCurrentUserId()).front_id,
|
||||
]);
|
||||
LoginService.addListener(this);
|
||||
Languages.addListener(this);
|
||||
currentUserService.addListener(this);
|
||||
}
|
||||
UNSAFE_componentWillMount() {
|
||||
this.setState({ thumbnail: false });
|
||||
}
|
||||
componentWillUnmount() {
|
||||
LoginService.removeListener(this);
|
||||
Languages.removeListener(this);
|
||||
currentUserService.removeListener(this);
|
||||
Collections.get('users').removeListener(this);
|
||||
}
|
||||
open() {
|
||||
this.fileinput.click();
|
||||
}
|
||||
changeThumbnail(event) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
||||
var that = this;
|
||||
event.preventDefault();
|
||||
getFilesTree(event, function (tree) {
|
||||
var first = tree[Object.keys(tree)[0]];
|
||||
if (first.constructor.name !== 'Object') {
|
||||
//A file
|
||||
var reader = new FileReader();
|
||||
reader.onload = function (e) {
|
||||
that.thumbnail.style.backgroundImage = "url('" + e.target.result + "')";
|
||||
};
|
||||
that.setState({ thumbnail: first });
|
||||
reader.readAsDataURL(first);
|
||||
}
|
||||
});
|
||||
}
|
||||
canEditAccount() {
|
||||
return (
|
||||
this.state.currentUserService.get().identity_provider !== 'openid' &&
|
||||
this.state.currentUserService.get().identity_provider !== 'cas'
|
||||
);
|
||||
}
|
||||
displayScene() {
|
||||
if (this.state.page === 1) {
|
||||
return (
|
||||
<form className="" autoComplete="off">
|
||||
<div className="title">{this.state.i18n.t('scenes.apps.account.title')}</div>
|
||||
{this.canEditAccount() && (
|
||||
<>
|
||||
{InitService.server_infos?.configuration?.accounts?.type === 'remote' && (
|
||||
<>
|
||||
<Text.Info>{Languages.t('scenes.apps.account.on_console')}</Text.Info>
|
||||
<Button
|
||||
className="mt-4"
|
||||
icon={ExternalLinkIcon}
|
||||
onClick={() =>
|
||||
window.open(InitService.getConsoleLink('account_management_url'), '_blank')
|
||||
}
|
||||
>
|
||||
{Languages.t('scenes.app.popup.workspaceparameter.edit_from_console')}
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
{InitService.server_infos?.configuration?.accounts?.type !== 'remote' && (
|
||||
<>
|
||||
<div className="group_section">
|
||||
<div className="subtitle">
|
||||
{this.state.i18n.t('scenes.apps.account.identity')}
|
||||
</div>
|
||||
|
||||
<Attribute
|
||||
label={this.state.i18n.t('scenes.apps.account.identity')}
|
||||
description={this.state.i18n.t('scenes.apps.account.identity.description')}
|
||||
>
|
||||
<div
|
||||
className="parameters_form thumbnail_container"
|
||||
style={{ paddingTop: 16 }}
|
||||
>
|
||||
<div
|
||||
onClick={() => {
|
||||
this.fileinput.click();
|
||||
}}
|
||||
>
|
||||
<input
|
||||
ref={node => (this.fileinput = node)}
|
||||
type="file"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: '-10000px',
|
||||
left: '-10000px',
|
||||
width: '100px',
|
||||
}}
|
||||
onChange={e => this.changeThumbnail(e)}
|
||||
/>
|
||||
<div
|
||||
ref={ref => (this.thumbnail = ref)}
|
||||
className="thumbnail"
|
||||
style={{
|
||||
'background-image':
|
||||
"url('" +
|
||||
userService.getThumbnail(
|
||||
Collections.get('users').find(userService.getCurrentUserId()),
|
||||
) +
|
||||
"')",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="smalltext">
|
||||
{this.state.i18n.t('scenes.apps.account.thumbnail.max_weight')}
|
||||
<br />
|
||||
<a
|
||||
className="red"
|
||||
href="#"
|
||||
onClick={() => {
|
||||
this.setState({ thumbnail: 'null' });
|
||||
currentUserService.updateidentity(
|
||||
this.state.last_name,
|
||||
this.state.first_name,
|
||||
'null',
|
||||
);
|
||||
}}
|
||||
>
|
||||
{this.state.i18n.t('general.remove')}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="parameters_form" style={{ paddingTop: 16 }}>
|
||||
<Input
|
||||
placeholder={this.state.i18n.t('scenes.apps.account.account.first_name')}
|
||||
className={
|
||||
'name ' +
|
||||
(this.state.currentUserService.errorUsernameExist ? 'error' : '')
|
||||
}
|
||||
type="text"
|
||||
value={this.state.first_name}
|
||||
onKeyDown={e => {
|
||||
if (e.keyCode === 13) {
|
||||
currentUserService.updateidentity(
|
||||
this.state.last_name,
|
||||
this.state.first_name,
|
||||
this.state.thumbnail,
|
||||
);
|
||||
}
|
||||
}}
|
||||
onChange={ev => this.setState({ first_name: ev.target.value })}
|
||||
/>
|
||||
<Input
|
||||
placeholder={this.state.i18n.t('scenes.apps.account.account.last_name')}
|
||||
className={
|
||||
'name ' +
|
||||
(this.state.currentUserService.errorUsernameExist ? 'error' : '')
|
||||
}
|
||||
type="text"
|
||||
value={this.state.last_name}
|
||||
onKeyDown={e => {
|
||||
if (e.keyCode === 13) {
|
||||
currentUserService.updateidentity(
|
||||
this.state.last_name,
|
||||
this.state.first_name,
|
||||
this.state.thumbnail,
|
||||
);
|
||||
}
|
||||
}}
|
||||
onChange={ev => this.setState({ last_name: ev.target.value })}
|
||||
/>
|
||||
<ButtonWithTimeout
|
||||
href="#"
|
||||
className="small buttonValidation"
|
||||
disabled={this.state.currentUserService.loading}
|
||||
onClick={() =>
|
||||
currentUserService.updateidentity(
|
||||
this.state.last_name,
|
||||
this.state.first_name,
|
||||
this.state.thumbnail,
|
||||
)
|
||||
}
|
||||
loading={this.state.currentUserService.loading}
|
||||
value={this.state.i18n.t('general.update')}
|
||||
/>
|
||||
</div>
|
||||
</Attribute>
|
||||
</div>
|
||||
|
||||
<div className="group_section">
|
||||
<div className="subtitle">
|
||||
{this.state.i18n.t('scenes.apps.account.preference')}
|
||||
</div>
|
||||
|
||||
<Attribute
|
||||
label={this.state.i18n.t('scenes.apps.account.languages.menu_title')}
|
||||
description={this.state.i18n.t('scenes.apps.account.languages.text')}
|
||||
>
|
||||
<div className="parameters_form">
|
||||
<select
|
||||
value={this.state.i18n.language}
|
||||
onChange={ev => Languages.setLanguage(ev.target.value)}
|
||||
>
|
||||
<option value="de">Deutsch</option>
|
||||
<option value="es">Español</option>
|
||||
<option value="en">English</option>
|
||||
<option value="fr">Français</option>
|
||||
<option value="ja">日本語</option>
|
||||
<option value="ru">Русский</option>
|
||||
</select>
|
||||
</div>
|
||||
</Attribute>
|
||||
</div>
|
||||
|
||||
<div className="group_section">
|
||||
<div className="subtitle">
|
||||
{this.state.i18n.t('scenes.apps.account.account.menu_title')}
|
||||
</div>
|
||||
|
||||
<Attribute
|
||||
label={this.state.i18n.t('scenes.apps.account.account.username')}
|
||||
description={this.state.i18n.t('scenes.apps.account.account.change_username')}
|
||||
>
|
||||
<div className="parameters_form">
|
||||
<Input
|
||||
className={
|
||||
this.state.currentUserService.errorUsernameExist ? 'error' : ''
|
||||
}
|
||||
type="text"
|
||||
value={this.state.username}
|
||||
onKeyDown={e => {
|
||||
if (e.keyCode === 13) {
|
||||
currentUserService.updateUserName(this.state.username);
|
||||
}
|
||||
}}
|
||||
onChange={ev => this.setState({ username: ev.target.value })}
|
||||
/>
|
||||
|
||||
{this.state.currentUserService.errorUsernameExist && (
|
||||
<span className="text error">
|
||||
{this.state.i18n.t(
|
||||
'scenes.login.create_account.username_already_exist',
|
||||
)}
|
||||
</span>
|
||||
)}
|
||||
|
||||
<ButtonWithTimeout
|
||||
href="#"
|
||||
className="small buttonValidation"
|
||||
disabled={this.state.currentUserService.loading}
|
||||
onClick={() => currentUserService.updateUserName(this.state.username)}
|
||||
loading={this.state.currentUserService.loading}
|
||||
value={this.state.i18n.t('general.update')}
|
||||
/>
|
||||
</div>
|
||||
</Attribute>
|
||||
|
||||
<Attribute
|
||||
label={this.state.i18n.t('scenes.apps.account.account.emails')}
|
||||
description={this.state.i18n.t(
|
||||
'scenes.apps.account.account.emails.description',
|
||||
)}
|
||||
>
|
||||
<div className="parameters_form mails_container">
|
||||
{(
|
||||
Collections.get('users').find(userService.getCurrentUserId()).mails || []
|
||||
).map(mail => {
|
||||
return (
|
||||
<div className="mail">
|
||||
<div className="address">{mail.email}</div>
|
||||
{mail.main && (
|
||||
<div className="main_mail">
|
||||
{this.state.i18n.t('scenes.apps.account.account.main_email')}
|
||||
</div>
|
||||
)}
|
||||
{!mail.main && (
|
||||
// eslint-disable-next-line jsx-a11y/anchor-is-valid
|
||||
<a
|
||||
className={currentUserService.loading ? 'isDisabled' : ''}
|
||||
onClick={() => currentUserService.makeMainMail(mail.id)}
|
||||
>
|
||||
{this.state.i18n.t('scenes.apps.account.account.make_main')}
|
||||
</a>
|
||||
)}
|
||||
{!mail.main && (
|
||||
// eslint-disable-next-line jsx-a11y/anchor-is-valid
|
||||
<a
|
||||
className={
|
||||
'red ' + (currentUserService.loading ? 'isDisabled' : '')
|
||||
}
|
||||
onClick={() => currentUserService.removeMail(mail.id)}
|
||||
>
|
||||
{this.state.i18n.t('general.remove')}
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
||||
{this.state.subMenuOpened < 1 && (
|
||||
// eslint-disable-next-line jsx-a11y/anchor-is-valid
|
||||
<a href="#" onClick={() => this.setState({ subMenuOpened: 1 })}>
|
||||
{this.state.i18n.t(
|
||||
'scenes.app.workspaces.welcome_page.add_secondary_emails',
|
||||
)}
|
||||
</a>
|
||||
)}
|
||||
|
||||
{this.state.subMenuOpened >= 1 && (
|
||||
<div className="parameters_form new_secondary_mail">
|
||||
<Input
|
||||
disabled={this.state.subMenuOpened === 2}
|
||||
className={
|
||||
'new_mail_input' +
|
||||
(this.state.subMenuOpened === 1 &&
|
||||
this.state.loginService.error_secondary_mail_already
|
||||
? 'error'
|
||||
: '')
|
||||
}
|
||||
type="text"
|
||||
onKeyDown={e => {
|
||||
if (e.keyCode === 13 && this.state.mail.length > 0) {
|
||||
this.state.loginService.addNewMail(
|
||||
this.state.mail,
|
||||
thot => thot.setState({ subMenuOpened: 2 }),
|
||||
this,
|
||||
);
|
||||
}
|
||||
}}
|
||||
placeholder={this.state.i18n.t(
|
||||
'scenes.app.workspaces.welcome_page.new_email',
|
||||
)}
|
||||
value={this.state.mail}
|
||||
onChange={evt => this.setState({ mail: evt.target.value })}
|
||||
/>
|
||||
{this.state.subMenuOpened === 1 &&
|
||||
this.state.loginService.error_secondary_mail_already && (
|
||||
<span id="errorUsernameExist" className={'text error'}>
|
||||
{this.state.i18n.t('scenes.login.create_account.email_used')}
|
||||
</span>
|
||||
)}
|
||||
|
||||
{this.state.subMenuOpened === 2 && (
|
||||
<Input
|
||||
type="text"
|
||||
onKeyDown={e => {
|
||||
if (e.keyCode === 13 && this.state.code.length > 0) {
|
||||
this.state.loginService.verifySecondMail(
|
||||
this.state.mail,
|
||||
this.state.code,
|
||||
thot => {
|
||||
thot.setState({ subMenuOpened: 0, mail: '', code: '' });
|
||||
},
|
||||
this,
|
||||
);
|
||||
}
|
||||
}}
|
||||
placeholder={'123-456-789'}
|
||||
onChange={evt => this.setState({ code: evt.target.value })}
|
||||
className={
|
||||
'new_mail_input_code' +
|
||||
(this.state.loginService.error_code || this.state.error_code
|
||||
? 'error'
|
||||
: '')
|
||||
}
|
||||
style={{ maxWidth: '200px', textAlign: 'center', marginTop: 10 }}
|
||||
/>
|
||||
)}
|
||||
{this.state.subMenuOpened === 2 &&
|
||||
(this.state.loginService.error_code || this.state.error_code) && (
|
||||
<span
|
||||
id="errorUsernameExist"
|
||||
className={'text error'}
|
||||
style={{ display: 'block' }}
|
||||
>
|
||||
{this.state.i18n.t(
|
||||
'scenes.apps.account.account.email_add_modal.invalid_code',
|
||||
)}
|
||||
</span>
|
||||
)}
|
||||
|
||||
{this.state.subMenuOpened === 1 && (
|
||||
<div className="form_bottom">
|
||||
<a
|
||||
href="#"
|
||||
className="cancel"
|
||||
onClick={() => this.setState({ subMenuOpened: 0 })}
|
||||
>
|
||||
{this.state.i18n.t('general.cancel')}
|
||||
</a>
|
||||
<ButtonWithTimeout
|
||||
href="#"
|
||||
className="small buttonValidation"
|
||||
disabled={this.state.loginService.loading}
|
||||
onClick={() =>
|
||||
this.state.loginService.addNewMail(
|
||||
this.state.mail,
|
||||
thot => thot.setState({ subMenuOpened: 2 }),
|
||||
this,
|
||||
)
|
||||
}
|
||||
value={this.state.i18n.t(
|
||||
'scenes.app.workspaces.welcome_page.add_new_email',
|
||||
)}
|
||||
loading={this.state.loginService.loading}
|
||||
loadingTimeout={1500}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{this.state.subMenuOpened === 2 && (
|
||||
<div className="form_bottom">
|
||||
<a
|
||||
href="#"
|
||||
className="cancel"
|
||||
onClick={() => this.setState({ subMenuOpened: 0 })}
|
||||
>
|
||||
{this.state.i18n.t('general.cancel')}
|
||||
</a>
|
||||
<ButtonWithTimeout
|
||||
href="#"
|
||||
className="small buttonValidation"
|
||||
disabled={this.state.loginService.loading}
|
||||
onClick={() =>
|
||||
this.state.loginService.verifySecondMail(
|
||||
this.state.mail,
|
||||
this.state.code,
|
||||
thot => {
|
||||
thot.setState({ subMenuOpened: 0, mail: '', code: '' });
|
||||
},
|
||||
this,
|
||||
)
|
||||
}
|
||||
value={this.state.i18n.t(
|
||||
'scenes.apps.account.account.email_add_modal.confirm',
|
||||
)}
|
||||
loading={this.state.loginService.loading}
|
||||
loadingTimeout={1500}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<span className="smalltext">
|
||||
{this.state.i18n.t('scenes.apps.account.account.description_main')}
|
||||
</span>
|
||||
</div>
|
||||
</Attribute>
|
||||
|
||||
<Attribute
|
||||
label={this.state.i18n.t('scenes.apps.account.account.password')}
|
||||
description={this.state.i18n.t(
|
||||
'scenes.apps.account.account.password.description',
|
||||
)}
|
||||
>
|
||||
<div className="parameters_form">
|
||||
<Input
|
||||
disabled={this.state.currentUserService.loading}
|
||||
placeholder={this.state.i18n.t(
|
||||
'scenes.apps.account.account.password_modal.old_password',
|
||||
)}
|
||||
className={this.state.currentUserService.badOldPassword ? 'error' : ''}
|
||||
type="password"
|
||||
value={this.state.oldPassword}
|
||||
onKeyDown={e => {
|
||||
if (e.keyCode === 13) {
|
||||
currentUserService.updatePassword(
|
||||
this.state.oldPassword,
|
||||
this.state.password,
|
||||
this.state.password1,
|
||||
);
|
||||
}
|
||||
}}
|
||||
onChange={ev => this.setState({ oldPassword: ev.target.value })}
|
||||
/>
|
||||
{this.state.currentUserService.badOldPassword && (
|
||||
<span className="text error">
|
||||
{this.state.i18n.t(
|
||||
'scenes.apps.account.account.password_modal.bad_old_password',
|
||||
)}
|
||||
</span>
|
||||
)}
|
||||
|
||||
<Input
|
||||
disabled={this.state.currentUserService.loading}
|
||||
placeholder={this.state.i18n.t(
|
||||
'scenes.apps.account.account.password_modal.password',
|
||||
)}
|
||||
className={this.state.currentUserService.badNewPassword ? 'error' : ''}
|
||||
type="password"
|
||||
value={this.state.password}
|
||||
onKeyDown={e => {
|
||||
if (e.keyCode === 13) {
|
||||
currentUserService.updatePassword(
|
||||
this.state.oldPassword,
|
||||
this.state.password,
|
||||
this.state.password1,
|
||||
);
|
||||
}
|
||||
}}
|
||||
onChange={ev => this.setState({ password: ev.target.value })}
|
||||
/>
|
||||
|
||||
<Input
|
||||
disabled={this.state.currentUserService.loading}
|
||||
placeholder={this.state.i18n.t(
|
||||
'scenes.apps.account.account.password_modal.password',
|
||||
)}
|
||||
className={this.state.currentUserService.badNewPassword ? 'error' : ''}
|
||||
type="password"
|
||||
value={this.state.password1}
|
||||
onKeyDown={e => {
|
||||
if (e.keyCode === 13) {
|
||||
currentUserService.updatePassword(
|
||||
this.state.oldPassword,
|
||||
this.state.password,
|
||||
this.state.password1,
|
||||
);
|
||||
}
|
||||
}}
|
||||
onChange={ev => this.setState({ password1: ev.target.value })}
|
||||
/>
|
||||
{this.state.currentUserService.badNewPassword && (
|
||||
<span className="text error">
|
||||
{this.state.i18n.t(
|
||||
'scenes.apps.account.account.password_modal.bad_password',
|
||||
)}
|
||||
</span>
|
||||
)}
|
||||
|
||||
<ButtonWithTimeout
|
||||
href="#"
|
||||
className="small buttonValidation"
|
||||
disabled={this.state.currentUserService.loading}
|
||||
onClick={() =>
|
||||
currentUserService.updatePassword(
|
||||
this.state.oldPassword,
|
||||
this.state.password,
|
||||
this.state.password1,
|
||||
)
|
||||
}
|
||||
loading={this.state.currentUserService.loading}
|
||||
value={this.state.i18n.t('general.update')}
|
||||
/>
|
||||
</div>
|
||||
</Attribute>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</form>
|
||||
);
|
||||
}
|
||||
if (this.state.page === 2) {
|
||||
return (
|
||||
<div className="">
|
||||
<div className="title">
|
||||
{Languages.t(
|
||||
'scenes.app.popup.userparameter.personnal_workspaces_title',
|
||||
[],
|
||||
'Vos espaces de travail',
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="group_section" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
setPage(page) {
|
||||
popupManager.popupStates['user_parameters'] = page;
|
||||
this.setState({ page: page });
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div className="userParameter fade_in">
|
||||
<div className="main">
|
||||
<div className="sideBar">
|
||||
<MenuList
|
||||
menu={[
|
||||
{
|
||||
type: 'menu',
|
||||
text: this.state.i18n.t('scenes.apps.account.title'),
|
||||
emoji: ':dark_sunglasses:',
|
||||
selected: this.state.page === 1 ? 'selected' : '',
|
||||
onClick: () => {
|
||||
this.setPage(1);
|
||||
},
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
<div className="content">{this.displayScene()}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import { DriveCurrentFolderAtom } from '../body/drive/browser';
|
||||
import { ConfirmDeleteModalAtom } from '../body/drive/modals/confirm-delete';
|
||||
import { CreateModal, CreateModalAtom } from '../body/drive/modals/create';
|
||||
import { Button } from '@atoms/button/button';
|
||||
import Languages from "features/global/services/languages-service";
|
||||
|
||||
export const CreateModalWithUploadZones = ({ initialParentId }: { initialParentId?: string }) => {
|
||||
const companyId = useRouterCompany();
|
||||
@@ -22,7 +23,7 @@ export const CreateModalWithUploadZones = ({ initialParentId }: { initialParentI
|
||||
DriveCurrentFolderAtom({ initialFolderId: initialParentId || 'root' }),
|
||||
);
|
||||
|
||||
console.log(parentId);
|
||||
console.log("Upload Zone:: " + parentId);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -81,6 +82,8 @@ export default () => {
|
||||
const { access, item, inTrash } = useDriveItem(parentId);
|
||||
const { children: trashChildren } = useDriveItem('trash');
|
||||
const uploadZoneRef = useRef<UploadZone | null>(null);
|
||||
const { uploadTree } = useDriveUpload();
|
||||
const companyId = useRouterCompany();
|
||||
|
||||
const setConfirmDeleteModalState = useSetRecoilState(ConfirmDeleteModalAtom);
|
||||
const setCreationModalState = useSetRecoilState(CreateModalAtom);
|
||||
@@ -108,20 +111,40 @@ export default () => {
|
||||
theme="danger"
|
||||
className="w-full mb-2 justify-center"
|
||||
>
|
||||
<TruckIcon className="w-5 h-5 mr-2" /> Empty trash
|
||||
<TruckIcon className="w-5 h-5 mr-2" /> { Languages.t('components.side_menu.buttons.empty_trash') }
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
{!(inTrash || access === 'read') && (
|
||||
<>
|
||||
<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,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
<Button
|
||||
onClick={() => uploadZoneRef.current?.open()}
|
||||
onClick={() => {
|
||||
uploadZoneRef.current?.open();
|
||||
}}
|
||||
size="lg"
|
||||
theme="primary"
|
||||
className="w-full mb-2 justify-center"
|
||||
style={{ boxShadow: '0 0 10px 0 rgba(0, 122, 255, 0.5)' }}
|
||||
>
|
||||
<UploadIcon className="w-5 h-5 mr-2" /> Upload
|
||||
<UploadIcon className="w-5 h-5 mr-2" /> {Languages.t('components.side_menu.buttons.upload')}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => openItemModal()}
|
||||
@@ -129,7 +152,7 @@ export default () => {
|
||||
theme="secondary"
|
||||
className="w-full mb-2 justify-center"
|
||||
>
|
||||
<PlusIcon className="w-5 h-5 mr-2" /> Create
|
||||
<PlusIcon className="w-5 h-5 mr-2" /> {Languages.t('components.side_menu.buttons.create')}
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -22,6 +22,7 @@ import DiskUsage from '../common/disk-usage';
|
||||
import Actions from './actions';
|
||||
import { useHistory, useLocation } from 'react-router-dom';
|
||||
import RouterServices from '@features/router/services/router-service';
|
||||
import Languages from "features/global/services/languages-service";
|
||||
|
||||
export default () => {
|
||||
const history = useHistory();
|
||||
@@ -65,7 +66,7 @@ export default () => {
|
||||
theme="white"
|
||||
className={'w-full mt-2 mb-1 ' + (folderType === 'home' && viewId == '' ? activeClass : '')}
|
||||
>
|
||||
<CloudIcon className="w-5 h-5 mr-4" /> Home
|
||||
<CloudIcon className="w-5 h-5 mr-4" /> {Languages.t('components.side_menu.home')}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {history.push(RouterServices.generateRouteFromState({companyId: company, viewId: ""})); setParentId('user_' + user?.id)}}
|
||||
@@ -73,7 +74,7 @@ export default () => {
|
||||
theme="white"
|
||||
className={'w-full mb-1 ' + (folderType === 'personal' && viewId == '' ? activeClass : '')}
|
||||
>
|
||||
<UserIcon className="w-5 h-5 mr-4" /> My Drive
|
||||
<UserIcon className="w-5 h-5 mr-4" /> {Languages.t('components.side_menu.my_drive')}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => history.push(RouterServices.generateRouteFromState({companyId: company, viewId: "shared-with-me"}))}
|
||||
@@ -108,7 +109,7 @@ export default () => {
|
||||
theme="white"
|
||||
className={'w-full mb-1 ' + (folderType === 'trash' && viewId == ''? activeClass : '')}
|
||||
>
|
||||
<TrashIcon className="w-5 h-5 mr-4 text-rose-500" /> Trash
|
||||
<TrashIcon className="w-5 h-5 mr-4 text-rose-500" /> {Languages.t('components.side_menu.trash')}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@ module.exports = function (app) {
|
||||
'/internal',
|
||||
createProxyMiddleware({
|
||||
target: 'http://localhost:4000',
|
||||
onError: (err, req, resp) => {
|
||||
console.log(err);
|
||||
},
|
||||
}),
|
||||
);
|
||||
app.use(
|
||||
|
||||
Reference in New Issue
Block a user