Add token creation dialog
This commit is contained in:
29
matrixgw_frontend/src/widgets/CopyTextChip.tsx
Normal file
29
matrixgw_frontend/src/widgets/CopyTextChip.tsx
Normal file
@@ -0,0 +1,29 @@
|
||||
import { Chip, Tooltip } from "@mui/material";
|
||||
import { useAlert } from "../hooks/contexts_provider/AlertDialogProvider";
|
||||
import { useSnackbar } from "../hooks/contexts_provider/SnackbarProvider";
|
||||
|
||||
export function CopyTextChip(p: { text: string }): React.ReactElement {
|
||||
const snackbar = useSnackbar();
|
||||
const alert = useAlert();
|
||||
|
||||
const copyTextToClipboard = () => {
|
||||
try {
|
||||
navigator.clipboard.writeText(p.text);
|
||||
snackbar(`'${p.text}' was copied to clipboard.`);
|
||||
} catch (e) {
|
||||
console.error(`Failed to copy text to the clipboard! ${e}`);
|
||||
alert(p.text);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Tooltip title="Copy to clipboard">
|
||||
<Chip
|
||||
label={p.text}
|
||||
variant="outlined"
|
||||
style={{ margin: "5px" }}
|
||||
onClick={copyTextToClipboard}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
23
matrixgw_frontend/src/widgets/forms/CheckboxInput.tsx
Normal file
23
matrixgw_frontend/src/widgets/forms/CheckboxInput.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
import { Checkbox, FormControlLabel } from "@mui/material";
|
||||
|
||||
export function CheckboxInput(p: {
|
||||
editable: boolean;
|
||||
label: string;
|
||||
checked: boolean | undefined;
|
||||
onValueChange: (v: boolean) => void;
|
||||
}): React.ReactElement {
|
||||
return (
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
disabled={!p.editable}
|
||||
checked={p.checked}
|
||||
onChange={(e) => {
|
||||
p.onValueChange(e.target.checked);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
label={p.label}
|
||||
/>
|
||||
);
|
||||
}
|
||||
49
matrixgw_frontend/src/widgets/forms/DateInput.tsx
Normal file
49
matrixgw_frontend/src/widgets/forms/DateInput.tsx
Normal file
@@ -0,0 +1,49 @@
|
||||
import { DateField } from "@mui/x-date-pickers";
|
||||
import dayjs from "dayjs";
|
||||
import { TextInput } from "./TextInput";
|
||||
|
||||
export function DateInput(p: {
|
||||
editable?: boolean;
|
||||
required?: boolean;
|
||||
label: string;
|
||||
value: number | undefined | null;
|
||||
checkValue?: (s: number) => boolean;
|
||||
disableFuture?: boolean;
|
||||
disablePast?: boolean;
|
||||
onChange: (newVal: number | undefined | null) => void;
|
||||
}): React.ReactElement {
|
||||
const date = p.value ? dayjs.unix(p.value) : undefined;
|
||||
|
||||
const error = p.value && p.checkValue && !p.checkValue(p.value);
|
||||
|
||||
if (!p.editable)
|
||||
return (
|
||||
<TextInput
|
||||
{...p}
|
||||
checkValue={undefined}
|
||||
value={date !== undefined ? date.format("DD/MM/YYYY") : undefined}
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<DateField
|
||||
clearable
|
||||
value={date}
|
||||
onChange={(v) => p.onChange(v?.unix())}
|
||||
slotProps={{
|
||||
textField: {
|
||||
fullWidth: true,
|
||||
label: p.label,
|
||||
variant: "standard",
|
||||
},
|
||||
inputAdornment: {
|
||||
variant: "standard",
|
||||
},
|
||||
}}
|
||||
disableFuture={p.disableFuture}
|
||||
disablePast={p.disablePast}
|
||||
error={error === true}
|
||||
format="DD/MM/YYYY"
|
||||
/>
|
||||
);
|
||||
}
|
||||
26
matrixgw_frontend/src/widgets/forms/NetworksInput.tsx
Normal file
26
matrixgw_frontend/src/widgets/forms/NetworksInput.tsx
Normal file
@@ -0,0 +1,26 @@
|
||||
import { isIPNetworkValid } from "../../utils/FormUtils";
|
||||
import { TextInput } from "./TextInput";
|
||||
|
||||
function rebuildNetworksList(val?: string): string[] | undefined {
|
||||
if (!val || val.trim() === "") return undefined;
|
||||
|
||||
return val.split(",").map((v) => v.trim());
|
||||
}
|
||||
|
||||
export function NetworksInput(p: {
|
||||
editable?: boolean;
|
||||
label: string;
|
||||
value?: string[];
|
||||
onChange: (n: string[] | undefined) => void;
|
||||
}): React.ReactElement {
|
||||
const textValue = (p.value ?? []).join(", ").trim();
|
||||
return (
|
||||
<TextInput
|
||||
{...p}
|
||||
type="string"
|
||||
value={textValue}
|
||||
onValueChange={(i) => p.onChange(rebuildNetworksList(i))}
|
||||
checkValue={(v) => (rebuildNetworksList(v) ?? []).every(isIPNetworkValid)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
65
matrixgw_frontend/src/widgets/forms/TextInput.tsx
Normal file
65
matrixgw_frontend/src/widgets/forms/TextInput.tsx
Normal file
@@ -0,0 +1,65 @@
|
||||
import { TextField, type TextFieldVariants } from "@mui/material";
|
||||
import type { LenConstraint } from "../../api/ServerApi";
|
||||
|
||||
/**
|
||||
* Text input
|
||||
*/
|
||||
export function TextInput(p: {
|
||||
label?: string;
|
||||
editable?: boolean;
|
||||
required?: boolean;
|
||||
value?: string;
|
||||
onValueChange?: (newVal: string | undefined) => void;
|
||||
size?: LenConstraint;
|
||||
checkValue?: (s: string) => boolean;
|
||||
multiline?: boolean;
|
||||
minRows?: number;
|
||||
maxRows?: number;
|
||||
placeholder?: string;
|
||||
type?: React.HTMLInputTypeAttribute;
|
||||
style?: React.CSSProperties;
|
||||
helperText?: string;
|
||||
variant?: TextFieldVariants;
|
||||
}): React.ReactElement {
|
||||
if (!p.editable && (p.value ?? "") === "") return <></>;
|
||||
|
||||
let valueError = undefined;
|
||||
if (p.value && p.value.length > 0) {
|
||||
if (p.size?.min && p.type !== "number" && p.value.length < p.size.min)
|
||||
valueError = `Please specify at least ${p.size.min} characters !`;
|
||||
if (p.checkValue && !p.checkValue(p.value)) valueError = "Invalid value!";
|
||||
if (
|
||||
p.type === "number" &&
|
||||
p.size &&
|
||||
(Number(p.value) > p.size.max || Number(p.value) < p.size.min)
|
||||
)
|
||||
valueError = "Invalid size range!";
|
||||
}
|
||||
|
||||
return (
|
||||
<TextField
|
||||
label={p.label}
|
||||
required={p.required}
|
||||
value={p.value ?? ""}
|
||||
onChange={(e) =>
|
||||
p.onValueChange?.(
|
||||
e.target.value.length === 0 ? undefined : e.target.value
|
||||
)
|
||||
}
|
||||
slotProps={{
|
||||
input: {
|
||||
readOnly: !p.editable,
|
||||
type: p.type,
|
||||
},
|
||||
htmlInput: { maxLength: p.size?.max, placeholder: p.placeholder },
|
||||
}}
|
||||
variant={p.variant ?? "standard"}
|
||||
style={p.style ?? { width: "100%", marginBottom: "15px" }}
|
||||
multiline={p.multiline}
|
||||
minRows={p.minRows}
|
||||
maxRows={p.maxRows}
|
||||
error={valueError !== undefined}
|
||||
helperText={valueError ?? p.helperText}
|
||||
/>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user