diff --git a/eslint.config.js b/eslint.config.js index 22bad9f0e..312fa61a7 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,36 +1,44 @@ -import js from '@eslint/js' -import globals from 'globals' -import reactHooks from 'eslint-plugin-react-hooks' -import reactRefresh from 'eslint-plugin-react-refresh' -import tseslint from 'typescript-eslint' -import react from 'eslint-plugin-react' +import js from "@eslint/js"; +import globals from "globals"; +import reactHooks from "eslint-plugin-react-hooks"; +import reactRefresh from "eslint-plugin-react-refresh"; +import tseslint from "typescript-eslint"; +import react from "eslint-plugin-react"; export default tseslint.config( - { ignores: ['dist'] }, + { ignores: ["dist"] }, { extends: [ js.configs.recommended, ...tseslint.configs.recommendedTypeChecked, ...tseslint.configs.stylisticTypeChecked, ], - files: ['**/*.{ts,tsx}'], + files: ["**/*.{ts,tsx}"], languageOptions: { ecmaVersion: 2020, globals: globals.browser, }, plugins: { - 'react-hooks': reactHooks, - 'react-refresh': reactRefresh, + "react-hooks": reactHooks, + "react-refresh": reactRefresh, react, }, rules: { ...reactHooks.configs.recommended.rules, - 'react-refresh/only-export-components': [ - 'warn', + "react-refresh/only-export-components": [ + "warn", { allowConstantExport: true }, ], ...react.configs.recommended.rules, - ...react.configs['jsx-runtime'].rules, + ...react.configs["jsx-runtime"].rules, + // TODO WIL: make no-reaching rule for imports + // "import/no-internal-modules": [ + // "error", + // { + // allow: [], + // forbid: ["**/uiAccess/*"], + // }, + // ], }, }, -) +); diff --git a/src/KonvaRootComponent/SignaledToolbarMain.tsx b/src/KonvaRootComponent/SignaledToolbarMain.tsx index 9a47d6e73..533ff6617 100644 --- a/src/KonvaRootComponent/SignaledToolbarMain.tsx +++ b/src/KonvaRootComponent/SignaledToolbarMain.tsx @@ -1,11 +1,13 @@ import { MouseEventHandler } from "react"; -import { ToolbarMain } from "~/components/features"; import { toolbarMain } from "~/signals/uiAccess/toolbarMain"; import { dispatchers } from "~/signals/uiEvents/toolbarMain"; -import { ToolbarMainButtonNames } from "~/components/features/ToolbarMain/enum"; + +import { ToolbarMain } from "~/components/features"; import { LoadingBar } from "~/components/ui"; +import { ToolbarMainButtonNames } from "~/components/features/ToolbarMain/enum"; + export const SignaledToolbarMain = () => { const loadingBar = toolbarMain.loadingBar.signal.value; const buttonProps = Object.values(ToolbarMainButtonNames).reduce( diff --git a/src/signals/uiAccess/toolbarMain.ts b/src/signals/uiAccess/toolbarMain.ts deleted file mode 100644 index cc126543b..000000000 --- a/src/signals/uiAccess/toolbarMain.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { signal } from "@preact/signals-react"; -import { ToolbarMainButtonNames } from "~/components/features/ToolbarMain/enum"; -import { LoadingBarStatus } from "~/components/ui"; - -interface LoadingParInterface { - isShowing: boolean; - progress: number; - status: LoadingBarStatus; - message?: string; -} - -const loadingBarSignal = signal({ - isShowing: true, - progress: 0, - status: LoadingBarStatus.ERROR, - message: undefined, -}); - -const loadingBar = { - signal: loadingBarSignal, - update: (props: Omit) => { - loadingBarSignal.value = { ...loadingBarSignal.value, ...props }; - }, - updateMessage(message: string | undefined) { - loadingBarSignal.value = { - ...loadingBarSignal.value, - message, - }; - }, - updateProgress(progress: number) { - loadingBarSignal.value = { - ...loadingBarSignal.value, - progress, - }; - }, - updateStatus(status: LoadingBarStatus) { - loadingBarSignal.value = { - ...loadingBarSignal.value, - status, - }; - }, - show: (props: Omit) => { - loadingBarSignal.value = { - ...loadingBarSignal.value, - ...props, - isShowing: true, - }; - }, - hide: () => { - loadingBarSignal.value = { ...loadingBarSignal.value, isShowing: false }; - }, -}; - -interface ToolbarMainSignalInterface { - disabled: boolean; - buttonStates: { - [key in ToolbarMainButtonNames]: { disabled: boolean; active: boolean }; - }; -} -const toolbarMainSignal = signal({ - disabled: false, - buttonStates: initButtonStates(), -}); - -export const toolbarMain = { - signal: toolbarMainSignal, - loadingBar: loadingBar, - changeButtonState( - buttonName: ToolbarMainButtonNames, - { disabled, active }: { disabled?: boolean; active?: boolean }, - ) { - toolbarMainSignal.value = { - ...toolbarMainSignal.value, - buttonStates: { - ...toolbarMainSignal.value.buttonStates, - [buttonName]: { - disabled: active ? false : (disabled ?? false), - active: active ?? false, - }, - }, - }; - }, -}; - -function initButtonStates() { - const ret: { [key: string]: { disabled: boolean; active: boolean } } = {}; - Object.values(ToolbarMainButtonNames).forEach((buttonName) => { - ret[buttonName] = { - disabled: false, - active: false, - }; - }); - return ret as ToolbarMainSignalInterface["buttonStates"]; -} diff --git a/src/signals/uiAccess/toolbarMain/index.ts b/src/signals/uiAccess/toolbarMain/index.ts new file mode 100644 index 000000000..0012cb5ea --- /dev/null +++ b/src/signals/uiAccess/toolbarMain/index.ts @@ -0,0 +1,7 @@ +import { toolbarMain as toolbarMainOnly } from "./toolbarMain"; +import { loadingBar } from "./loadingBar"; + +export const toolbarMain = { + ...toolbarMainOnly, + loadingBar, +}; diff --git a/src/signals/uiAccess/toolbarMain/loadingBar.ts b/src/signals/uiAccess/toolbarMain/loadingBar.ts new file mode 100644 index 000000000..f55eb5623 --- /dev/null +++ b/src/signals/uiAccess/toolbarMain/loadingBar.ts @@ -0,0 +1,51 @@ +import { signal } from "@preact/signals-react"; +import { LoadingBarStatus } from "~/components/ui"; + +interface LoadingParInterface { + isShowing: boolean; + progress: number; + status: LoadingBarStatus; + message?: string; +} + +const loadingBarSignal = signal({ + isShowing: false, + progress: 0, + status: LoadingBarStatus.IDLE, + message: undefined, +}); + +export const loadingBar = { + signal: loadingBarSignal, + update: (props: Omit) => { + loadingBarSignal.value = { ...loadingBarSignal.value, ...props }; + }, + updateMessage(message: string | undefined) { + loadingBarSignal.value = { + ...loadingBarSignal.value, + message, + }; + }, + updateProgress(progress: number) { + loadingBarSignal.value = { + ...loadingBarSignal.value, + progress, + }; + }, + updateStatus(status: LoadingBarStatus) { + loadingBarSignal.value = { + ...loadingBarSignal.value, + status, + }; + }, + show: (props: Omit) => { + loadingBarSignal.value = { + ...loadingBarSignal.value, + ...props, + isShowing: true, + }; + }, + hide: () => { + loadingBarSignal.value = { ...loadingBarSignal.value, isShowing: false }; + }, +}; diff --git a/src/signals/uiAccess/toolbarMain/toolbarMain.ts b/src/signals/uiAccess/toolbarMain/toolbarMain.ts new file mode 100644 index 000000000..c5a69e0f0 --- /dev/null +++ b/src/signals/uiAccess/toolbarMain/toolbarMain.ts @@ -0,0 +1,44 @@ +import { signal } from "@preact/signals-react"; +import { ToolbarMainButtonNames } from "~/components/features/ToolbarMain/enum"; + +interface ToolbarMainSignalInterface { + disabled: boolean; + buttonStates: { + [key in ToolbarMainButtonNames]: { disabled: boolean; active: boolean }; + }; +} +const toolbarMainSignal = signal({ + disabled: false, + buttonStates: initButtonStates(), +}); + +export const toolbarMain = { + signal: toolbarMainSignal, + + changeButtonState( + buttonName: ToolbarMainButtonNames, + { disabled, active }: { disabled?: boolean; active?: boolean }, + ) { + toolbarMainSignal.value = { + ...toolbarMainSignal.value, + buttonStates: { + ...toolbarMainSignal.value.buttonStates, + [buttonName]: { + disabled: active ? false : (disabled ?? false), + active: active ?? false, + }, + }, + }; + }, +}; + +function initButtonStates() { + const ret: { [key: string]: { disabled: boolean; active: boolean } } = {}; + Object.values(ToolbarMainButtonNames).forEach((buttonName) => { + ret[buttonName] = { + disabled: false, + active: false, + }; + }); + return ret as ToolbarMainSignalInterface["buttonStates"]; +} diff --git a/src/signals/uiEvents/toolbarMain/index.ts b/src/signals/uiEvents/toolbarMain/index.ts new file mode 100644 index 000000000..d770ba4a7 --- /dev/null +++ b/src/signals/uiEvents/toolbarMain/index.ts @@ -0,0 +1,13 @@ +import { buttonDispatchers, buttonEventsHandlers } from "./toolbarMain"; +import { + loadingBarRetryDispatch, + loadingBarRetryEventHandler, +} from "./loadingBar"; +export const dispatchers = { + ...buttonDispatchers, + loadingBarRetry: loadingBarRetryDispatch, +}; +export const eventsHandlers = { + ...buttonEventsHandlers, + loadingBarRetry: loadingBarRetryEventHandler, +}; diff --git a/src/signals/uiEvents/toolbarMain/loadingBar.ts b/src/signals/uiEvents/toolbarMain/loadingBar.ts new file mode 100644 index 000000000..e6d382d51 --- /dev/null +++ b/src/signals/uiEvents/toolbarMain/loadingBar.ts @@ -0,0 +1,28 @@ +import { MouseEventHandler } from "react"; +import { signal, effect } from "@preact/signals-react"; + +const loadingBarRetryEvent = signal< + React.MouseEvent | undefined +>(); + +let loadingBarRetryEffectCleanup: (() => void) | undefined = undefined; +export const loadingBarRetryEventHandler = { + onClick: (callback: MouseEventHandler) => { + if (loadingBarRetryEffectCleanup) { + loadingBarRetryEffectCleanup(); + } + loadingBarRetryEffectCleanup = effect(() => { + if (loadingBarRetryEvent.value) { + callback(loadingBarRetryEvent.value); + loadingBarRetryEvent.value = undefined; + } + }); + }, +}; + +export const loadingBarRetryDispatch = ( + e: React.MouseEvent, +) => { + console.log("toolbarMain > loadingBar > retry : onClick dispatched", e); + loadingBarRetryEvent.value = e; +}; diff --git a/src/signals/uiEvents/toolbarMain.ts b/src/signals/uiEvents/toolbarMain/toolbarMain.ts similarity index 59% rename from src/signals/uiEvents/toolbarMain.ts rename to src/signals/uiEvents/toolbarMain/toolbarMain.ts index 24bb8dd4e..10a97a5ff 100644 --- a/src/signals/uiEvents/toolbarMain.ts +++ b/src/signals/uiEvents/toolbarMain/toolbarMain.ts @@ -16,10 +16,6 @@ const events = Object.values(ToolbarMainButtonNames).reduce( >; }, ); -const loadingBarRetryEvent = signal< - React.MouseEvent | undefined ->(); - const effectsCleanups = Object.values(ToolbarMainButtonNames).reduce( (acc, buttonName) => { acc[buttonName] = undefined; @@ -29,8 +25,9 @@ const effectsCleanups = Object.values(ToolbarMainButtonNames).reduce( [key in ToolbarMainButtonNames]: (() => void) | undefined; }, ); - -const buttonEventsHandlers = Object.values(ToolbarMainButtonNames).reduce( +export const buttonEventsHandlers = Object.values( + ToolbarMainButtonNames, +).reduce( (acc, buttonName) => { acc[buttonName] = { onClick: (callback: MouseEventHandler) => { @@ -53,25 +50,8 @@ const buttonEventsHandlers = Object.values(ToolbarMainButtonNames).reduce( }; }, ); -let loadingBarRetryEffectCleanup: (() => void) | undefined = undefined; -const loadingBarRetryEventHandler = { - onClick: (callback: MouseEventHandler) => { - if (loadingBarRetryEffectCleanup) { - loadingBarRetryEffectCleanup(); - } - loadingBarRetryEffectCleanup = effect(() => { - if (loadingBarRetryEvent.value) { - callback(loadingBarRetryEvent.value); - loadingBarRetryEvent.value = undefined; - } - }); - }, -}; -export const eventsHandlers = { - ...buttonEventsHandlers, - loadingBarRetry: loadingBarRetryEventHandler, -}; -const buttonDispatchers = Object.values(ToolbarMainButtonNames).reduce( + +export const buttonDispatchers = Object.values(ToolbarMainButtonNames).reduce( (acc, buttonName) => { acc[buttonName] = (e: React.MouseEvent) => { events[buttonName].value = e; @@ -82,11 +62,3 @@ const buttonDispatchers = Object.values(ToolbarMainButtonNames).reduce( [key in ToolbarMainButtonNames]: MouseEventHandler; }, ); -const loadingBarRetryDispatch = (e: React.MouseEvent) => { - console.log("toolbarMain > loadingBar > retry : onClick dispatched", e); - loadingBarRetryEvent.value = e; -}; -export const dispatchers = { - ...buttonDispatchers, - loadingBarRetry: loadingBarRetryDispatch, -};