mirror of
https://github.com/Steffo99/sophon.git
synced 2024-12-22 14:54:22 +00:00
🧹 Improve GroupCreateBox
code quality
This commit is contained in:
parent
2b47f097b1
commit
6ec92ac07b
2 changed files with 101 additions and 42 deletions
|
@ -4,6 +4,7 @@ import {useAuthorizationContext} from "../../contexts/authorization"
|
||||||
import {useCacheContext} from "../../contexts/cache"
|
import {useCacheContext} from "../../contexts/cache"
|
||||||
import {ManagedResource, ManagedViewSet} from "../../hooks/useManagedViewSet"
|
import {ManagedResource, ManagedViewSet} from "../../hooks/useManagedViewSet"
|
||||||
import {SophonResearchGroup} from "../../types/SophonTypes"
|
import {SophonResearchGroup} from "../../types/SophonTypes"
|
||||||
|
import {Validators} from "../../utils/Validators"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,15 +25,66 @@ export interface GroupCreateBoxProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link Box} to create or edit a {@link SophonResearchGroup}.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
export function GroupCreateBox({viewSet, resource}: GroupCreateBoxProps): JSX.Element | null {
|
export function GroupCreateBox({viewSet, resource}: GroupCreateBoxProps): JSX.Element | null {
|
||||||
const authorization = useAuthorizationContext()
|
const authorization = useAuthorizationContext()
|
||||||
const cache = useCacheContext()
|
const cache = useCacheContext()
|
||||||
|
|
||||||
const name =
|
const name =
|
||||||
useFormState<string>(resource?.value.name ?? "", val => val.length > 0 ? true : undefined)
|
useFormState<string>(
|
||||||
|
resource?.value.name ?? "",
|
||||||
|
Validators.notZeroLength,
|
||||||
|
)
|
||||||
|
|
||||||
const description =
|
const description =
|
||||||
useFormState<string>(resource?.value.description ?? "", val => val.length > 0 ? true : undefined)
|
useFormState<string>(
|
||||||
|
resource?.value.description ?? "",
|
||||||
|
Validators.notZeroLength,
|
||||||
|
)
|
||||||
|
|
||||||
|
const members =
|
||||||
|
useFormState<number[]>(
|
||||||
|
resource?.value.members ?? [],
|
||||||
|
Validators.alwaysValid,
|
||||||
|
)
|
||||||
|
|
||||||
|
const access =
|
||||||
|
useFormState<"OPEN" | "MANUAL" | undefined>(
|
||||||
|
resource?.value.access ?? undefined,
|
||||||
|
Validators.notEmpty,
|
||||||
|
)
|
||||||
|
|
||||||
|
const slug =
|
||||||
|
React.useMemo(
|
||||||
|
() => resource ? resource.value.slug : name.value.replaceAll(/[^A-Za-z0-9-]/g, "-").toLowerCase(),
|
||||||
|
[resource, name],
|
||||||
|
)
|
||||||
|
|
||||||
|
const canAdministrate =
|
||||||
|
React.useMemo(
|
||||||
|
() => {
|
||||||
|
if(resource) {
|
||||||
|
if(!authorization) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if(!authorization.state.user) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if(authorization.state.user.id !== resource.value.owner) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[authorization, resource],
|
||||||
|
)
|
||||||
|
|
||||||
const membersOptions: { [key: string]: number } | undefined =
|
const membersOptions: { [key: string]: number } | undefined =
|
||||||
React.useMemo(
|
React.useMemo(
|
||||||
|
@ -46,17 +98,7 @@ export function GroupCreateBox({viewSet, resource}: GroupCreateBoxProps): JSX.El
|
||||||
[authorization, cache],
|
[authorization, cache],
|
||||||
)
|
)
|
||||||
|
|
||||||
const members =
|
const applyChanges =
|
||||||
useFormState<number[]>(resource?.value.members ?? [], arr => arr.length > 0 ? true : undefined)
|
|
||||||
|
|
||||||
const access =
|
|
||||||
useFormState<"OPEN" | "MANUAL" | undefined>(resource?.value.access ?? undefined, val => (
|
|
||||||
val?.length
|
|
||||||
) ? true : undefined)
|
|
||||||
|
|
||||||
const slug = name.value.replaceAll(/[^A-Za-z0-9-]/g, "-").toLowerCase()
|
|
||||||
|
|
||||||
const onSubmit =
|
|
||||||
React.useCallback(
|
React.useCallback(
|
||||||
async () => {
|
async () => {
|
||||||
if(resource) {
|
if(resource) {
|
||||||
|
@ -68,8 +110,8 @@ export function GroupCreateBox({viewSet, resource}: GroupCreateBoxProps): JSX.El
|
||||||
access: access.value,
|
access: access.value,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
else if(viewSet) {
|
else {
|
||||||
await viewSet.create({
|
await viewSet!.create({
|
||||||
name: name.value,
|
name: name.value,
|
||||||
slug: slug,
|
slug: slug,
|
||||||
description: description.value,
|
description: description.value,
|
||||||
|
@ -81,34 +123,25 @@ export function GroupCreateBox({viewSet, resource}: GroupCreateBoxProps): JSX.El
|
||||||
[viewSet, resource, name, slug, description, members, access],
|
[viewSet, resource, name, slug, description, members, access],
|
||||||
)
|
)
|
||||||
|
|
||||||
const canAdministrate =
|
const canApply =
|
||||||
React.useMemo(
|
|
||||||
() => !resource ||
|
|
||||||
(
|
|
||||||
authorization && authorization.state.user && authorization.state.user.id === resource.value.owner
|
|
||||||
),
|
|
||||||
[authorization, resource],
|
|
||||||
)
|
|
||||||
|
|
||||||
const canSubmit =
|
|
||||||
React.useMemo(
|
React.useMemo(
|
||||||
() => name.validity === true && access.validity === true && Boolean(authorization?.state.user?.username),
|
() => name.validity === true && access.validity === true && Boolean(authorization?.state.user?.username),
|
||||||
[name, access, authorization],
|
[name, access, authorization],
|
||||||
)
|
)
|
||||||
|
|
||||||
if(!authorization?.state.token) {
|
const hasError =
|
||||||
return null
|
React.useMemo(
|
||||||
}
|
() => viewSet?.operationError || resource?.error,
|
||||||
if(!(
|
[viewSet, resource],
|
||||||
viewSet || resource
|
)
|
||||||
)) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
if(!canAdministrate) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
const hasError = viewSet?.operationError || resource?.error
|
if(!authorization?.state.token ||
|
||||||
|
!(
|
||||||
|
viewSet || resource
|
||||||
|
) ||
|
||||||
|
!canAdministrate) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
|
@ -136,14 +169,15 @@ export function GroupCreateBox({viewSet, resource}: GroupCreateBoxProps): JSX.El
|
||||||
/>
|
/>
|
||||||
<Form.Multiselect
|
<Form.Multiselect
|
||||||
label={"Members"}
|
label={"Members"}
|
||||||
options={membersOptions ?? {}} {...members}
|
options={membersOptions ?? {}}
|
||||||
|
{...members}
|
||||||
/>
|
/>
|
||||||
<Form.Field
|
<Form.Field
|
||||||
label={"Owner"}
|
label={"Owner"}
|
||||||
required={true}
|
required={true}
|
||||||
disabled={true}
|
disabled={true}
|
||||||
value={authorization?.state.user?.username}
|
value={authorization.state.user.username}
|
||||||
validity={Boolean(authorization?.state.user?.username)}
|
validity={true}
|
||||||
/>
|
/>
|
||||||
<Form.Select
|
<Form.Select
|
||||||
label={"Access"}
|
label={"Access"}
|
||||||
|
@ -157,8 +191,8 @@ export function GroupCreateBox({viewSet, resource}: GroupCreateBoxProps): JSX.El
|
||||||
<Form.Row>
|
<Form.Row>
|
||||||
<Form.Button
|
<Form.Button
|
||||||
type={"button"}
|
type={"button"}
|
||||||
onClick={onSubmit}
|
onClick={applyChanges}
|
||||||
disabled={!canSubmit}
|
disabled={!canApply}
|
||||||
builtinColor={hasError ? "red" : undefined}
|
builtinColor={hasError ? "red" : undefined}
|
||||||
>
|
>
|
||||||
{resource ? "Edit" : "Create"}
|
{resource ? "Edit" : "Create"}
|
||||||
|
|
25
frontend/src/utils/Validators.ts
Normal file
25
frontend/src/utils/Validators.ts
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import {Validity} from "@steffo/bluelib-react/dist/types"
|
||||||
|
|
||||||
|
|
||||||
|
export class Validators {
|
||||||
|
static alwaysValid<T>(val: T): Validity {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
static notEmpty<T>(val: T): Validity {
|
||||||
|
if(!val) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
static notZeroLength<T extends { length: number }>(val: T): Validity {
|
||||||
|
if(!val) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
if(val.length === 0) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue