Fix type problems.

This commit is contained in:
Paulo Gustavo Veiga 2022-11-02 19:56:37 -07:00
parent 926eb51405
commit e60ed49478
21 changed files with 109 additions and 81 deletions

View File

@ -1,4 +1,5 @@
declare module '*.svg' {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const content: any;
export default content;
}

View File

@ -34,7 +34,7 @@ interface ActionConfig {
/**
* the event handler for a common button
*/
onClick?: (event: object) => void;
onClick?: (event) => void;
/**
* custom element for a menu entry
*/

View File

@ -1,3 +1,4 @@
/* eslint-disable react-hooks/rules-of-hooks */
/*
* Copyright [2021] [wisemapping]
*
@ -16,14 +17,7 @@
* limitations under the License.
*/
import React, { useRef, useState } from 'react';
import {
WidgetManager,
Topic,
LinkModel,
LinkIcon,
NoteModel,
NoteIcon,
} from '@wisemapping/mindplot';
import { WidgetManager, Topic } from '@wisemapping/mindplot';
import { linkContent, noteContent } from './react-component';
export class DefaultWidgetManager extends WidgetManager {
@ -41,8 +35,8 @@ export class DefaultWidgetManager extends WidgetManager {
this.setPopoverTarget = setPopoverTarget;
}
showEditorForLink(topic: Topic, linkModel: LinkModel, linkIcon: LinkIcon): void {
const model: any = {
showEditorForLink(topic: Topic): void {
const model = {
getValue: () => topic.getLinkValue(),
setValue: (value: string) => topic.setLinkValue(value),
};
@ -60,13 +54,13 @@ export class DefaultWidgetManager extends WidgetManager {
return this.editorContent;
}
handleClose: (event: {}, reason: 'backdropClick' | 'escapeKeyDown') => void = () => {
handleClose: (event, reason: 'backdropClick' | 'escapeKeyDown') => void = () => {
this.setPopoverOpen(false);
this.editorContent = undefined;
this.setPopoverTarget(undefined);
};
showEditorForNote(topic: Topic, noteModel: NoteModel, noteIcon: NoteIcon) {
showEditorForNote(topic: Topic): void {
const model = {
getValue(): string {
return topic.getNoteValue();
@ -82,7 +76,7 @@ export class DefaultWidgetManager extends WidgetManager {
topic.closeEditors();
}
static create(): [boolean, Element | undefined, DefaultWidgetManager] {
static useCreate(): [boolean, Element | undefined, DefaultWidgetManager] {
const [popoverOpen, setPopoverOpen] = useState(false);
const [popoverTarget, setPopoverTarget] = useState(undefined);
const widgetManager = useRef(new DefaultWidgetManager(setPopoverOpen, setPopoverTarget));

View File

@ -20,11 +20,17 @@ import TopicLink from '../../components/action-widget/pane/topic-link';
import TopicNote from '../../components/action-widget/pane/topic-note';
import NodeProperty from '../model/node-property';
const linkContent = (linkModel: NodeProperty, closeModal: () => void): React.ReactElement => {
const linkContent = (
linkModel: NodeProperty<string>,
closeModal: () => void,
): React.ReactElement => {
return <TopicLink closeModal={closeModal} urlModel={linkModel}></TopicLink>;
};
const noteContent = (noteModel: NodeProperty, closeModal: () => void): React.ReactElement => {
const noteContent = (
noteModel: NodeProperty<string>,
closeModal: () => void,
): React.ReactElement => {
return <TopicNote closeModal={closeModal} noteModel={noteModel}></TopicNote>;
};

View File

@ -27,7 +27,7 @@ class Events {
return string.replace(/^on([A-Z])/, (_full, first) => first.toLowerCase());
}
addEvent(typeName: string, fn: any, internal?: boolean): Events {
addEvent(typeName: string, fn: () => void, internal?: boolean): Events {
const type = Events._normalizeEventName(typeName);
// Add function had not been added yet
@ -38,10 +38,13 @@ class Events {
}
// Mark reference ...
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
fn.internal = Boolean(internal);
return this;
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
fireEvent(typeName: string, eventArgs?): Events {
const type = Events._normalizeEventName(typeName);
const events = this._handlerByType[type];
@ -54,9 +57,12 @@ class Events {
return this;
}
removeEvent(typeName: string, fn?): Events {
removeEvent(typeName: string, fn?: () => void): Events {
const type = Events._normalizeEventName(typeName);
const events = this._handlerByType[type];
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
if (events && !fn.internal) {
const index = events.indexOf(fn);
if (index !== -1) events.splice(index, 1);

View File

@ -20,6 +20,7 @@ import {
MindplotWebComponent,
PersistenceManager,
DesignerModel,
WidgetManager,
} from '@wisemapping/mindplot';
import Capability from '../../action/capability';
@ -34,7 +35,7 @@ class Editor {
return this.component?.getDesigner()?.getMindmap() != null;
}
save(minor: boolean) {
save(minor: boolean): void {
if (!this.component) {
throw new Error('Designer object has not been initialized.');
}
@ -52,12 +53,16 @@ class Editor {
return this.getDesigner().getModel();
}
loadMindmap(mapId: string, persistenceManager: PersistenceManager, widgetManager): void {
loadMindmap(
mapId: string,
persistenceManager: PersistenceManager,
widgetManager: WidgetManager,
): void {
this.component.buildDesigner(persistenceManager, widgetManager);
this.component.loadMap(mapId);
}
registerEvents(canvasUpdate: (timestamp: number) => void, capability: Capability) {
registerEvents(canvasUpdate: (timestamp: number) => void, capability: Capability): void {
const designer = this.component.getDesigner();
const onNodeBlurHandler = () => {
if (!designer.getModel().selectedTopic()) {

View File

@ -11,16 +11,16 @@ import {
class NodePropertyBuilder {
designer: Designer;
fontSizeModel: NodeProperty;
selectedTopicColorModel: NodeProperty;
fontFamilyModel: NodeProperty;
fontStyleModel: NodeProperty;
borderColorModel: NodeProperty;
fontColorModel: NodeProperty;
topicShapeModel: NodeProperty;
topicIconModel: NodeProperty;
noteModel: NodeProperty;
linkModel: NodeProperty;
fontSizeModel: NodeProperty<number>;
selectedTopicColorModel: NodeProperty<string>;
fontFamilyModel: NodeProperty<string>;
fontStyleModel: NodeProperty<string>;
borderColorModel: NodeProperty<string>;
fontColorModel: NodeProperty<string>;
topicShapeModel: NodeProperty<string>;
topicIconModel: NodeProperty<string>;
noteModel: NodeProperty<string>;
linkModel: NodeProperty<string>;
constructor(designer: Designer) {
this.designer = designer;
@ -34,7 +34,7 @@ class NodePropertyBuilder {
return this.designer.getModel().selectedTopic()?.getFontSize();
}
private uniqueOrNull(propertyGetter: (Topic: Topic) => any | null) {
private uniqueOrNull(propertyGetter: (Topic: Topic) => string | number | null) {
const nodes = this.designer.getModel().filterSelectedTopics();
return getTheUniqueValueOrNull(nodes, propertyGetter);
}
@ -43,9 +43,9 @@ class NodePropertyBuilder {
*
* @returns model to and switch font weigth
*/
fontWeigthModel(): NodeProperty {
fontWeigthModel(): NodeProperty<string> {
return {
getValue: () => this.designer.getModel().selectedTopic()?.getFontWeight(),
getValue: () => String(this.designer.getModel().selectedTopic()?.getFontWeight()),
switchValue: () => this.designer.changeFontWeight(),
};
}
@ -54,7 +54,7 @@ class NodePropertyBuilder {
*
* @returns model to and switch font size in both directions. Font sizes used to iterate: [6, 8, 10, 15]
*/
getFontSizeModel(): NodeProperty {
getFontSizeModel(): NodeProperty<number> {
if (!this.fontSizeModel)
this.fontSizeModel = {
getValue: () => this.getFontSize(),
@ -76,7 +76,7 @@ class NodePropertyBuilder {
*
* @returns model to get and set topic color
*/
getSelectedTopicColorModel(): NodeProperty {
getSelectedTopicColorModel(): NodeProperty<string> {
if (!this.selectedTopicColorModel)
this.selectedTopicColorModel = {
getValue: () => this.designer.getModel().selectedTopic()?.getBackgroundColor(),
@ -90,7 +90,7 @@ class NodePropertyBuilder {
*
* @returns model to get and set the node link
*/
getLinkModel(): NodeProperty {
getLinkModel(): NodeProperty<string> {
// const selected = this.selectedTopic();
if (!this.linkModel)
this.linkModel = {
@ -110,7 +110,7 @@ class NodePropertyBuilder {
*
* @returns model to get and set topic border color
*/
getColorBorderModel(): NodeProperty {
getColorBorderModel(): NodeProperty<string> {
if (!this.borderColorModel)
this.borderColorModel = {
getValue: () => this.uniqueOrNull((node) => node.getBorderColor()),
@ -123,7 +123,7 @@ class NodePropertyBuilder {
*
* @returns model to get and set topic font color
*/
getFontColorModel(): NodeProperty {
getFontColorModel(): NodeProperty<string> {
if (!this.fontColorModel)
this.fontColorModel = {
getValue: () => this.uniqueOrNull((node) => node.getFontColor()),
@ -136,7 +136,7 @@ class NodePropertyBuilder {
*
* @returns model to get and set topic icon
*/
getTopicIconModel(): NodeProperty {
getTopicIconModel(): NodeProperty<string> {
if (!this.topicIconModel)
this.topicIconModel = {
getValue: () => null,
@ -152,7 +152,7 @@ class NodePropertyBuilder {
*
* @returns model to get and set topic note
*/
getNoteModel(): NodeProperty {
getNoteModel(): NodeProperty<string> {
if (!this.noteModel)
this.noteModel = {
getValue: (): string => this.selectedTopic()?.getNoteValue(),
@ -168,7 +168,7 @@ class NodePropertyBuilder {
*
* @returns model to get and set topic font family
*/
getFontFamilyModel(): NodeProperty {
getFontFamilyModel(): NodeProperty<string> {
if (!this.fontFamilyModel)
this.fontFamilyModel = {
getValue: () => this.uniqueOrNull((node) => node.getFontFamily()),
@ -181,7 +181,7 @@ class NodePropertyBuilder {
*
* @returns model to get and switch topic style
*/
getFontStyleModel(): NodeProperty {
getFontStyleModel(): NodeProperty<string> {
if (!this.fontStyleModel)
this.fontStyleModel = {
getValue: () => this.selectedTopic()?.getFontStyle(),
@ -194,7 +194,7 @@ class NodePropertyBuilder {
*
* @returns model to get and set topic shape
*/
getTopicShapeModel(): NodeProperty {
getTopicShapeModel(): NodeProperty<string> {
if (!this.topicShapeModel)
this.topicShapeModel = {
getValue: () => this.uniqueOrNull((node) => node.getShapeType()),

View File

@ -4,15 +4,15 @@ import { SwitchValueDirection } from '../../../components/toolbar/ToolbarValueMo
* Interface to get and set a property of the mindplot selected node
*/
interface NodeProperty {
interface NodeProperty<Type> {
/**
* get the property value
*/
getValue: () => any;
getValue: () => Type;
/**
* set the property value
*/
setValue?: (value: any) => void;
setValue?: (value: Type) => void;
/**
* toogle boolean values or change for next/previous in reduced lists of values
*/

View File

@ -15,7 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';
import React, { ReactElement } from 'react';
import Box from '@mui/material/Box';
import FormControl from '@mui/material/FormControl';
import MenuItem from '@mui/material/MenuItem';
@ -27,7 +27,7 @@ import NodeProperty from '../../../../classes/model/node-property';
/**
* Font family selector for editor toolbar
*/
const FontFamilySelect = (props: { fontFamilyModel: NodeProperty }) => {
const FontFamilySelect = (props: { fontFamilyModel: NodeProperty<string> }): ReactElement => {
const [font, setFont] = React.useState(props.fontFamilyModel.getValue());
const handleChange = (event: SelectChangeEvent) => {

View File

@ -15,7 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React, { useEffect, useState } from 'react';
import React, { ReactElement, useEffect, useState } from 'react';
import ActionConfig from '../../../../classes/action/action-config';
import Editor from '../../../../classes/model/editor';
import { ToolbarMenuItem } from '../../../toolbar';
@ -26,12 +26,12 @@ type UndoAndRedo = {
model: Editor;
};
const UndoAndRedo = ({ configuration, disabledCondition, model }: UndoAndRedo) => {
const UndoAndRedo = ({ configuration, disabledCondition, model }: UndoAndRedo): ReactElement => {
const [disabled, setDisabled] = useState(true);
useEffect(() => {
if (model?.isMapLoadded()) {
const handleUpdate: any = (event) => {
const handleUpdate = (event) => {
const isDisabled = disabledCondition(event);
setDisabled(!isDisabled);

View File

@ -24,7 +24,10 @@ import colors from './colors.json';
/**
* Color picker for toolbar
*/
const ColorPicker = (props: { closeModal: () => void; colorModel: NodeProperty }): ReactElement => {
const ColorPicker = (props: {
closeModal: () => void;
colorModel: NodeProperty<string>;
}): ReactElement => {
return (
<Box component="div" sx={{ m: 2 }}>
<ReactColorPicker

View File

@ -5,15 +5,15 @@ import { SvgImageIcon } from '@wisemapping/mindplot';
import NodeProperty from '../../../../../classes/model/node-property';
type IconImageTab = {
iconModel: NodeProperty;
iconModel: NodeProperty<string>;
triggerClose: () => void;
};
const IconImageTab = ({ iconModel, triggerClose }: IconImageTab): ReactElement => {
return (
<Box sx={{ width: '350px' }}>
{iconGroups.map((family) => (
<span>
{family.icons.map((icon) => (
{iconGroups.map((family, i) => (
<span key={i}>
{family.icons.map((icon: string) => (
<img
className="panelIcon"
key={icon}

View File

@ -26,7 +26,7 @@ import FormControlLabel from '@mui/material/FormControlLabel';
type IconPickerProp = {
triggerClose: () => void;
iconModel: NodeProperty;
iconModel: NodeProperty<string>;
};
const IconPicker = ({ triggerClose, iconModel }: IconPickerProp): ReactElement => {

View File

@ -24,7 +24,7 @@ import DeleteOutlineOutlinedIcon from '@mui/icons-material/DeleteOutlineOutlined
import { FormattedMessage } from 'react-intl';
const SaveAndDelete = (props: {
model: NodeProperty;
model: NodeProperty<string>;
closeModal: () => void;
submitHandler: () => void;
}): ReactElement => {

View File

@ -29,8 +29,11 @@ import { useIntl } from 'react-intl';
/**
* Url form for toolbar and node contextual editor
*/
const TopicLink = (props: { closeModal: () => void; urlModel: NodeProperty }): ReactElement => {
const [url, setUrl] = useState(props.urlModel.getValue());
const TopicLink = (props: {
closeModal: () => void;
urlModel: NodeProperty<string>;
}): ReactElement => {
const [url, setUrl] = useState<string>(props.urlModel.getValue());
const intl = useIntl();
const submitHandler = () => {

View File

@ -16,7 +16,7 @@
* limitations under the License.
*/
import Box from '@mui/material/Box';
import React, { useState } from 'react';
import React, { ReactElement, useState } from 'react';
import NodeProperty from '../../../../classes/model/node-property';
import Input from '../../input';
import SaveAndDelete from '../save-and-delete';
@ -25,7 +25,10 @@ import { useIntl } from 'react-intl';
/**
* Note form for toolbar and node contextual editor
*/
const TopicNote = (props: { closeModal: () => void; noteModel: NodeProperty | null }) => {
const TopicNote = (props: {
closeModal: () => void;
noteModel: NodeProperty<string> | null;
}): ReactElement => {
const [note, setNote] = useState(props.noteModel.getValue());
const intl = useIntl();

View File

@ -15,7 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React, { ReactElement, ReactElement, useEffect, useState } from 'react';
import React, { ReactElement, useEffect, useState } from 'react';
import MaterialToolbar from '@mui/material/Toolbar';
import MaterialAppBar from '@mui/material/AppBar';
import { ToolbarMenuItem } from '../toolbar';

View File

@ -44,16 +44,16 @@ import TopicNote from '../action-widget/pane/topic-note';
import IconPicker from '../action-widget/pane/icon-picker';
import FontFamilySelector from '../action-widget/button/font-family-selector';
import Editor from '../../classes/model/editor';
import { useIntl } from 'react-intl';
import { IntlShape } from 'react-intl';
const keyTooltip = (msg: string, key: string): string => {
const isMac = window.navigator.platform.toUpperCase().indexOf('MAC') >= 0;
return `${msg} (${isMac ? '⌘' : 'Ctrl'} + ${key})`;
};
export function buildEditorPanelConfig(model: Editor): ActionConfig[] {
export function buildEditorPanelConfig(model: Editor, intl: IntlShape): ActionConfig[] {
const toolbarValueModelBuilder = new NodePropertyValueModelBuilder(model.getDesigner());
const intl = useIntl();
// eslint-disable-next-line react-hooks/rules-of-hooks
const colorAndShapeToolbarConfiguration: ActionConfig = {
icon: <BrushOutlinedIcon />,
tooltip: intl.formatMessage({
@ -102,7 +102,7 @@ export function buildEditorPanelConfig(model: Editor): ActionConfig[] {
{
icon: () => (
<Palette
htmlColor={toolbarValueModelBuilder.getSelectedTopicColorModel().getValue()}
htmlColor={toolbarValueModelBuilder.getSelectedTopicColorModel().getValue() as string}
></Palette>
),
tooltip: intl.formatMessage({
@ -125,7 +125,7 @@ export function buildEditorPanelConfig(model: Editor): ActionConfig[] {
{
icon: () => (
<SquareOutlined
htmlColor={toolbarValueModelBuilder.getColorBorderModel().getValue()}
htmlColor={toolbarValueModelBuilder.getColorBorderModel().getValue() as string}
></SquareOutlined>
),
tooltip: intl.formatMessage({
@ -210,7 +210,7 @@ export function buildEditorPanelConfig(model: Editor): ActionConfig[] {
},
{
icon: () => (
<Palette htmlColor={toolbarValueModelBuilder.getFontColorModel().getValue()}></Palette>
<Palette htmlColor={toolbarValueModelBuilder.getFontColorModel().getValue() as string} />
),
tooltip: intl.formatMessage({
id: 'editor-panel.tooltip-topic-font-color',

View File

@ -16,6 +16,7 @@
* limitations under the License.
*/
import React, { ReactElement } from 'react';
import { useIntl } from 'react-intl';
import ActionConfig from '../../classes/action/action-config';
import Capability from '../../classes/action/capability';
import Model from '../../classes/model/editor';
@ -29,9 +30,10 @@ type EditorToolbarProps = {
const EditorToolbar = ({ model, capability }: EditorToolbarProps): ReactElement => {
let config: ActionConfig[] | undefined;
const intl = useIntl();
if (!capability.isHidden('edition-toolbar') && model?.isMapLoadded()) {
config = buildEditorPanelConfig(model);
config = buildEditorPanelConfig(model, intl);
}
return <span>{config ? <Toolbar configurations={config} /> : <></>}</span>;

View File

@ -15,7 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React, { useCallback, useEffect, useState } from 'react';
import React, { ReactElement, useCallback, useEffect, useState } from 'react';
import Popover from '@mui/material/Popover';
import Model from '../classes/model/editor';
@ -30,6 +30,7 @@ import {
import I18nMsg from '../classes/i18n-msg';
import { theme as defaultEditorTheme } from '../theme';
// eslint-disable-next-line no-restricted-imports
import ThemeProvider from '@mui/material/styles/ThemeProvider';
import { Theme } from '@mui/material/styles';
import { Notifier } from './warning-dialog/styled';
@ -65,13 +66,14 @@ const Editor = ({
onAction,
theme,
accountConfiguration,
}: EditorProps) => {
}: EditorProps): ReactElement => {
const [model, setModel] = useState<Model | undefined>();
// This is required to redraw in case of chansges in the canvas...
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [canvasUpdate, setCanvasUpdate] = useState<number>();
const editorTheme: Theme = theme ? theme : defaultEditorTheme;
const [popoverOpen, popoverTarget, widgetManager] = DefaultWidgetManager.create();
const [popoverOpen, popoverTarget, widgetManager] = DefaultWidgetManager.useCreate();
const capability = new Capability(options.mode, mapInfo.isLocked());
const mindplotRef = useCallback((component: MindplotWebComponent) => {

View File

@ -17,8 +17,8 @@
*/
import KeyboardOutlined from '@mui/icons-material/KeyboardOutlined';
import Typography from '@mui/material/Typography';
import React from 'react';
import { useIntl } from 'react-intl';
import React, { ReactElement } from 'react';
import { IntlShape, useIntl } from 'react-intl';
import ActionConfig from '../../classes/action/action-config';
import Capability from '../../classes/action/capability';
import Editor from '../../classes/model/editor';
@ -30,9 +30,11 @@ import ZoomInOutlinedIcon from '@mui/icons-material/ZoomInOutlined';
import CenterFocusStrongOutlinedIcon from '@mui/icons-material/CenterFocusStrongOutlined';
import Box from '@mui/material/Box';
export function buildZoomToolbarConfig(model: Editor, capability: Capability): ActionConfig[] {
const intl = useIntl();
export function buildZoomToolbarConfig(
model: Editor,
capability: Capability,
intl: IntlShape,
): ActionConfig[] {
return [
{
icon: <CenterFocusStrongOutlinedIcon />,
@ -99,8 +101,9 @@ type ZoomPanelProps = {
capability: Capability;
};
const ZoomPanel = ({ model, capability }: ZoomPanelProps) => {
const config = buildZoomToolbarConfig(model, capability);
const ZoomPanel = ({ model, capability }: ZoomPanelProps): ReactElement => {
const intl = useIntl();
const config = buildZoomToolbarConfig(model, capability, intl);
return (
<Toolbar
configurations={config}