mirror of
https://bitbucket.org/wisemapping/wisemapping-frontend.git
synced 2024-11-25 23:54:55 +01:00
Split components class.
This commit is contained in:
parent
2a6723f73a
commit
2cdc59b9da
@ -7,7 +7,7 @@ import {
|
|||||||
NoteModel,
|
NoteModel,
|
||||||
NoteIcon,
|
NoteIcon,
|
||||||
} from '@wisemapping/mindplot';
|
} from '@wisemapping/mindplot';
|
||||||
import { linkContent, noteContent } from '../../components/toolbar/contents';
|
import { linkContent, noteContent } from './react-component';
|
||||||
|
|
||||||
export class DefaultWidgetManager extends WidgetManager {
|
export class DefaultWidgetManager extends WidgetManager {
|
||||||
private editorOpen: boolean;
|
private editorOpen: boolean;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { NoteForm, UrlForm } from './toolbarCustomComponents';
|
import UrlForm from '../../components/toolbar/component/link-form';
|
||||||
|
import NoteForm from '../../components/toolbar/component/note-form';
|
||||||
|
|
||||||
const linkContent = (linkModel, closeModal): React.ReactElement => {
|
const linkContent = (linkModel, closeModal): React.ReactElement => {
|
||||||
return <UrlForm closeModal={closeModal} urlModel={linkModel}></UrlForm>;
|
return <UrlForm closeModal={closeModal} urlModel={linkModel}></UrlForm>;
|
@ -1,11 +1,7 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { StyledLogo, Notifier } from './styled';
|
import { Notifier } from './styled';
|
||||||
import { useIntl } from 'react-intl';
|
import { useIntl } from 'react-intl';
|
||||||
|
|
||||||
import KeyboardSvg from '../../../images/keyboard.svg';
|
|
||||||
import AddSvg from '../../../images/add.svg';
|
|
||||||
import MinusSvg from '../../../images/minus.svg';
|
|
||||||
import CenterFocusSvg from '../../../images/center_focus.svg';
|
|
||||||
import CloseDialogSvg from '../../../images/close-dialog-icon.svg';
|
import CloseDialogSvg from '../../../images/close-dialog-icon.svg';
|
||||||
|
|
||||||
import ActionButton from '../action-button';
|
import ActionButton from '../action-button';
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
import Box from '@mui/material/Box';
|
||||||
|
import React from 'react';
|
||||||
|
import { NodePropertyValueModel } from '../../ToolbarValueModelBuilder';
|
||||||
|
import { CirclePicker as ReactColorPicker } from 'react-color';
|
||||||
|
import colors from './colors.json';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Color picker for toolbar
|
||||||
|
*/
|
||||||
|
const ColorPicker = (props: { closeModal: () => void; colorModel: NodePropertyValueModel }) => {
|
||||||
|
return (
|
||||||
|
<Box component="div" sx={{ m: 2 }}>
|
||||||
|
<ReactColorPicker
|
||||||
|
color={props.colorModel.getValue() || '#fff'}
|
||||||
|
onChangeComplete={(color) => {
|
||||||
|
props.colorModel.setValue(color.hex);
|
||||||
|
props.closeModal();
|
||||||
|
}}
|
||||||
|
colors={colors}
|
||||||
|
width={216}
|
||||||
|
circleSpacing={9}
|
||||||
|
circleSize={18}
|
||||||
|
></ReactColorPicker>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ColorPicker;
|
@ -0,0 +1,28 @@
|
|||||||
|
import TextField, { TextFieldProps } from '@mui/material/TextField';
|
||||||
|
import DesignerKeyboard from '@wisemapping/mindplot/src/components/DesignerKeyboard';
|
||||||
|
import React, { useEffect } from 'react';
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param props text field props.
|
||||||
|
* @returns wrapped mui TextField, that disable mindplot keyboard events on focus and enable it on blur
|
||||||
|
*/
|
||||||
|
const Input = (props: TextFieldProps) => {
|
||||||
|
useEffect(() => {
|
||||||
|
return () => DesignerKeyboard.resume();
|
||||||
|
}, []);
|
||||||
|
return (
|
||||||
|
<TextField
|
||||||
|
{...props}
|
||||||
|
onFocus={(e) => {
|
||||||
|
DesignerKeyboard.pause();
|
||||||
|
props.onFocus && props.onFocus(e);
|
||||||
|
}}
|
||||||
|
onBlur={(e) => {
|
||||||
|
DesignerKeyboard.resume();
|
||||||
|
props.onBlur && props.onBlur(e);
|
||||||
|
}}
|
||||||
|
></TextField>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default Input;
|
@ -0,0 +1,127 @@
|
|||||||
|
import { $msg } from '@wisemapping/mindplot';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
export const KeyboardShorcutsHelp = () => {
|
||||||
|
return (
|
||||||
|
<div id="keyboardTable" style={{ position: 'relative', zIndex: '2' }}>
|
||||||
|
<table>
|
||||||
|
<colgroup>
|
||||||
|
<col width="40%" />
|
||||||
|
<col width="30%" />
|
||||||
|
<col width="30%" />
|
||||||
|
</colgroup>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{$msg('ACTION')}</th>
|
||||||
|
<th>Windows - Linux</th>
|
||||||
|
<th>Mac OS X</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('SAVE_CHANGES')}</td>
|
||||||
|
<td>{$msg('CTRL')} + S</td>
|
||||||
|
<td>⌘ + S</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('CREATE_SIBLING_TOPIC')}</td>
|
||||||
|
<td>Enter</td>
|
||||||
|
<td>Enter</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('CREATE_CHILD_TOPIC')}</td>
|
||||||
|
<td>{$msg('K_INSERT')} / Tab</td>
|
||||||
|
<td>⌘ + Enter / Tab</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('DELETE_TOPIC')}</td>
|
||||||
|
<td>{$msg('K_DELETE')}</td>
|
||||||
|
<td>Delete</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('EDIT_TOPIC_TEXT')}</td>
|
||||||
|
<td>{$msg('JUST_START_TYPING')} | F2</td>
|
||||||
|
<td>{$msg('JUST_START_TYPING')} | F2</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('MULTIPLE_LINES')}</td>
|
||||||
|
<td>{$msg('CTRL')} + Enter</td>
|
||||||
|
<td>⌘ + Enter</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('COPY_AND_PASTE_TOPICS')}</td>
|
||||||
|
<td>
|
||||||
|
{$msg('CTRL')} + C / {$msg('CTRL')} + V
|
||||||
|
</td>
|
||||||
|
<td>⌘ + C / ⌘ + V</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('COLLAPSE_CHILDREN')}</td>
|
||||||
|
<td>{$msg('SPACE_BAR')}</td>
|
||||||
|
<td>{$msg('SPACE_BAR')}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('TOPIC_NAVIGATION')}</td>
|
||||||
|
<td>{$msg('ARROW_KEYS')}</td>
|
||||||
|
<td>{$msg('ARROW_KEYS')}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('SELECT_MULTIPLE_NODES')}</td>
|
||||||
|
<td>
|
||||||
|
{$msg('CTRL')} + {$msg('MOUSE_CLICK')}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{$msg('CTRL')} + {$msg('MOUSE_CLICK')}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('UNDO_EDITION')}</td>
|
||||||
|
<td>{$msg('CTRL')} + Z</td>
|
||||||
|
<td>⌘ + Z</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('REDO_EDITION')}</td>
|
||||||
|
<td>{$msg('CTRL')} + Shift + Z</td>
|
||||||
|
<td>⌘ + Shift + Z</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('SELECT_ALL_TOPIC')}</td>
|
||||||
|
<td>{$msg('CTRL')} + A</td>
|
||||||
|
<td>⌘ + A</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('CANCEL_TEXT_CHANGES')}</td>
|
||||||
|
<td>Esc</td>
|
||||||
|
<td>Esc</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('DESELECT_ALL_TOPIC')}</td>
|
||||||
|
<td>{$msg('CTRL')} + Shift + A</td>
|
||||||
|
<td>⌘ + Shift + A</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('CHANGE_TEXT_ITALIC')}</td>
|
||||||
|
<td>{$msg('CTRL')} + I</td>
|
||||||
|
<td>⌘ + I</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('CHANGE_TEXT_BOLD')}</td>
|
||||||
|
<td>{$msg('CTRL')} + B</td>
|
||||||
|
<td>⌘ + B</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('TOPIC_NOTE')}</td>
|
||||||
|
<td>{$msg('CTRL')} + K</td>
|
||||||
|
<td>⌘ + K</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$msg('TOPIC_LINK')}</td>
|
||||||
|
<td>{$msg('CTRL')} + L</td>
|
||||||
|
<td>⌘ + L</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
@ -0,0 +1,76 @@
|
|||||||
|
import { useState } from 'react';
|
||||||
|
import { $msg } from '@wisemapping/mindplot';
|
||||||
|
import { NodePropertyValueModel } from '../../ToolbarValueModelBuilder';
|
||||||
|
import Box from '@mui/material/Box';
|
||||||
|
import React from 'react';
|
||||||
|
import Input from '../input';
|
||||||
|
import Link from '@mui/material/Link';
|
||||||
|
import IconButton from '@mui/material/IconButton';
|
||||||
|
import SaveAndDelete from '../save-and-delete';
|
||||||
|
import OpenInNewOutlinedIcon from '@mui/icons-material/OpenInNewOutlined';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Url form for toolbar and node contextual editor
|
||||||
|
*/
|
||||||
|
const UrlForm = (props: { closeModal: () => void; urlModel: NodePropertyValueModel }) => {
|
||||||
|
const [url, setUrl] = useState(props.urlModel.getValue());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* if url is valid set model value and calls closeModal
|
||||||
|
*/
|
||||||
|
const submitHandler = () => {
|
||||||
|
if (checkURL(url)) {
|
||||||
|
props.closeModal();
|
||||||
|
props.urlModel.setValue(url);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const keyDownHandler = (event) => {
|
||||||
|
if (event.key === 'Enter') {
|
||||||
|
event.preventDefault();
|
||||||
|
submitHandler();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const checkURL = (url: string): boolean => {
|
||||||
|
const regex =
|
||||||
|
/^((http|https):\/\/)?[a-z0-9]+([-.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/i;
|
||||||
|
return regex.test(url);
|
||||||
|
};
|
||||||
|
|
||||||
|
const isValidUrl = !url || checkURL(url);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box display="flex" sx={{ p: 1 }}>
|
||||||
|
<Input
|
||||||
|
autoFocus
|
||||||
|
error={!isValidUrl}
|
||||||
|
helperText={isValidUrl ? '' : $msg('URL_ERROR')}
|
||||||
|
placeholder={$msg('PASTE_URL_HERE')}
|
||||||
|
label="URL"
|
||||||
|
value={url}
|
||||||
|
onChange={(event) => setUrl(event.target.value)}
|
||||||
|
variant="outlined"
|
||||||
|
size="small"
|
||||||
|
onKeyDown={keyDownHandler}
|
||||||
|
InputProps={{
|
||||||
|
endAdornment: (
|
||||||
|
<Link href={isValidUrl ? url : ''} target="_blank">
|
||||||
|
<IconButton disabled={!isValidUrl}>
|
||||||
|
<OpenInNewOutlinedIcon></OpenInNewOutlinedIcon>
|
||||||
|
</IconButton>
|
||||||
|
</Link>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
sx={{ pr: 1 }}
|
||||||
|
></Input>
|
||||||
|
<SaveAndDelete
|
||||||
|
model={props.urlModel}
|
||||||
|
closeModal={props.closeModal}
|
||||||
|
submitHandler={submitHandler}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default UrlForm;
|
@ -0,0 +1,42 @@
|
|||||||
|
import Box from '@mui/material/Box';
|
||||||
|
import { $msg } from '@wisemapping/mindplot';
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { NodePropertyValueModel } from '../../ToolbarValueModelBuilder';
|
||||||
|
import Input from '../input';
|
||||||
|
import SaveAndDelete from '../save-and-delete';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Note form for toolbar and node contextual editor
|
||||||
|
*/
|
||||||
|
const NoteForm = (props: { closeModal: () => void; noteModel: NodePropertyValueModel | null }) => {
|
||||||
|
const [note, setNote] = useState(props.noteModel.getValue());
|
||||||
|
|
||||||
|
const submitHandler = () => {
|
||||||
|
props.closeModal();
|
||||||
|
props.noteModel.setValue(note);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box sx={{ p: 2, width: '300px' }}>
|
||||||
|
<Input
|
||||||
|
autoFocus
|
||||||
|
multiline
|
||||||
|
label={$msg('NOTE')}
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
rows={12}
|
||||||
|
margin="dense"
|
||||||
|
value={note}
|
||||||
|
onChange={(event) => setNote(event.target.value)}
|
||||||
|
></Input>
|
||||||
|
<br />
|
||||||
|
<SaveAndDelete
|
||||||
|
model={props.noteModel}
|
||||||
|
closeModal={props.closeModal}
|
||||||
|
submitHandler={submitHandler}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default NoteForm;
|
@ -0,0 +1,34 @@
|
|||||||
|
import Box from '@mui/material/Box';
|
||||||
|
import Button from '@mui/material/Button';
|
||||||
|
import IconButton from '@mui/material/IconButton';
|
||||||
|
import { $msg } from '@wisemapping/mindplot';
|
||||||
|
import React from 'react';
|
||||||
|
import { NodePropertyValueModel } from '../../ToolbarValueModelBuilder';
|
||||||
|
import DeleteOutlineOutlinedIcon from '@mui/icons-material/DeleteOutlineOutlined';
|
||||||
|
|
||||||
|
const SaveAndDelete = (props: {
|
||||||
|
model: NodePropertyValueModel;
|
||||||
|
closeModal: () => void;
|
||||||
|
submitHandler: () => void;
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<Box component="span">
|
||||||
|
<IconButton
|
||||||
|
onClick={() => {
|
||||||
|
props.closeModal();
|
||||||
|
props.model.setValue(undefined);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<DeleteOutlineOutlinedIcon />
|
||||||
|
</IconButton>
|
||||||
|
<Button color="primary" variant="outlined" onClick={props.submitHandler} sx={{ mr: 1 }}>
|
||||||
|
{$msg('ACCEPT')}
|
||||||
|
</Button>
|
||||||
|
<Button color="primary" variant="contained" onClick={props.closeModal}>
|
||||||
|
{$msg('CANCEL')}
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SaveAndDelete;
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React from 'react';
|
||||||
import BrushOutlinedIcon from '@mui/icons-material/BrushOutlined';
|
import BrushOutlinedIcon from '@mui/icons-material/BrushOutlined';
|
||||||
import FontDownloadOutlinedIcon from '@mui/icons-material/FontDownloadOutlined';
|
import FontDownloadOutlinedIcon from '@mui/icons-material/FontDownloadOutlined';
|
||||||
import TextIncreaseOutlinedIcon from '@mui/icons-material/TextIncreaseOutlined';
|
import TextIncreaseOutlinedIcon from '@mui/icons-material/TextIncreaseOutlined';
|
||||||
@ -36,19 +36,15 @@ import SquareOutlined from '@mui/icons-material/SquareOutlined';
|
|||||||
import { $msg, Designer } from '@wisemapping/mindplot';
|
import { $msg, Designer } from '@wisemapping/mindplot';
|
||||||
import ActionConfig from '../../classes/action-config';
|
import ActionConfig from '../../classes/action-config';
|
||||||
import { SwitchValueDirection, NodePropertyValueModelBuilder } from './ToolbarValueModelBuilder';
|
import { SwitchValueDirection, NodePropertyValueModelBuilder } from './ToolbarValueModelBuilder';
|
||||||
import {
|
import { FontFamilySelect, ToolbarEmojiPcker, UndoAndRedoButton } from './toolbarCustomComponents';
|
||||||
ColorPicker,
|
|
||||||
FontFamilySelect,
|
|
||||||
KeyboardShorcutsHelp,
|
|
||||||
NoteForm,
|
|
||||||
ToolbarEmojiPcker,
|
|
||||||
UndoAndRedoButton,
|
|
||||||
UrlForm,
|
|
||||||
} from './toolbarCustomComponents';
|
|
||||||
import Typography from '@mui/material/Typography';
|
import Typography from '@mui/material/Typography';
|
||||||
import { ToolbarActionType } from '.';
|
import { ToolbarActionType } from '.';
|
||||||
import KeyboardOutlined from '@mui/icons-material/KeyboardOutlined';
|
import KeyboardOutlined from '@mui/icons-material/KeyboardOutlined';
|
||||||
import Tooltip from '@mui/material/Tooltip';
|
import Tooltip from '@mui/material/Tooltip';
|
||||||
|
import UrlForm from './component/link-form';
|
||||||
|
import NoteForm from './component/note-form';
|
||||||
|
import ColorPicker from './component/color-picker';
|
||||||
|
import { KeyboardShorcutsHelp } from './component/keyboard-shortcut-help';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -1,203 +1,18 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import Box from '@mui/material/Box';
|
import Box from '@mui/material/Box';
|
||||||
import Button from '@mui/material/Button';
|
|
||||||
import FormControl from '@mui/material/FormControl';
|
import FormControl from '@mui/material/FormControl';
|
||||||
import IconButton from '@mui/material/IconButton';
|
|
||||||
import OpenInNewOutlinedIcon from '@mui/icons-material/OpenInNewOutlined';
|
|
||||||
import DeleteOutlineOutlinedIcon from '@mui/icons-material/DeleteOutlineOutlined';
|
|
||||||
import MenuItem from '@mui/material/MenuItem';
|
import MenuItem from '@mui/material/MenuItem';
|
||||||
import Select, { SelectChangeEvent } from '@mui/material/Select';
|
import Select, { SelectChangeEvent } from '@mui/material/Select';
|
||||||
import TextField, { TextFieldProps } from '@mui/material/TextField';
|
|
||||||
import Typography from '@mui/material/Typography';
|
import Typography from '@mui/material/Typography';
|
||||||
import { $msg, DesignerKeyboard, ImageIcon } from '@wisemapping/mindplot';
|
import { $msg, ImageIcon } from '@wisemapping/mindplot';
|
||||||
|
|
||||||
import { CirclePicker as ReactColorPicker } from 'react-color';
|
|
||||||
import { NodePropertyValueModel } from './ToolbarValueModelBuilder';
|
import { NodePropertyValueModel } from './ToolbarValueModelBuilder';
|
||||||
import iconGroups from './iconGroups.json';
|
import iconGroups from './iconGroups.json';
|
||||||
import colors from './colors.json';
|
|
||||||
import Link from '@mui/material/Link';
|
|
||||||
import Tab from '@mui/material/Tab';
|
import Tab from '@mui/material/Tab';
|
||||||
import Tabs from '@mui/material/Tabs';
|
import Tabs from '@mui/material/Tabs';
|
||||||
import { ToolbarMenuItem } from './Toolbar';
|
import { ToolbarMenuItem } from './Toolbar';
|
||||||
import ActionConfig from '../../classes/action-config';
|
import ActionConfig from '../../classes/action-config';
|
||||||
|
|
||||||
/**
|
|
||||||
* Color picker for toolbar
|
|
||||||
*/
|
|
||||||
export const ColorPicker = (props: {
|
|
||||||
closeModal: () => void;
|
|
||||||
colorModel: NodePropertyValueModel;
|
|
||||||
}) => {
|
|
||||||
return (
|
|
||||||
<Box component="div" sx={{ m: 2 }}>
|
|
||||||
<ReactColorPicker
|
|
||||||
color={props.colorModel.getValue() || '#fff'}
|
|
||||||
onChangeComplete={(color) => {
|
|
||||||
props.colorModel.setValue(color.hex);
|
|
||||||
props.closeModal();
|
|
||||||
}}
|
|
||||||
colors={colors}
|
|
||||||
width={216}
|
|
||||||
circleSpacing={9}
|
|
||||||
circleSize={18}
|
|
||||||
></ReactColorPicker>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* checks whether the input is a valid url
|
|
||||||
* @return {Boolean} true if the url is valid
|
|
||||||
*/
|
|
||||||
function checkURL(url: string): boolean {
|
|
||||||
const regex =
|
|
||||||
/^((http|https):\/\/)?[a-z0-9]+([-.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/i;
|
|
||||||
return regex.test(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
const SaveAndDelete = (props: {
|
|
||||||
model: NodePropertyValueModel;
|
|
||||||
closeModal: () => void;
|
|
||||||
submitHandler: () => void;
|
|
||||||
}) => {
|
|
||||||
return (
|
|
||||||
<Box component="span">
|
|
||||||
<IconButton
|
|
||||||
onClick={() => {
|
|
||||||
props.closeModal();
|
|
||||||
props.model.setValue(undefined);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<DeleteOutlineOutlinedIcon />
|
|
||||||
</IconButton>
|
|
||||||
<Button color="primary" variant="outlined" onClick={props.submitHandler} sx={{ mr: 1 }}>
|
|
||||||
{$msg('ACCEPT')}
|
|
||||||
</Button>
|
|
||||||
<Button color="primary" variant="contained" onClick={props.closeModal}>
|
|
||||||
{$msg('CANCEL')}
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Url form for toolbar and node contextual editor
|
|
||||||
*/
|
|
||||||
export const UrlForm = (props: { closeModal: () => void; urlModel: NodePropertyValueModel }) => {
|
|
||||||
const [url, setUrl] = useState(props.urlModel.getValue());
|
|
||||||
|
|
||||||
/**
|
|
||||||
* if url is valid set model value and calls closeModal
|
|
||||||
*/
|
|
||||||
const submitHandler = () => {
|
|
||||||
if (checkURL(url)) {
|
|
||||||
props.closeModal();
|
|
||||||
props.urlModel.setValue(url);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const keyDownHandler = (event) => {
|
|
||||||
if (event.key === 'Enter') {
|
|
||||||
event.preventDefault();
|
|
||||||
submitHandler();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const isValidUrl = !url || checkURL(url);
|
|
||||||
return (
|
|
||||||
<Box display="flex" sx={{ p: 1 }}>
|
|
||||||
<Input
|
|
||||||
autoFocus
|
|
||||||
error={!isValidUrl}
|
|
||||||
helperText={isValidUrl ? '' : $msg('URL_ERROR')}
|
|
||||||
placeholder={$msg('PASTE_URL_HERE')}
|
|
||||||
label="URL"
|
|
||||||
value={url}
|
|
||||||
onChange={(event) => setUrl(event.target.value)}
|
|
||||||
variant="outlined"
|
|
||||||
size="small"
|
|
||||||
onKeyDown={keyDownHandler}
|
|
||||||
InputProps={{
|
|
||||||
endAdornment: (
|
|
||||||
<Link href={isValidUrl ? url : ''} target="_blank">
|
|
||||||
<IconButton disabled={!isValidUrl}>
|
|
||||||
<OpenInNewOutlinedIcon></OpenInNewOutlinedIcon>
|
|
||||||
</IconButton>
|
|
||||||
</Link>
|
|
||||||
),
|
|
||||||
}}
|
|
||||||
sx={{ pr: 1 }}
|
|
||||||
></Input>
|
|
||||||
<SaveAndDelete
|
|
||||||
model={props.urlModel}
|
|
||||||
closeModal={props.closeModal}
|
|
||||||
submitHandler={submitHandler}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param props text field props.
|
|
||||||
* @returns wrapped mui TextField, that disable mindplot keyboard events on focus and enable it on blur
|
|
||||||
*/
|
|
||||||
const Input = (props: TextFieldProps) => {
|
|
||||||
useEffect(() => {
|
|
||||||
return () => DesignerKeyboard.resume();
|
|
||||||
}, []);
|
|
||||||
return (
|
|
||||||
<TextField
|
|
||||||
{...props}
|
|
||||||
onFocus={(e) => {
|
|
||||||
DesignerKeyboard.pause();
|
|
||||||
props.onFocus && props.onFocus(e);
|
|
||||||
}}
|
|
||||||
onBlur={(e) => {
|
|
||||||
DesignerKeyboard.resume();
|
|
||||||
props.onBlur && props.onBlur(e);
|
|
||||||
}}
|
|
||||||
></TextField>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Note form for toolbar and node contextual editor
|
|
||||||
*/
|
|
||||||
export const NoteForm = (props: {
|
|
||||||
closeModal: () => void;
|
|
||||||
noteModel: NodePropertyValueModel | null;
|
|
||||||
}) => {
|
|
||||||
const [note, setNote] = useState(props.noteModel.getValue());
|
|
||||||
|
|
||||||
const submitHandler = () => {
|
|
||||||
props.closeModal();
|
|
||||||
props.noteModel.setValue(note);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Box sx={{ p: 2, width: '300px' }}>
|
|
||||||
<Input
|
|
||||||
autoFocus
|
|
||||||
multiline
|
|
||||||
label={$msg('NOTE')}
|
|
||||||
variant="outlined"
|
|
||||||
fullWidth
|
|
||||||
rows={12}
|
|
||||||
margin="dense"
|
|
||||||
value={note}
|
|
||||||
onChange={(event) => setNote(event.target.value)}
|
|
||||||
></Input>
|
|
||||||
<br />
|
|
||||||
<SaveAndDelete
|
|
||||||
model={props.noteModel}
|
|
||||||
closeModal={props.closeModal}
|
|
||||||
submitHandler={submitHandler}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Font family selector for editor toolbar
|
* Font family selector for editor toolbar
|
||||||
*/
|
*/
|
||||||
@ -336,128 +151,3 @@ export const UndoAndRedoButton = (props: {
|
|||||||
></ToolbarMenuItem>
|
></ToolbarMenuItem>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const KeyboardShorcutsHelp = () => {
|
|
||||||
return (
|
|
||||||
<div id="keyboardTable" style={{ position: 'relative', zIndex: '2' }}>
|
|
||||||
<table>
|
|
||||||
<colgroup>
|
|
||||||
<col width="40%" />
|
|
||||||
<col width="30%" />
|
|
||||||
<col width="30%" />
|
|
||||||
</colgroup>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>{$msg('ACTION')}</th>
|
|
||||||
<th>Windows - Linux</th>
|
|
||||||
<th>Mac OS X</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td>{$msg('SAVE_CHANGES')}</td>
|
|
||||||
<td>{$msg('CTRL')} + S</td>
|
|
||||||
<td>⌘ + S</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{$msg('CREATE_SIBLING_TOPIC')}</td>
|
|
||||||
<td>Enter</td>
|
|
||||||
<td>Enter</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{$msg('CREATE_CHILD_TOPIC')}</td>
|
|
||||||
<td>{$msg('K_INSERT')} / Tab</td>
|
|
||||||
<td>⌘ + Enter / Tab</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{$msg('DELETE_TOPIC')}</td>
|
|
||||||
<td>{$msg('K_DELETE')}</td>
|
|
||||||
<td>Delete</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{$msg('EDIT_TOPIC_TEXT')}</td>
|
|
||||||
<td>{$msg('JUST_START_TYPING')} | F2</td>
|
|
||||||
<td>{$msg('JUST_START_TYPING')} | F2</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{$msg('MULTIPLE_LINES')}</td>
|
|
||||||
<td>{$msg('CTRL')} + Enter</td>
|
|
||||||
<td>⌘ + Enter</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{$msg('COPY_AND_PASTE_TOPICS')}</td>
|
|
||||||
<td>
|
|
||||||
{$msg('CTRL')} + C / {$msg('CTRL')} + V
|
|
||||||
</td>
|
|
||||||
<td>⌘ + C / ⌘ + V</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>{$msg('COLLAPSE_CHILDREN')}</td>
|
|
||||||
<td>{$msg('SPACE_BAR')}</td>
|
|
||||||
<td>{$msg('SPACE_BAR')}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{$msg('TOPIC_NAVIGATION')}</td>
|
|
||||||
<td>{$msg('ARROW_KEYS')}</td>
|
|
||||||
<td>{$msg('ARROW_KEYS')}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{$msg('SELECT_MULTIPLE_NODES')}</td>
|
|
||||||
<td>
|
|
||||||
{$msg('CTRL')} + {$msg('MOUSE_CLICK')}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{$msg('CTRL')} + {$msg('MOUSE_CLICK')}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{$msg('UNDO_EDITION')}</td>
|
|
||||||
<td>{$msg('CTRL')} + Z</td>
|
|
||||||
<td>⌘ + Z</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{$msg('REDO_EDITION')}</td>
|
|
||||||
<td>{$msg('CTRL')} + Shift + Z</td>
|
|
||||||
<td>⌘ + Shift + Z</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{$msg('SELECT_ALL_TOPIC')}</td>
|
|
||||||
<td>{$msg('CTRL')} + A</td>
|
|
||||||
<td>⌘ + A</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{$msg('CANCEL_TEXT_CHANGES')}</td>
|
|
||||||
<td>Esc</td>
|
|
||||||
<td>Esc</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{$msg('DESELECT_ALL_TOPIC')}</td>
|
|
||||||
<td>{$msg('CTRL')} + Shift + A</td>
|
|
||||||
<td>⌘ + Shift + A</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{$msg('CHANGE_TEXT_ITALIC')}</td>
|
|
||||||
<td>{$msg('CTRL')} + I</td>
|
|
||||||
<td>⌘ + I</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{$msg('CHANGE_TEXT_BOLD')}</td>
|
|
||||||
<td>{$msg('CTRL')} + B</td>
|
|
||||||
<td>⌘ + B</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{$msg('TOPIC_NOTE')}</td>
|
|
||||||
<td>{$msg('CTRL')} + K</td>
|
|
||||||
<td>⌘ + K</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{$msg('TOPIC_LINK')}</td>
|
|
||||||
<td>{$msg('CTRL')} + L</td>
|
|
||||||
<td>⌘ + L</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
Loading…
Reference in New Issue
Block a user