Fix lot of eslint problems

This commit is contained in:
Eric NGUYEN 2022-11-21 13:47:04 +01:00
parent 5b9a0e6b34
commit 8b11c71384
17 changed files with 52 additions and 108 deletions

3
.eslintignore Normal file
View file

@ -0,0 +1,3 @@
/dist
/public
/src/dts

View file

@ -1,4 +1,9 @@
module.exports = { module.exports = {
settings: {
react: {
version: "detect"
}
},
env: { env: {
browser: true, browser: true,
es2021: true es2021: true
@ -43,40 +48,6 @@ module.exports = {
'@typescript-eslint/no-unused-vars': 'error', '@typescript-eslint/no-unused-vars': 'error',
'@typescript-eslint/ban-types': ['error'], '@typescript-eslint/ban-types': ['error'],
'@typescript-eslint/no-floating-promises': 'off', // disabled cuz troublesome for SweetAlert since they never reject '@typescript-eslint/no-floating-promises': 'off', // disabled cuz troublesome for SweetAlert since they never reject
"@typescript-eslint/naming-convention": [
"error",
{
"selector": "default",
"format": ["camelCase"]
},
{
'selector': 'function',
'format': ['PascalCase']
},
{
"selector": "variable",
"format": ["camelCase", "UPPER_CASE"]
},
{
"selector": "parameter",
"format": ["camelCase"],
"leadingUnderscore": "allow"
},
{
'selector': ['enumMember', 'enum'],
'format': ['PascalCase']
},
{
"selector": "memberLike",
"modifiers": ["private"],
"format": ["camelCase"],
"leadingUnderscore": "require"
},
{
"selector": ['typeLike'],
"format": ["PascalCase"],
}
],
// React // React
'react-hooks/rules-of-hooks': 'error', // Checks rules of Hooks 'react-hooks/rules-of-hooks': 'error', // Checks rules of Hooks

View file

@ -1,8 +1,8 @@
import * as React from 'react'; import * as React from 'react';
import { loadEnv } from 'vite'; import { beforeEach, describe, it } from 'vitest';
import { beforeEach, describe, expect, it } from 'vitest'; import { AppState } from '../../Enums/AppState';
import { FAST_BOOT } from '../../utils/default'; import { FAST_BOOT } from '../../utils/default';
import { fireEvent, render, RenderResult, screen } from '../../utils/test-utils'; import { fireEvent, render, RenderResult } from '../../utils/test-utils';
import { App } from './App'; import { App } from './App';
describe.concurrent('App', () => { describe.concurrent('App', () => {
@ -15,7 +15,7 @@ describe.concurrent('App', () => {
}); });
it('New editor', async() => { it('New editor', async() => {
if (FAST_BOOT) { if (FAST_BOOT !== AppState.MainMenu) {
return; return;
} }
@ -24,7 +24,7 @@ describe.concurrent('App', () => {
}, 10000); }, 10000);
it('Load editor by file', () => { it('Load editor by file', () => {
if (FAST_BOOT) { if (FAST_BOOT !== AppState.MainMenu) {
return; return;
} }
@ -37,7 +37,7 @@ describe.concurrent('App', () => {
const load2 = app.getByText(/Load a configuration file/i); const load2 = app.getByText(/Load a configuration file/i);
fireEvent.click(load2); fireEvent.click(load2);
const chooseFile = app.getByText(/Import Save/i); app.getByText(/Import Save/i);
const inputFile: HTMLInputElement = document.querySelector('input[type="file"]') as HTMLInputElement; document.querySelector('input[type="file"]') as HTMLInputElement;
}); });
}); });

View file

@ -297,46 +297,3 @@ function HandleReplace(
return newHistoryBeforeDelete; return newHistoryBeforeDelete;
} }
function HandleInsert(
containers: Map<string, IContainerModel>,
selectedContainer: IContainerModel,
response: ISetContainerListResponse,
configuration: IConfiguration,
history: IHistoryState[],
historyCurrentStep: number
): IHistoryState[] {
const parent = FindContainerById(containers, selectedContainer.properties.id);
if (parent === undefined || parent === null) {
throw new Error('[InsertContainer] Cannot insert in a container that does not exists');
}
const index = parent.children.indexOf(selectedContainer.properties.id);
const newHistoryAfterDelete = DeleteContainer(
selectedContainer.properties.id,
history,
historyCurrentStep
);
const { history: newHistoryBeforeDelete } = AddContainers(
index,
response.Containers,
selectedContainer.properties.parentId,
configuration,
newHistoryAfterDelete,
newHistoryAfterDelete.length - 1
);
// Remove AddContainers from history
if (import.meta.env.PROD) {
newHistoryBeforeDelete.splice(newHistoryBeforeDelete.length - 2, 1);
}
// Rename the last action by Replace
const types = response.Containers.map(container => container.Type);
newHistoryBeforeDelete[newHistoryBeforeDelete.length - 1].lastAction =
`Replace ${selectedContainer.properties.id} by [${types.join(', ')}]`;
return newHistoryBeforeDelete;
}

View file

@ -2,10 +2,7 @@ import './Loader.scss';
import * as React from 'react'; import * as React from 'react';
export interface ILoaderProps { export function Loader(): JSX.Element {
}
export function Loader(props: ILoaderProps): JSX.Element {
return ( return (
<div className='loader'> <div className='loader'>
Loading... Loading...

View file

@ -4,8 +4,6 @@ import { FixedSizeList as List } from 'react-window';
import { MessageType } from '../../Enums/MessageType'; import { MessageType } from '../../Enums/MessageType';
import { IHistoryState } from '../../Interfaces/IHistoryState'; import { IHistoryState } from '../../Interfaces/IHistoryState';
import { IMessage } from '../../Interfaces/IMessage'; import { IMessage } from '../../Interfaces/IMessage';
import { DISABLE_API } from '../../utils/default';
import { GetCircularReplacer } from '../../utils/saveload';
import { TITLE_BAR_HEIGHT } from '../Sidebar/Sidebar'; import { TITLE_BAR_HEIGHT } from '../Sidebar/Sidebar';
import { Text } from '../Text/Text'; import { Text } from '../Text/Text';

View file

@ -95,17 +95,17 @@ export function Container(props: IContainerProps): JSX.Element {
); );
} }
function CreateReactCustomSVG(customSVG: string, props: IContainerProperties): React.ReactNode { function CreateReactCustomSVG(customSVG: string, properties: IContainerProperties): React.ReactNode {
return <Interweave return <Interweave
tagName='g' tagName='g'
disableLineBreaks={true} disableLineBreaks={true}
content={customSVG} content={customSVG}
allowElements={true} allowElements={true}
transform={(node, children) => Transform(node, children, props)} transform={(node, children) => Transform(node, children, properties)}
/>; />;
} }
function Transform(node: HTMLElement, children: Node[], props: IContainerProperties): React.ReactNode { function Transform(node: HTMLElement, children: Node[], properties: IContainerProperties): React.ReactNode {
const supportedTags = ['line', 'path', 'rect']; const supportedTags = ['line', 'path', 'rect'];
if (supportedTags.includes(node.tagName.toLowerCase())) { if (supportedTags.includes(node.tagName.toLowerCase())) {
const attributes: { [att: string]: string | object | null } = {}; const attributes: { [att: string]: string | object | null } = {};
@ -118,13 +118,14 @@ function Transform(node: HTMLElement, children: Node[], props: IContainerPropert
if (attributeValue.startsWith('{userData.') && attributeValue.endsWith('}')) { if (attributeValue.startsWith('{userData.') && attributeValue.endsWith('}')) {
// support for userData // support for userData
if (props.userData === undefined) { const userData = properties.userData;
if (userData === undefined) {
return undefined; return undefined;
} }
const userDataKey = attributeValue.replace(/userData\./, ''); const userDataKey = attributeValue.replace(/userData\./, '');
const prop = Object.entries(props.userData).find(([key]) => `{${key}}` === userDataKey); const prop = Object.entries(userData).find(([key]) => `{${key}}` === userDataKey);
if (prop !== undefined) { if (prop !== undefined) {
attributes[Camelize(attName)] = prop[1]; attributes[Camelize(attName)] = prop[1];
return; return;
@ -139,7 +140,7 @@ function Transform(node: HTMLElement, children: Node[], props: IContainerPropert
return; return;
} }
const prop = Object.entries(props).find(([key]) => `{${key}}` === attributeValue); const prop = Object.entries(properties).find(([key]) => `{${key}}` === attributeValue);
if (prop !== undefined) { if (prop !== undefined) {
attributes[Camelize(attName)] = prop[1]; attributes[Camelize(attName)] = prop[1];
return; return;

View file

@ -26,6 +26,7 @@ export const ID = 'svg';
export function SVG(props: ISVGProps): JSX.Element { export function SVG(props: ISVGProps): JSX.Element {
const [tool, setTool] = React.useState<Tool>(TOOL_PAN); const [tool, setTool] = React.useState<Tool>(TOOL_PAN);
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const [value, setValue] = React.useState<Value>({} as Value); const [value, setValue] = React.useState<Value>({} as Value);
const [scale, setScale] = React.useState<number>(value.a ?? 1); const [scale, setScale] = React.useState<number>(value.a ?? 1);

View file

@ -3,7 +3,6 @@ import { ISymbolModel } from '../../Interfaces/ISymbolModel';
import { RestoreX, TransformX } from '../../utils/svg'; import { RestoreX, TransformX } from '../../utils/svg';
import { InputGroup } from '../InputGroup/InputGroup'; import { InputGroup } from '../InputGroup/InputGroup';
import { TextInputGroup } from '../InputGroup/TextInputGroup'; import { TextInputGroup } from '../InputGroup/TextInputGroup';
import { PositionReferenceSelector } from '../RadioGroupButtons/PositionReferenceSelector';
import { Text } from '../Text/Text'; import { Text } from '../Text/Text';
interface ISymbolFormProps { interface ISymbolFormProps {

View file

@ -14,7 +14,7 @@ interface ISymbolsSidebarProps {
export function SymbolsSidebar(props: ISymbolsSidebarProps): JSX.Element { export function SymbolsSidebar(props: ISymbolsSidebarProps): JSX.Element {
// States // States
const divRef = React.useRef<HTMLDivElement>(null); const divRef = React.useRef<HTMLDivElement>(null);
const [width, height] = useSize(divRef); const height = useSize(divRef)[1];
// Render // Render
const containers = [...props.symbols.values()]; const containers = [...props.symbols.values()];
function Row({ index, style }: { index: number, style: React.CSSProperties }): JSX.Element { function Row({ index, style }: { index: number, style: React.CSSProperties }): JSX.Element {

View file

@ -21,7 +21,7 @@ export function UseWorker(
return () => { return () => {
}; };
}, [state]); }, [state, configurationUrl]);
React.useEffect(() => { React.useEffect(() => {
myWorker.onmessage = (event) => { myWorker.onmessage = (event) => {
@ -53,5 +53,5 @@ export function UseAsync(
.then(async(json: IGetFeedbackResponse) => { .then(async(json: IGetFeedbackResponse) => {
setMessages(json.messages); setMessages(json.messages);
}); });
}, [state]); }, [state, configurationUrl, setMessages]);
} }

View file

@ -40,6 +40,12 @@ export function UseCustomEvents(
setAppState: (appState: AppState) => void setAppState: (appState: AppState) => void
): void { ): void {
useEffect(() => { useEffect(() => {
const current = appRef.current;
if (current === null) {
return;
}
const funcs = new Map<string, () => void>(); const funcs = new Map<string, () => void>();
for (const event of events) { for (const event of events) {
function Func(eventInitDict?: CustomEventInit): void { function Func(eventInitDict?: CustomEventInit): void {
@ -51,7 +57,7 @@ export function UseCustomEvents(
eventInitDict eventInitDict
}); });
} }
appRef.current?.addEventListener(event.name, Func); current.addEventListener(event.name, Func);
funcs.set(event.name, Func); funcs.set(event.name, Func);
} }
return () => { return () => {
@ -60,7 +66,7 @@ export function UseCustomEvents(
if (func === undefined) { if (func === undefined) {
continue; continue;
} }
appRef.current?.removeEventListener(event.name, func); current.removeEventListener(event.name, func);
} }
}; };
}); });

View file

@ -51,8 +51,14 @@ export function UseCustomEvents(
historyCurrentStep, historyCurrentStep,
configuration configuration
}; };
const current = editorRef.current;
if (current === null) {
return;
}
const funcs = new Map<string, () => void>(); const funcs = new Map<string, () => void>();
for (const event of events) { for (const event of events) {
function Func(eventInitDict?: CustomEventInit): void { function Func(eventInitDict?: CustomEventInit): void {
return event.func({ return event.func({
@ -62,7 +68,7 @@ export function UseCustomEvents(
eventInitDict eventInitDict
}); });
} }
editorRef.current?.addEventListener(event.name, Func); current?.addEventListener(event.name, Func);
funcs.set(event.name, Func); funcs.set(event.name, Func);
} }
return () => { return () => {
@ -71,7 +77,7 @@ export function UseCustomEvents(
if (func === undefined) { if (func === undefined) {
continue; continue;
} }
editorRef.current?.removeEventListener(event.name, func); current?.removeEventListener(event.name, func);
} }
}; };
}); });

View file

@ -8,11 +8,12 @@ import { IEditorState } from '../Interfaces/IEditorState';
import { ISymbolModel } from '../Interfaces/ISymbolModel'; import { ISymbolModel } from '../Interfaces/ISymbolModel';
import { Orientation } from '../Enums/Orientation'; import { Orientation } from '../Enums/Orientation';
import { Position } from '../Enums/Position'; import { Position } from '../Enums/Position';
import { AppState } from '../Enums/AppState';
/// EDITOR DEFAULTS /// /// EDITOR DEFAULTS ///
/** Enable fast boot and disable main menu (0 = disabled, 1 = loading, 2 = loaded) */ /** Enable fast boot and disable main menu (0 = disabled, 1 = loading, 2 = loaded) */
export const FAST_BOOT = import.meta.env.PROD ? 2 : 0; export const FAST_BOOT = import.meta.env.PROD ? AppState.Loaded : AppState.MainMenu;
/** Disable any call to the API (default = false) */ /** Disable any call to the API (default = false) */
export const DISABLE_API = false; export const DISABLE_API = false;
@ -184,7 +185,7 @@ const DEFAULT_CONTAINER_STYLE = {
fillOpacity: 1, fillOpacity: 1,
fill: 'white', fill: 'white',
strokeWidth: 2 strokeWidth: 2
} };
/** /**
* Default Main container properties * Default Main container properties

View file

@ -12,7 +12,6 @@ export function * MakeChildrenIterator(containers: Map<string, IContainerModel>,
}; };
} }
/** /**
* Returns a Generator iterating of over the children depth-first * Returns a Generator iterating of over the children depth-first
*/ */

1
src/vite-env.d.ts vendored
View file

@ -1,3 +1,4 @@
// eslint-disable-next-line @typescript-eslint/triple-slash-reference
/// <reference types="vite/client" /> /// <reference types="vite/client" />
interface ImportMetaEnv { interface ImportMetaEnv {

View file

@ -17,6 +17,10 @@
"jsx": "react-jsx" "jsx": "react-jsx"
}, },
"include": ["src"], "include": ["src"],
"exclude": ["test-server"], "exclude": [
"test-server",
"public/**/*",
"src/dts/**/*"
],
"references": [{ "path": "./tsconfig.node.json" }] "references": [{ "path": "./tsconfig.node.json" }]
} }