Split components class.

This commit is contained in:
Paulo Gustavo Veiga 2022-10-06 22:16:21 -07:00
parent 2a6723f73a
commit 2cdc59b9da
12 changed files with 346 additions and 328 deletions

View File

@ -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;

View File

@ -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>;

View File

@ -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';

View File

@ -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;

View File

@ -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;

View File

@ -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>
);
};

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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';
/** /**
* *

View File

@ -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>
);
};