diff options
-rw-r--r-- | FrontEnd/package.json | 1 | ||||
-rw-r--r-- | FrontEnd/src/app/utilities/useReverseScrollPositionRemember.ts | 6 | ||||
-rw-r--r-- | FrontEnd/src/app/utilities/useScrollToTop.ts | 8 | ||||
-rw-r--r-- | FrontEnd/src/app/views/common/OperationDialog.tsx | 68 |
4 files changed, 47 insertions, 36 deletions
diff --git a/FrontEnd/package.json b/FrontEnd/package.json index 5ed6261b..acfd3c4c 100644 --- a/FrontEnd/package.json +++ b/FrontEnd/package.json @@ -17,6 +17,7 @@ "i18next-browser-languagedetector": "^6.1.1",
"js-base64": "^3.6.1",
"lodash": "^4.17.21",
+ "moment": "^2.29.1",
"pepjs": "^0.5.3",
"react": "^17.0.1",
"react-bootstrap": "^2.0.0-beta.0",
diff --git a/FrontEnd/src/app/utilities/useReverseScrollPositionRemember.ts b/FrontEnd/src/app/utilities/useReverseScrollPositionRemember.ts index a97d7660..a5812808 100644 --- a/FrontEnd/src/app/utilities/useReverseScrollPositionRemember.ts +++ b/FrontEnd/src/app/utilities/useReverseScrollPositionRemember.ts @@ -41,9 +41,6 @@ const scrollListener = (): void => { reverseScrollToPosition != null && Math.abs(window.scrollY - reverseScrollToPosition) > 50 ) { - console.log( - `Reverse scroll position coerce. Required: ${reverseScrollToPosition}. Actual: ${window.scrollY}.` - ); scrollToReverseScrollPosition(reverseScrollPosition); return; } @@ -51,9 +48,6 @@ const scrollListener = (): void => { reverseScrollToPosition == null && Math.abs(window.scrollY - lastScrollPosition) > 1000 ) { - console.log( - `Scroll jump detected. New: ${window.scrollY}. Old: ${lastScrollPosition}.` - ); scrollToReverseScrollPosition(reverseScrollPosition); return; } diff --git a/FrontEnd/src/app/utilities/useScrollToTop.ts b/FrontEnd/src/app/utilities/useScrollToTop.ts index da63cb0a..892e3545 100644 --- a/FrontEnd/src/app/utilities/useScrollToTop.ts +++ b/FrontEnd/src/app/utilities/useScrollToTop.ts @@ -1,6 +1,6 @@ import React from "react"; import { fromEvent } from "rxjs"; -import { filter, throttleTime, tap } from "rxjs/operators"; +import { filter, throttleTime } from "rxjs/operators"; function useScrollToTop( handler: () => void, @@ -23,11 +23,6 @@ function useScrollToTop( React.useEffect(() => { const subscription = fromEvent(window, "scroll") .pipe( - tap(() => { - console.log( - `Scroll event fired: ${window.scrollY}, time: ${Date.now()}.` - ); - }), filter(() => { return window.scrollY <= option.maxOffset; }), @@ -35,7 +30,6 @@ function useScrollToTop( ) .subscribe(() => { if (enable) { - console.log(`Fire scroll to top event, time: ${Date.now()}.`); handlerRef.current?.(); } }); diff --git a/FrontEnd/src/app/views/common/OperationDialog.tsx b/FrontEnd/src/app/views/common/OperationDialog.tsx index 0ede42e5..ac4c51b9 100644 --- a/FrontEnd/src/app/views/common/OperationDialog.tsx +++ b/FrontEnd/src/app/views/common/OperationDialog.tsx @@ -2,6 +2,7 @@ import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { Form, Button, Modal } from "react-bootstrap"; import { TwitterPicker } from "react-color"; +import moment from "moment"; import { convertI18nText, I18nText, UiLogicError } from "@/common"; @@ -79,26 +80,39 @@ export type OperationDialogInput = | OperationDialogColorInput | OperationDialogDateTimeInput; -type MapOperationInputInfoValueType<T> = T extends OperationDialogTextInput - ? string - : T extends OperationDialogBoolInput - ? boolean - : T extends OperationDialogSelectInput - ? string - : T extends OperationDialogColorInput - ? string | null - : T extends OperationDialogDateTimeInput - ? string - : never; - -const defaultValueMap: { - [T in OperationDialogInput as T["type"]]: MapOperationInputInfoValueType<T>; +interface OperationInputTypeStringToValueTypeMap { + text: string; + bool: boolean; + select: string; + color: string | null; + datetime: string; +} + +type MapOperationInputTypeStringToValueType<Type> = + Type extends keyof OperationInputTypeStringToValueTypeMap + ? OperationInputTypeStringToValueTypeMap[Type] + : never; + +type MapOperationInputInfoValueType<T> = T extends OperationDialogInput + ? MapOperationInputTypeStringToValueType<T["type"]> + : T; + +const initValueMapperMap: { + [T in OperationDialogInput as T["type"]]: ( + item: T + ) => MapOperationInputInfoValueType<T>; } = { - bool: false, - color: null, - datetime: "", - select: "", - text: "", + bool: (item) => item.initValue ?? false, + color: (item) => item.initValue ?? null, + datetime: (item) => { + if (item.initValue != null) { + return moment(item.initValue).format("YYYY-MM-DDTHH:mm:ss"); + } else { + return ""; + } + }, + select: (item) => item.initValue ?? item.options[0].value, + text: (item) => item.initValue ?? "", }; type MapOperationInputInfoValueTypeList< @@ -171,9 +185,13 @@ const OperationDialog = < type ValueType = boolean | string | null | undefined; const [values, setValues] = useState<ValueType[]>( - inputScheme.map((i) => { - if (i.type in defaultValueMap) { - return i.initValue ?? defaultValueMap[i.type]; + inputScheme.map((item) => { + if (item.type in initValueMapperMap) { + return ( + initValueMapperMap[item.type] as ( + i: OperationDialogInput + ) => ValueType + )(item); } else { throw new UiLogicError("Unknown input scheme."); } @@ -199,7 +217,11 @@ const OperationDialog = < setStep({ type: "process" }); props .onProcess( - values as unknown as MapOperationInputInfoValueTypeList<OperationInputInfoList> + values.map((v, index) => { + if (inputScheme[index].type === "datetime" && v !== "") + return new Date(v as string).toISOString(); + else return v; + }) as unknown as MapOperationInputInfoValueTypeList<OperationInputInfoList> ) .then( (d) => { |