From 38b84bb8051db2f03b152d66c34a1cb4c8944a12 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Fri, 12 Nov 2021 13:12:27 -0300 Subject: fix #7059 --- .../anastasis-webui/src/components/AsyncButton.tsx | 12 +++++- .../src/components/fields/DateInput.tsx | 10 ++++- .../src/components/fields/EmailInput.tsx | 6 +++ .../src/components/fields/NumberInput.tsx | 6 +++ .../src/components/fields/TextInput.tsx | 6 +++ .../src/pages/home/AttributeEntryScreen.tsx | 9 ++++ .../src/pages/home/ConfirmModal.tsx | 9 +++- .../src/pages/home/SecretEditorScreen.tsx | 49 ++++++++++++++-------- .../pages/home/authMethod/AuthMethodEmailSetup.tsx | 4 ++ .../pages/home/authMethod/AuthMethodEmailSolve.tsx | 47 ++++++++++++++------- .../pages/home/authMethod/AuthMethodIbanSetup.tsx | 5 +++ .../pages/home/authMethod/AuthMethodPostSetup.tsx | 35 +++++++++++++--- .../pages/home/authMethod/AuthMethodPostSolve.tsx | 7 +++- .../home/authMethod/AuthMethodQuestionSetup.tsx | 5 +++ .../home/authMethod/AuthMethodQuestionSolve.tsx | 11 +++-- .../pages/home/authMethod/AuthMethodSmsSetup.tsx | 4 ++ .../pages/home/authMethod/AuthMethodSmsSolve.tsx | 47 ++++++++++++++------- .../pages/home/authMethod/AuthMethodTotpSetup.tsx | 9 +++- .../pages/home/authMethod/AuthMethodTotpSolve.tsx | 7 +++- .../pages/home/authMethod/AuthMethodVideoSetup.tsx | 4 ++ 20 files changed, 225 insertions(+), 67 deletions(-) diff --git a/packages/anastasis-webui/src/components/AsyncButton.tsx b/packages/anastasis-webui/src/components/AsyncButton.tsx index 33f3a7258..8f855f29f 100644 --- a/packages/anastasis-webui/src/components/AsyncButton.tsx +++ b/packages/anastasis-webui/src/components/AsyncButton.tsx @@ -20,6 +20,7 @@ */ import { ComponentChildren, h, VNode } from "preact"; +import { useLayoutEffect, useRef } from "preact/hooks"; // import { LoadingModal } from "../modal"; import { useAsync } from "../hooks/async"; // import { Translate } from "../../i18n"; @@ -28,17 +29,26 @@ type Props = { children: ComponentChildren; disabled?: boolean; onClick?: () => Promise; + grabFocus?: boolean; [rest: string]: any; }; export function AsyncButton({ onClick, + grabFocus, disabled, children, ...rest }: Props): VNode { const { isLoading, request } = useAsync(onClick); + const buttonRef = useRef(null); + useLayoutEffect(() => { + if (grabFocus) { + buttonRef.current?.focus(); + } + }, [grabFocus]); + // if (isSlow) { // return ; // } @@ -48,7 +58,7 @@ export function AsyncButton({ return ( - diff --git a/packages/anastasis-webui/src/components/fields/DateInput.tsx b/packages/anastasis-webui/src/components/fields/DateInput.tsx index 0b6a7e316..18ef89908 100644 --- a/packages/anastasis-webui/src/components/fields/DateInput.tsx +++ b/packages/anastasis-webui/src/components/fields/DateInput.tsx @@ -1,4 +1,4 @@ -import { format, isAfter, parse, sub, subYears } from "date-fns"; +import { format, subYears } from "date-fns"; import { h, VNode } from "preact"; import { useLayoutEffect, useRef, useState } from "preact/hooks"; import { DatePicker } from "../picker/DatePicker"; @@ -9,6 +9,7 @@ export interface DateInputProps { tooltip?: string; error?: string; years?: Array; + onConfirm?: () => void; bind: [string, (x: string) => void]; } @@ -44,7 +45,12 @@ export function DateInput(props: DateInputProps): VNode { type="text" class={showError ? "input is-danger" : "input"} value={value} - onInput={(e) => { + onKeyPress={(e) => { + if (e.key === 'Enter' && props.onConfirm) { + props.onConfirm() + } + }} + onInput={(e) => { const text = e.currentTarget.value; setDirty(true); props.bind[1](text); diff --git a/packages/anastasis-webui/src/components/fields/EmailInput.tsx b/packages/anastasis-webui/src/components/fields/EmailInput.tsx index fe676f284..4c35c0686 100644 --- a/packages/anastasis-webui/src/components/fields/EmailInput.tsx +++ b/packages/anastasis-webui/src/components/fields/EmailInput.tsx @@ -7,6 +7,7 @@ export interface TextInputProps { error?: string; placeholder?: string; tooltip?: string; + onConfirm?: () => void; bind: [string, (x: string) => void]; } @@ -37,6 +38,11 @@ export function EmailInput(props: TextInputProps): VNode { placeholder={props.placeholder} type="email" class={showError ? "input is-danger" : "input"} + onKeyPress={(e) => { + if (e.key === 'Enter' && props.onConfirm) { + props.onConfirm() + } + }} onInput={(e) => { setDirty(true); props.bind[1]((e.target as HTMLInputElement).value); diff --git a/packages/anastasis-webui/src/components/fields/NumberInput.tsx b/packages/anastasis-webui/src/components/fields/NumberInput.tsx index e1489eafa..4856131c7 100644 --- a/packages/anastasis-webui/src/components/fields/NumberInput.tsx +++ b/packages/anastasis-webui/src/components/fields/NumberInput.tsx @@ -7,6 +7,7 @@ export interface TextInputProps { error?: string; placeholder?: string; tooltip?: string; + onConfirm?: () => void; bind: [string, (x: string) => void]; } @@ -36,6 +37,11 @@ export function PhoneNumberInput(props: TextInputProps): VNode { type="tel" placeholder={props.placeholder} class={showError ? "input is-danger" : "input"} + onKeyPress={(e) => { + if (e.key === 'Enter' && props.onConfirm) { + props.onConfirm() + } + }} onInput={(e) => { setDirty(true); props.bind[1]((e.target as HTMLInputElement).value); diff --git a/packages/anastasis-webui/src/components/fields/TextInput.tsx b/packages/anastasis-webui/src/components/fields/TextInput.tsx index 4f417730c..efa95d84e 100644 --- a/packages/anastasis-webui/src/components/fields/TextInput.tsx +++ b/packages/anastasis-webui/src/components/fields/TextInput.tsx @@ -8,6 +8,7 @@ export interface TextInputProps { error?: string; placeholder?: string; tooltip?: string; + onConfirm?: () => void; bind: [string, (x: string) => void]; } @@ -37,6 +38,11 @@ export function TextInput(props: TextInputProps): VNode { disabled={props.disabled} placeholder={props.placeholder} class={showError ? "input is-danger" : "input"} + onKeyPress={(e) => { + if (e.key === 'Enter' && props.onConfirm) { + props.onConfirm() + } + }} onInput={(e) => { setDirty(true); props.bind[1]((e.target as HTMLInputElement).value); diff --git a/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.tsx b/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.tsx index 4a937d855..1b50779e0 100644 --- a/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.tsx +++ b/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.tsx @@ -44,6 +44,11 @@ export function AttributeEntryScreen(): VNode { setValue={(v: string) => setAttrs({ ...attrs, [spec.name]: v })} spec={spec} errorMessage={error} + onConfirm={() => { + if (!hasErrors) { + setAskUserIfSure(true) + } + }} value={value} /> ); @@ -104,6 +109,7 @@ interface AttributeEntryFieldProps { setValue: (newValue: string) => void; spec: UserAttributeSpec; errorMessage: string | undefined; + onConfirm: () => void; } const possibleBirthdayYear: Array = []; for (let i = 0; i < 100; i++) { @@ -117,6 +123,7 @@ function AttributeEntryField(props: AttributeEntryFieldProps): VNode { grabFocus={props.isFirst} label={props.spec.label} years={possibleBirthdayYear} + onConfirm={props.onConfirm} error={props.errorMessage} bind={[props.value, props.setValue]} /> @@ -125,6 +132,7 @@ function AttributeEntryField(props: AttributeEntryFieldProps): VNode { @@ -133,6 +141,7 @@ function AttributeEntryField(props: AttributeEntryFieldProps): VNode { diff --git a/packages/anastasis-webui/src/pages/home/ConfirmModal.tsx b/packages/anastasis-webui/src/pages/home/ConfirmModal.tsx index e3561d892..c9c59c1b4 100644 --- a/packages/anastasis-webui/src/pages/home/ConfirmModal.tsx +++ b/packages/anastasis-webui/src/pages/home/ConfirmModal.tsx @@ -1,4 +1,6 @@ +import { differenceInBusinessDays } from "date-fns"; import { ComponentChildren, h, VNode } from "preact"; +import { useLayoutEffect, useRef } from "preact/hooks"; import { AsyncButton } from "../../components/AsyncButton"; export interface ConfirmModelProps { @@ -17,7 +19,7 @@ export function ConfirmModal({ active, description, onCancel, onConfirm, children, danger, disabled, label = "Confirm", cancelLabel = "Dismiss" }: ConfirmModelProps): VNode { return ( -
+