Frontend: Keep Input Focus on Change

This commit is contained in:
ADAMJR 2022-01-14 18:08:41 +00:00
parent 090d85f215
commit 372c4410e6
10 changed files with 45 additions and 17 deletions

View File

@ -1,19 +1,20 @@
FROM node:16-alpine3.14
RUN addgroup app && adduser -SG app app
RUN mkdir /app && chown app:app /app `
RUN mkdir /app && chown app:app /app
USER app
WORKDIR /app/backend
COPY --chown=app:app backend/package*.json ./
RUN npm i
WORKDIR /app/frontend
COPY --chown=app:app frontend/package*.json ./
RUN npm i
# WORKDIR /app/frontend
# COPY --chown=app:app ./frontend/package*.json ./
# RUN ln -s ./frontend/src/types /app
# RUN npm i
WORKDIR /app
COPY --chown=app:app . .
# WORKDIR /app/backend
# COPY --chown=app:app ./backend/package*.json ./
# RUN npm i
EXPOSE 3000
EXPOSE 4200
CMD ./bin/start-dev.sh

View File

@ -42,7 +42,7 @@ export default class Themes extends DBWrapper<string, ThemeDocument> {
public parse(styles: string) {
try { parseCSS(styles) }
catch (error: any) {
throw new TypeError(`CSS Error: ${styles}`)
throw new TypeError(`CSS Error: ${error.message}`);
}
}
}

View File

@ -14,9 +14,9 @@ services:
ports: [3000:3000, 4200:4200]
env_file: [./backend/.env, ./frontend/env/.env.dev]
volumes:
- ./backend/src:/app/src
- ./backend/assets:/app/assets
- ./backend/logs:/app/logs
- ./frontend/src:/app/src
- ./backend/src:/app/backend/src
- ./backend/assets:/app/backend/assets
- ./backend/logs:/app/backend/logs
- ./frontend/src:/app/frontend/src
volumes:
accord:

View File

@ -10,7 +10,7 @@ const FileInput: React.FunctionComponent<FileInputProps> = (props) => {
<Input
accept="image/*"
className="pt-5"
label="Avatar Image"
label={props.label ?? 'Image'}
register={(): any => {}}
type="file"
{...props}

View File

@ -8,3 +8,7 @@ input:hover {
input:focus {
border: 1px solid var(--link);
}
input:disabled {
color: var(--muted);
cursor: not-allowed;
}

View File

@ -17,6 +17,7 @@ export interface InputProps {
className?: string;
disabled?: boolean;
tooltip?: string;
setFocusedInputId?: (val: any) => any;
}
const Input: React.FunctionComponent<InputProps & React.AllHTMLAttributes<HTMLInputElement>> = (props) => {
@ -50,6 +51,7 @@ const Input: React.FunctionComponent<InputProps & React.AllHTMLAttributes<HTMLIn
type={type ?? 'text'}
autoFocus={autoFocus}
disabled={disabled}
onFocus={(e) => props.setFocusedInputId?.(e.currentTarget.id)}
{...filterProps(props)}
{...register?.(name, { ...options })}
size={60}

View File

@ -1,4 +1,3 @@
import { TextareaAutosize } from '@material-ui/core';
import classNames from 'classnames';
import React, { useEffect, useState } from 'react';
import { useForm } from 'react-hook-form';
@ -20,11 +19,19 @@ const UserSettingsThemes: React.FunctionComponent = () => {
const themes = useSelector((s: Store.AppState) => s.entities.themes);
const [themeId, setTab] = useState(selfUser.activeThemeId);
const [addMode, enableAddMode] = useState(false);
const [focusedInputId, setFocusedInputId] = useState('');
const theme = getTheme(themeId, themes);
useEffect(() => {
if (!theme) setTab('default');
}, [theme, themeId]);
const refreshFocus = () => {
if (!focusedInputId) return;
const input: HTMLInputElement | null = document.querySelector(`#${focusedInputId}`);
input?.focus();
}
const SideIcons: React.FunctionComponent = () => (
<div className="flex items-center flex-col">
@ -80,7 +87,7 @@ const UserSettingsThemes: React.FunctionComponent = () => {
<div className="mb-10">
<Input
className="float-left w-1/3 mr-3"
className="float-left w-1/3 mr-3 disabled"
label="Code"
name="code"
register={register}
@ -124,6 +131,7 @@ const UserSettingsThemes: React.FunctionComponent = () => {
label="Name"
name="name"
register={register}
setFocusedInputId={setFocusedInputId}
options={{ value: theme.name }} />
<Input
tooltip="The code that is used to share themes."
@ -131,12 +139,16 @@ const UserSettingsThemes: React.FunctionComponent = () => {
label="Code"
name="code"
register={register}
options={{ value: theme.code }} />
options={{ value: theme.code }}
setFocusedInputId={setFocusedInputId}
disabled />
<FileInput
className="w-1/3"
name="iconURL"
label="Icon"
options={{ value: theme.iconURL }}
tooltip="An optional icon for your theme."
setFocusedInputId={setFocusedInputId}
onChange={(e) => {
const file = e.currentTarget?.files?.[0];
if (!file) return;
@ -148,9 +160,11 @@ const UserSettingsThemes: React.FunctionComponent = () => {
<textarea
className="p-2 rounded bg-bg-secondary outline-none border-bg-tertiary hover:border w-1/2 mt-2"
defaultValue={theme.styles}
onFocus={(e) => setFocusedInputId?.(e.currentTarget.id)}
{...register('styles', { value: theme.styles })} />
<SaveChanges
onOpen={refreshFocus}
setValue={setValue}
onSave={onSave}
obj={theme} />

View File

@ -8,6 +8,7 @@ import NormalButton from './buttons/normal-button';
export interface SaveChangesProps {
onSave: (e) => any;
onOpen?: () => any;
onReset?: (e) => any;
/** @deprecated */
setValue?: UseFormSetValue<FieldValues>;
@ -28,6 +29,7 @@ const SaveChanges: React.FunctionComponent<SaveChangesProps> = (props) => {
key: 'saveChanges',
persist: true,
});
props.onOpen?.();
}, [isOpen]);
const onClickSave = (e) => {

4
frontend/types/global.d.ts vendored Normal file
View File

@ -0,0 +1,4 @@
declare global {
const events: EventEmitter;
}
export {};

View File

@ -5,6 +5,7 @@
"dc:down": "docker-compose -f docker-compose.dev.yml down",
"dc:logs": "docker-compose -f docker-compose.dev.yml logs -t",
"dc:ps": "docker-compose -f docker-compose.dev.yml ps",
"dc:inspect": "docker-compose -f docker-compose.dev.yml ps",
"dc:build:prod": "docker-compose -f docker-compose.prod.yml build",
"dc:up:prod": "docker-compose -f docker-compose.prod.yml up -d --build",
"dc:down:prod": "docker-compose -f docker-compose.prod.yml down",