wisemapping-frontend/packages/webapp/src/components/editor-page/index.tsx

201 lines
6.4 KiB
TypeScript
Raw Normal View History

/*
* Copyright [2021] [wisemapping]
*
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
* It is basically the Apache License, Version 2.0 (the "License") plus the
* "powered by wisemapping" text requirement on every single page;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the license at
*
* http://www.wisemapping.org/license
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
2022-02-16 05:39:52 +01:00
import React, { useEffect } from 'react';
2023-01-06 18:11:12 +01:00
import Editor, { EditorOptions } from '@wisemapping/editor';
2023-01-05 01:48:01 +01:00
import {
EditorRenderMode,
PersistenceManager,
RESTPersistenceManager,
LocalStorageManager,
MockPersistenceManager,
} from '@wisemapping/editor';
2022-03-14 18:47:42 +01:00
import { IntlProvider } from 'react-intl';
import AppI18n, { Locales } from '../../classes/app-i18n';
2022-02-13 04:15:51 +01:00
import { useSelector } from 'react-redux';
2022-02-22 06:55:13 +01:00
import { hotkeysEnabled } from '../../redux/editorSlice';
2022-05-29 19:22:57 +02:00
import ReactGA from 'react-ga4';
import { useFetchAccount, useFetchMapById } from '../../redux/clientSlice';
2022-03-14 18:57:07 +01:00
import EditorOptionsBuilder from './EditorOptionsBuilder';
import { useTheme } from '@mui/material/styles';
import MapInfoImpl from '../../classes/editor-map-info';
import { MapInfo } from '@wisemapping/editor';
import { activeInstance } from '../../redux/clientSlice';
import Client from '../../classes/client';
2023-01-05 01:48:01 +01:00
import AppConfig from '../../classes/app-config';
import exampleMap from '../../classes/client/mock-client/example-map.wxml';
import withSessionExpirationHandling from '../HOCs/withSessionExpirationHandling';
const buildPersistenceManagerForEditor = (mode: string): PersistenceManager => {
let persistenceManager: PersistenceManager;
if (AppConfig.isRestClient()) {
if (mode === 'edition-owner' || mode === 'edition-editor') {
persistenceManager = new RESTPersistenceManager({
documentUrl: '/c/restful/maps/{id}/document',
revertUrl: '/c/restful/maps/{id}/history/latest',
lockUrl: '/c/restful/maps/{id}/lock',
});
} else {
persistenceManager = new LocalStorageManager(
`/c/restful/maps/{id}/${
globalThis.historyId ? `${globalThis.historyId}/` : ''
}document/xml${mode === 'showcase' ? '-pub' : ''}`,
true,
);
}
persistenceManager.addErrorHandler((error) => {
if (error.errorType === 'session-expired') {
// TODO: this line was in RestPersistenceClient, do something similar here
//client.sessionExpired();
}
});
} else {
persistenceManager = new MockPersistenceManager(exampleMap);
}
return persistenceManager;
};
2022-01-25 19:10:40 +01:00
export type EditorPropsType = {
2022-07-10 05:56:01 +02:00
isTryMode: boolean;
2022-01-25 19:10:40 +01:00
};
2023-01-05 01:48:01 +01:00
type ActionType =
| 'open'
| 'share'
| 'import'
| 'delete'
| 'info'
| 'create'
| 'duplicate'
| 'export'
| 'label'
| 'rename'
| 'print'
| 'info'
| 'publish'
| 'history'
| undefined;
const ActionDispatcher = React.lazy(() => import('../maps-page/action-dispatcher'));
const AccountMenu = React.lazy(() => import('../maps-page/account-menu'));
2022-01-25 19:10:40 +01:00
2022-02-22 06:37:00 +01:00
const EditorPage = ({ isTryMode }: EditorPropsType): React.ReactElement => {
2022-07-10 05:56:01 +02:00
const [activeDialog, setActiveDialog] = React.useState<ActionType | null>(null);
const hotkey = useSelector(hotkeysEnabled);
const userLocale = AppI18n.getUserLocale();
const theme = useTheme();
const client: Client = useSelector(activeInstance);
2022-02-05 22:53:10 +01:00
2022-07-10 05:56:01 +02:00
useEffect(() => {
ReactGA.send({ hitType: 'pageview', page: window.location.pathname, title: `Map Editor` });
}, []);
2022-02-22 06:37:00 +01:00
const useFindEditorMode = (isTryMode: boolean, mapId: number): EditorRenderMode | null => {
2022-07-10 05:56:01 +02:00
let result: EditorRenderMode = null;
if (isTryMode) {
result = 'showcase';
2022-10-31 07:10:39 +01:00
} else if (globalThis.mindmapLocked) {
2022-07-10 05:56:01 +02:00
result = 'viewonly';
} else {
const fetchResult = useFetchMapById(mapId);
2022-07-10 05:56:01 +02:00
if (!fetchResult.isLoading) {
if (fetchResult.error) {
throw new Error(`Map info could not be loaded: ${JSON.stringify(fetchResult.error)}`);
}
2022-03-15 20:23:41 +01:00
2022-07-10 05:56:01 +02:00
if (!fetchResult.map) {
throw new Error(
`Map info could not be loaded. Info not present: ${JSON.stringify(fetchResult)}`,
);
}
2022-07-10 05:56:01 +02:00
result = `edition-${fetchResult.map.role}`;
}
}
2022-07-10 05:56:01 +02:00
return result;
};
2022-07-10 05:56:01 +02:00
// What is the role ?
const mapId = EditorOptionsBuilder.loadMapId();
const mode = useFindEditorMode(isTryMode, mapId);
2022-07-10 05:56:01 +02:00
// Account settings can be null and editor cannot be initilized multiple times. This creates problems
// at the i18n resource loading.
const isAccountLoaded = mode === 'showcase' || useFetchAccount;
2022-07-10 05:56:01 +02:00
const loadCompleted = mode && isAccountLoaded;
2022-02-26 04:59:21 +01:00
2023-01-06 18:11:12 +01:00
let options: EditorOptions, persistence: PersistenceManager;
let mapInfo: MapInfo;
2022-07-10 05:56:01 +02:00
if (loadCompleted) {
options = EditorOptionsBuilder.build(userLocale.code, mode, hotkey);
persistence = buildPersistenceManagerForEditor(mode);
mapInfo = new MapInfoImpl(
mapId,
client,
2022-10-31 06:34:34 +01:00
options.mapTitle,
2023-01-06 18:11:12 +01:00
options.locked,
options.lockedMsg,
options.zoom,
);
2022-07-10 05:56:01 +02:00
}
2022-01-25 19:10:40 +01:00
2022-10-08 23:21:03 +02:00
useEffect(() => {
2022-10-31 06:34:34 +01:00
if (mapInfo?.getTitle()) {
document.title = `${mapInfo.getTitle()} | WiseMapping `;
2022-10-09 00:49:03 +02:00
}
2022-10-31 06:34:34 +01:00
}, [mapInfo?.getTitle()]);
2022-10-08 23:21:03 +02:00
2022-07-10 05:56:01 +02:00
return loadCompleted ? (
<IntlProvider
locale={userLocale.code}
defaultLocale={Locales.EN.code}
messages={userLocale.message as Record<string, string>}
>
<Editor
onAction={setActiveDialog}
options={options}
persistenceManager={persistence}
mapInfo={mapInfo}
theme={theme}
accountConfiguration={
2022-10-12 06:49:24 +02:00
// Prevent load on non-authenticated.
2022-10-08 23:52:40 +02:00
options.mode !== 'showcase' ? (
<IntlProvider
locale={userLocale.code}
messages={userLocale.message as Record<string, string>}
>
<AccountMenu />
</IntlProvider>
) : (
<></>
)
}
2022-07-10 05:56:01 +02:00
/>
{activeDialog && (
<ActionDispatcher
action={activeDialog}
onClose={() => setActiveDialog(null)}
mapsId={[mapId]}
fromEditor
/>
)}
</IntlProvider>
) : (
<></>
);
};
2022-02-22 06:37:00 +01:00
2023-01-05 01:48:01 +01:00
export default withSessionExpirationHandling(EditorPage);