chore: run prettier
This commit is contained in:
parent
9cdbbc3a00
commit
155d7bb876
76 changed files with 788 additions and 550 deletions
|
@ -9,7 +9,7 @@ interface CodeProps {
|
|||
|
||||
export default ({ dark, className, children }: CodeProps) => (
|
||||
<code
|
||||
className={classNames('font-mono text-sm px-2 py-1 inline-block rounded', className, {
|
||||
className={classNames('inline-block rounded px-2 py-1 font-mono text-sm', className, {
|
||||
'bg-neutral-700': !dark,
|
||||
'bg-neutral-900 text-slate-100': dark,
|
||||
})}
|
||||
|
|
|
@ -50,8 +50,8 @@ const CopyOnClick = ({ text, showInNotification = true, children }: CopyOnClickP
|
|||
{copied && (
|
||||
<Portal>
|
||||
<FadeTransition show duration="duration-250" key={copied ? 'visible' : 'invisible'}>
|
||||
<div className="fixed z-50 bottom-0 right-0 m-4">
|
||||
<div className="rounded-md py-3 px-4 text-slate-200 bg-neutral-600/95 shadow">
|
||||
<div className="fixed bottom-0 right-0 z-50 m-4">
|
||||
<div className="rounded-md bg-neutral-600/95 py-3 px-4 text-slate-200 shadow">
|
||||
<p>
|
||||
{showInNotification
|
||||
? `Copied "${String(text)}" to clipboard.`
|
||||
|
|
|
@ -26,7 +26,15 @@ interface IdObj {
|
|||
id: number;
|
||||
}
|
||||
|
||||
export const Option = <T extends IdObj>({ selectId, id, item, active, isHighlighted, onClick, children }: OptionProps<T>) => {
|
||||
export const Option = <T extends IdObj>({
|
||||
selectId,
|
||||
id,
|
||||
item,
|
||||
active,
|
||||
isHighlighted,
|
||||
onClick,
|
||||
children,
|
||||
}: OptionProps<T>) => {
|
||||
if (isHighlighted === undefined) {
|
||||
isHighlighted = false;
|
||||
}
|
||||
|
@ -39,16 +47,32 @@ export const Option = <T extends IdObj>({ selectId, id, item, active, isHighligh
|
|||
|
||||
if (active) {
|
||||
return (
|
||||
<li id={selectId + '-select-item-' + id} role="option" css={[ tw`relative py-2 pl-3 cursor-pointer select-none text-neutral-200 pr-9 hover:bg-neutral-700`, isHighlighted ? tw`bg-neutral-700` : null ]} onClick={onClick(item)}>
|
||||
<li
|
||||
id={selectId + '-select-item-' + id}
|
||||
role="option"
|
||||
css={[
|
||||
tw`relative py-2 pl-3 cursor-pointer select-none text-neutral-200 pr-9 hover:bg-neutral-700`,
|
||||
isHighlighted ? tw`bg-neutral-700` : null,
|
||||
]}
|
||||
onClick={onClick(item)}
|
||||
>
|
||||
<div css={tw`flex items-center`}>
|
||||
<span css={tw`block font-medium truncate`}>
|
||||
{children}
|
||||
</span>
|
||||
<span css={tw`block font-medium truncate`}>{children}</span>
|
||||
</div>
|
||||
|
||||
<span css={tw`absolute inset-y-0 right-0 flex items-center pr-4`}>
|
||||
<svg css={tw`w-5 h-5 text-primary-400`} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
<path clipRule="evenodd" fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"/>
|
||||
<svg
|
||||
css={tw`w-5 h-5 text-primary-400`}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
clipRule="evenodd"
|
||||
fillRule="evenodd"
|
||||
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</li>
|
||||
|
@ -56,11 +80,17 @@ export const Option = <T extends IdObj>({ selectId, id, item, active, isHighligh
|
|||
}
|
||||
|
||||
return (
|
||||
<li id={selectId + 'select-item-' + id} role="option" css={[ tw`relative py-2 pl-3 cursor-pointer select-none text-neutral-200 pr-9 hover:bg-neutral-700`, isHighlighted ? tw`bg-neutral-700` : null ]} onClick={onClick(item)}>
|
||||
<li
|
||||
id={selectId + 'select-item-' + id}
|
||||
role="option"
|
||||
css={[
|
||||
tw`relative py-2 pl-3 cursor-pointer select-none text-neutral-200 pr-9 hover:bg-neutral-700`,
|
||||
isHighlighted ? tw`bg-neutral-700` : null,
|
||||
]}
|
||||
onClick={onClick(item)}
|
||||
>
|
||||
<div css={tw`flex items-center`}>
|
||||
<span css={tw`block font-normal truncate`}>
|
||||
{children}
|
||||
</span>
|
||||
<span css={tw`block font-normal truncate`}>{children}</span>
|
||||
</div>
|
||||
</li>
|
||||
);
|
||||
|
@ -88,13 +118,27 @@ interface SearchableSelectProps<T> {
|
|||
className?: string;
|
||||
}
|
||||
|
||||
export const SearchableSelect = <T extends IdObj>({ id, name, label, placeholder, selected, setSelected, items, setItems, onSearch, onSelect, getSelectedText, children, className }: SearchableSelectProps<T>) => {
|
||||
const [ loading, setLoading ] = useState(false);
|
||||
const [ expanded, setExpanded ] = useState(false);
|
||||
export const SearchableSelect = <T extends IdObj>({
|
||||
id,
|
||||
name,
|
||||
label,
|
||||
placeholder,
|
||||
selected,
|
||||
setSelected,
|
||||
items,
|
||||
setItems,
|
||||
onSearch,
|
||||
onSelect,
|
||||
getSelectedText,
|
||||
children,
|
||||
className,
|
||||
}: SearchableSelectProps<T>) => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [expanded, setExpanded] = useState(false);
|
||||
|
||||
const [ inputText, setInputText ] = useState('');
|
||||
const [inputText, setInputText] = useState('');
|
||||
|
||||
const [ highlighted, setHighlighted ] = useState<number | null>(null);
|
||||
const [highlighted, setHighlighted] = useState<number | null>(null);
|
||||
|
||||
const searchInput = createRef<HTMLInputElement>();
|
||||
const itemsList = createRef<HTMLDivElement>();
|
||||
|
@ -220,7 +264,7 @@ export const SearchableSelect = <T extends IdObj>({ id, name, label, placeholder
|
|||
window.removeEventListener('mousedown', clickHandler);
|
||||
window.removeEventListener('contextmenu', contextmenuHandler);
|
||||
};
|
||||
}, [ expanded ]);
|
||||
}, [expanded]);
|
||||
|
||||
const onClick = (item: T) => () => {
|
||||
onSelect(item);
|
||||
|
@ -235,13 +279,15 @@ export const SearchableSelect = <T extends IdObj>({ id, name, label, placeholder
|
|||
}
|
||||
|
||||
setInputText(getSelectedText(selected) || '');
|
||||
}, [ selected ]);
|
||||
}, [selected]);
|
||||
|
||||
// This shit is really stupid but works, so is it really stupid?
|
||||
const c = React.Children.map(children, child => React.cloneElement(child as ReactElement, {
|
||||
isHighlighted: ((child as ReactElement).props as OptionProps<T>).id === highlighted,
|
||||
onClick: onClick.bind(child),
|
||||
}));
|
||||
const c = React.Children.map(children, child =>
|
||||
React.cloneElement(child as ReactElement, {
|
||||
isHighlighted: ((child as ReactElement).props as OptionProps<T>).id === highlighted,
|
||||
onClick: onClick.bind(child),
|
||||
}),
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
|
@ -269,33 +315,57 @@ export const SearchableSelect = <T extends IdObj>({ id, name, label, placeholder
|
|||
/>
|
||||
</InputSpinner>
|
||||
|
||||
<div css={[ tw`absolute inset-y-0 right-0 flex items-center pr-2 ml-3`, !expanded && tw`pointer-events-none` ]}>
|
||||
{inputText !== '' && expanded &&
|
||||
<svg css={tw`w-5 h-5 text-neutral-400 cursor-pointer`} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"
|
||||
onMouseDown={e => {
|
||||
e.preventDefault();
|
||||
setInputText('');
|
||||
}}
|
||||
<div
|
||||
css={[
|
||||
tw`absolute inset-y-0 right-0 flex items-center pr-2 ml-3`,
|
||||
!expanded && tw`pointer-events-none`,
|
||||
]}
|
||||
>
|
||||
{inputText !== '' && expanded && (
|
||||
<svg
|
||||
css={tw`w-5 h-5 text-neutral-400 cursor-pointer`}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
onMouseDown={e => {
|
||||
e.preventDefault();
|
||||
setInputText('');
|
||||
}}
|
||||
>
|
||||
<path
|
||||
clipRule="evenodd"
|
||||
fillRule="evenodd"
|
||||
d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
<svg
|
||||
css={tw`w-5 h-5 text-neutral-400 pointer-events-none`}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path clipRule="evenodd" fillRule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"/>
|
||||
</svg>
|
||||
}
|
||||
<svg css={tw`w-5 h-5 text-neutral-400 pointer-events-none`} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
<path clipRule="evenodd" fillRule="evenodd" d="M10 3a1 1 0 01.707.293l3 3a1 1 0 01-1.414 1.414L10 5.414 7.707 7.707a1 1 0 01-1.414-1.414l3-3A1 1 0 0110 3zm-3.707 9.293a1 1 0 011.414 0L10 14.586l2.293-2.293a1 1 0 011.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z"/>
|
||||
<path
|
||||
clipRule="evenodd"
|
||||
fillRule="evenodd"
|
||||
d="M10 3a1 1 0 01.707.293l3 3a1 1 0 01-1.414 1.414L10 5.414 7.707 7.707a1 1 0 01-1.414-1.414l3-3A1 1 0 0110 3zm-3.707 9.293a1 1 0 011.414 0L10 14.586l2.293-2.293a1 1 0 011.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<Dropdown ref={itemsList} expanded={expanded}>
|
||||
{items === null || items.length < 1 ?
|
||||
items === null || inputText.length < 2 ?
|
||||
{items === null || items.length < 1 ? (
|
||||
items === null || inputText.length < 2 ? (
|
||||
<div css={tw`flex flex-row items-center h-10 px-3`}>
|
||||
<p css={tw`text-sm`}>Please type 2 or more characters.</p>
|
||||
</div>
|
||||
:
|
||||
) : (
|
||||
<div css={tw`flex flex-row items-center h-10 px-3`}>
|
||||
<p css={tw`text-sm`}>No results found.</p>
|
||||
</div>
|
||||
:
|
||||
)
|
||||
) : (
|
||||
<ul
|
||||
tabIndex={-1}
|
||||
role={id + '-select'}
|
||||
|
@ -305,7 +375,7 @@ export const SearchableSelect = <T extends IdObj>({ id, name, label, placeholder
|
|||
>
|
||||
{c}
|
||||
</ul>
|
||||
}
|
||||
)}
|
||||
</Dropdown>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,22 @@
|
|||
import { CSSObject } from '@emotion/serialize';
|
||||
import { Field as FormikField, FieldProps } from 'formik';
|
||||
import React, { forwardRef } from 'react';
|
||||
import Select, { ContainerProps, ControlProps, GroupProps, IndicatorContainerProps, IndicatorProps, InputProps, MenuListComponentProps, MenuProps, MultiValueProps, OptionProps, PlaceholderProps, SingleValueProps, StylesConfig, ValueContainerProps } from 'react-select';
|
||||
import Select, {
|
||||
ContainerProps,
|
||||
ControlProps,
|
||||
GroupProps,
|
||||
IndicatorContainerProps,
|
||||
IndicatorProps,
|
||||
InputProps,
|
||||
MenuListComponentProps,
|
||||
MenuProps,
|
||||
MultiValueProps,
|
||||
OptionProps,
|
||||
PlaceholderProps,
|
||||
SingleValueProps,
|
||||
StylesConfig,
|
||||
ValueContainerProps,
|
||||
} from 'react-select';
|
||||
import Async from 'react-select/async';
|
||||
import Creatable from 'react-select/creatable';
|
||||
import tw, { theme } from 'twin.macro';
|
||||
|
@ -42,10 +57,9 @@ export const SelectStyle: StylesConfig<T, any, any> = {
|
|||
borderWidth: '2px',
|
||||
color: theme`colors.neutral.200`,
|
||||
cursor: 'pointer',
|
||||
boxShadow: props.isFocused ?
|
||||
'rgb(255, 255, 255) 0px 0px 0px 0px, rgba(36, 135, 235, 0.5) 0px 0px 0px 2px, rgba(0, 0, 0, 0.1) 0px 4px 6px -1px, rgba(0, 0, 0, 0.06) 0px 2px 4px -1px'
|
||||
:
|
||||
undefined,
|
||||
boxShadow: props.isFocused
|
||||
? 'rgb(255, 255, 255) 0px 0px 0px 0px, rgba(36, 135, 235, 0.5) 0px 0px 0px 2px, rgba(0, 0, 0, 0.1) 0px 4px 6px -1px, rgba(0, 0, 0, 0.06) 0px 2px 4px -1px'
|
||||
: undefined,
|
||||
|
||||
':hover': {
|
||||
borderColor: !props.isFocused ? theme`colors.neutral.400` : theme`colors.primary.300`,
|
||||
|
@ -228,67 +242,74 @@ interface SelectFieldProps {
|
|||
isSearchable?: boolean;
|
||||
|
||||
isCreatable?: boolean;
|
||||
isValidNewOption?: ((
|
||||
inputValue: string,
|
||||
value: ValueType<any, boolean>,
|
||||
options: ReadonlyArray<any>,
|
||||
) => boolean) | undefined;
|
||||
isValidNewOption?:
|
||||
| ((inputValue: string, value: ValueType<any, boolean>, options: ReadonlyArray<any>) => boolean)
|
||||
| undefined;
|
||||
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const SelectField = forwardRef<HTMLElement, SelectFieldProps>(
|
||||
function Select2 ({ id, name, label, description, validate, className, isMulti, isCreatable, ...props }, ref) {
|
||||
const { options } = props;
|
||||
const SelectField = forwardRef<HTMLElement, SelectFieldProps>(function Select2(
|
||||
{ id, name, label, description, validate, className, isMulti, isCreatable, ...props },
|
||||
ref,
|
||||
) {
|
||||
const { options } = props;
|
||||
|
||||
const onChange = (options: Option | Option[], name: string, setFieldValue: (field: string, value: any, shouldValidate?: boolean) => void) => {
|
||||
if (isMulti) {
|
||||
setFieldValue(name, (options as Option[]).map(o => o.value));
|
||||
return;
|
||||
}
|
||||
const onChange = (
|
||||
options: Option | Option[],
|
||||
name: string,
|
||||
setFieldValue: (field: string, value: any, shouldValidate?: boolean) => void,
|
||||
) => {
|
||||
if (isMulti) {
|
||||
setFieldValue(
|
||||
name,
|
||||
(options as Option[]).map(o => o.value),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
setFieldValue(name, (options as Option).value);
|
||||
};
|
||||
setFieldValue(name, (options as Option).value);
|
||||
};
|
||||
|
||||
return (
|
||||
<FormikField innerRef={ref} name={name} validate={validate}>
|
||||
{({ field, form: { errors, touched, setFieldValue } }: FieldProps) => (
|
||||
<div className={className}>
|
||||
{label && <Label htmlFor={id}>{label}</Label>}
|
||||
{isCreatable ?
|
||||
<Creatable
|
||||
{...field}
|
||||
{...props}
|
||||
styles={SelectStyle}
|
||||
options={options}
|
||||
value={(options ? options.find(o => o.value === field.value) : '') as any}
|
||||
onChange={o => onChange(o, name, setFieldValue)}
|
||||
isMulti={isMulti}
|
||||
/>
|
||||
:
|
||||
<Select
|
||||
{...field}
|
||||
{...props}
|
||||
styles={SelectStyle}
|
||||
options={options}
|
||||
value={(options ? options.find(o => o.value === field.value) : '') as any}
|
||||
onChange={o => onChange(o, name, setFieldValue)}
|
||||
isMulti={isMulti}
|
||||
/>
|
||||
}
|
||||
{touched[field.name] && errors[field.name] ?
|
||||
<p css={tw`text-red-200 text-xs mt-1`}>
|
||||
{(errors[field.name] as string).charAt(0).toUpperCase() + (errors[field.name] as string).slice(1)}
|
||||
</p>
|
||||
:
|
||||
description ? <p css={tw`text-neutral-400 text-xs mt-1`}>{description}</p> : null
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
</FormikField>
|
||||
);
|
||||
}
|
||||
);
|
||||
return (
|
||||
<FormikField innerRef={ref} name={name} validate={validate}>
|
||||
{({ field, form: { errors, touched, setFieldValue } }: FieldProps) => (
|
||||
<div className={className}>
|
||||
{label && <Label htmlFor={id}>{label}</Label>}
|
||||
{isCreatable ? (
|
||||
<Creatable
|
||||
{...field}
|
||||
{...props}
|
||||
styles={SelectStyle}
|
||||
options={options}
|
||||
value={(options ? options.find(o => o.value === field.value) : '') as any}
|
||||
onChange={o => onChange(o, name, setFieldValue)}
|
||||
isMulti={isMulti}
|
||||
/>
|
||||
) : (
|
||||
<Select
|
||||
{...field}
|
||||
{...props}
|
||||
styles={SelectStyle}
|
||||
options={options}
|
||||
value={(options ? options.find(o => o.value === field.value) : '') as any}
|
||||
onChange={o => onChange(o, name, setFieldValue)}
|
||||
isMulti={isMulti}
|
||||
/>
|
||||
)}
|
||||
{touched[field.name] && errors[field.name] ? (
|
||||
<p css={tw`text-red-200 text-xs mt-1`}>
|
||||
{(errors[field.name] as string).charAt(0).toUpperCase() +
|
||||
(errors[field.name] as string).slice(1)}
|
||||
</p>
|
||||
) : description ? (
|
||||
<p css={tw`text-neutral-400 text-xs mt-1`}>{description}</p>
|
||||
) : null}
|
||||
</div>
|
||||
)}
|
||||
</FormikField>
|
||||
);
|
||||
});
|
||||
|
||||
interface AsyncSelectFieldProps {
|
||||
id?: string;
|
||||
|
@ -305,43 +326,52 @@ interface AsyncSelectFieldProps {
|
|||
loadOptions(inputValue: string, callback: (options: Array<Option>) => void): void;
|
||||
}
|
||||
|
||||
const AsyncSelectField = forwardRef<HTMLElement, AsyncSelectFieldProps>(
|
||||
function AsyncSelect2 ({ id, name, label, description, validate, className, isMulti, ...props }, ref) {
|
||||
const onChange = (options: Option | Option[], name: string, setFieldValue: (field: string, value: any, shouldValidate?: boolean) => void) => {
|
||||
if (isMulti) {
|
||||
setFieldValue(name, (options as Option[]).map(o => Number(o.value)));
|
||||
return;
|
||||
}
|
||||
const AsyncSelectField = forwardRef<HTMLElement, AsyncSelectFieldProps>(function AsyncSelect2(
|
||||
{ id, name, label, description, validate, className, isMulti, ...props },
|
||||
ref,
|
||||
) {
|
||||
const onChange = (
|
||||
options: Option | Option[],
|
||||
name: string,
|
||||
setFieldValue: (field: string, value: any, shouldValidate?: boolean) => void,
|
||||
) => {
|
||||
if (isMulti) {
|
||||
setFieldValue(
|
||||
name,
|
||||
(options as Option[]).map(o => Number(o.value)),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
setFieldValue(name, Number((options as Option).value));
|
||||
};
|
||||
setFieldValue(name, Number((options as Option).value));
|
||||
};
|
||||
|
||||
return (
|
||||
<FormikField innerRef={ref} name={name} validate={validate}>
|
||||
{({ field, form: { errors, touched, setFieldValue } }: FieldProps) => (
|
||||
<div className={className}>
|
||||
{label && <Label htmlFor={id}>{label}</Label>}
|
||||
<Async
|
||||
{...props}
|
||||
id={id}
|
||||
name={name}
|
||||
styles={SelectStyle}
|
||||
onChange={o => onChange(o, name, setFieldValue)}
|
||||
isMulti={isMulti}
|
||||
/>
|
||||
{touched[field.name] && errors[field.name] ?
|
||||
<p css={tw`text-red-200 text-xs mt-1`}>
|
||||
{(errors[field.name] as string).charAt(0).toUpperCase() + (errors[field.name] as string).slice(1)}
|
||||
</p>
|
||||
:
|
||||
description ? <p css={tw`text-neutral-400 text-xs mt-1`}>{description}</p> : null
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
</FormikField>
|
||||
);
|
||||
}
|
||||
);
|
||||
return (
|
||||
<FormikField innerRef={ref} name={name} validate={validate}>
|
||||
{({ field, form: { errors, touched, setFieldValue } }: FieldProps) => (
|
||||
<div className={className}>
|
||||
{label && <Label htmlFor={id}>{label}</Label>}
|
||||
<Async
|
||||
{...props}
|
||||
id={id}
|
||||
name={name}
|
||||
styles={SelectStyle}
|
||||
onChange={o => onChange(o, name, setFieldValue)}
|
||||
isMulti={isMulti}
|
||||
/>
|
||||
{touched[field.name] && errors[field.name] ? (
|
||||
<p css={tw`text-red-200 text-xs mt-1`}>
|
||||
{(errors[field.name] as string).charAt(0).toUpperCase() +
|
||||
(errors[field.name] as string).slice(1)}
|
||||
</p>
|
||||
) : description ? (
|
||||
<p css={tw`text-neutral-400 text-xs mt-1`}>{description}</p>
|
||||
) : null}
|
||||
</div>
|
||||
)}
|
||||
</FormikField>
|
||||
);
|
||||
});
|
||||
|
||||
export default SelectField;
|
||||
export { AsyncSelectField };
|
||||
|
|
|
@ -44,13 +44,13 @@ export default ({ activity, children }: Props) => {
|
|||
const properties = wrapProperties(activity.properties);
|
||||
|
||||
return (
|
||||
<div className={'grid grid-cols-10 py-4 border-b-2 border-slate-800 last:rounded-b last:border-0 group'}>
|
||||
<div className={'hidden sm:flex sm:col-span-1 items-center justify-center select-none'}>
|
||||
<div className={'flex items-center w-10 h-10 rounded-full bg-slate-600 overflow-hidden'}>
|
||||
<div className={'group grid grid-cols-10 border-b-2 border-slate-800 py-4 last:rounded-b last:border-0'}>
|
||||
<div className={'hidden select-none items-center justify-center sm:col-span-1 sm:flex'}>
|
||||
<div className={'flex h-10 w-10 items-center overflow-hidden rounded-full bg-slate-600'}>
|
||||
<Avatar name={actor?.uuid || 'system'} />
|
||||
</div>
|
||||
</div>
|
||||
<div className={'col-span-10 sm:col-span-9 flex'}>
|
||||
<div className={'col-span-10 flex sm:col-span-9'}>
|
||||
<div className={'flex-1 px-4 sm:px-0'}>
|
||||
<div className={'flex items-center text-slate-50'}>
|
||||
<Tooltip placement={'top'} content={actor?.email || 'System User'}>
|
||||
|
@ -59,7 +59,7 @@ export default ({ activity, children }: Props) => {
|
|||
<span className={'text-slate-400'}> — </span>
|
||||
<Link
|
||||
to={`#${pathTo({ event: activity.event })}`}
|
||||
className={'transition-colors duration-75 active:text-cyan-400 hover:text-cyan-400'}
|
||||
className={'transition-colors duration-75 hover:text-cyan-400 active:text-cyan-400'}
|
||||
>
|
||||
{activity.event}
|
||||
</Link>
|
||||
|
|
|
@ -11,7 +11,7 @@ export default ({ meta }: { meta: Record<string, unknown> }) => {
|
|||
<Dialog open={open} onClose={() => setOpen(false)} hideCloseIcon title={'Metadata'}>
|
||||
<pre
|
||||
className={
|
||||
'bg-slate-900 rounded p-2 font-mono text-sm leading-relaxed overflow-x-scroll whitespace-pre-wrap'
|
||||
'overflow-x-scroll whitespace-pre-wrap rounded bg-slate-900 p-2 font-mono text-sm leading-relaxed'
|
||||
}
|
||||
>
|
||||
{JSON.stringify(meta, null, 2)}
|
||||
|
@ -23,11 +23,11 @@ export default ({ meta }: { meta: Record<string, unknown> }) => {
|
|||
<button
|
||||
aria-describedby={'View additional event metadata'}
|
||||
className={
|
||||
'p-2 transition-colors duration-100 text-slate-400 group-hover:text-slate-300 group-hover:hover:text-slate-50'
|
||||
'p-2 text-slate-400 transition-colors duration-100 group-hover:text-slate-300 group-hover:hover:text-slate-50'
|
||||
}
|
||||
onClick={() => setOpen(true)}
|
||||
>
|
||||
<ClipboardListIcon className={'w-5 h-5'} />
|
||||
<ClipboardListIcon className={'h-5 w-5'} />
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -12,7 +12,7 @@ export default ({ type, className, children }: AlertProps) => {
|
|||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
'flex items-center border-l-8 text-slate-50 rounded-md shadow px-4 py-3',
|
||||
'flex items-center rounded-md border-l-8 px-4 py-3 text-slate-50 shadow',
|
||||
{
|
||||
['border-red-500 bg-red-500/25']: type === 'danger',
|
||||
['border-yellow-500 bg-yellow-500/25']: type === 'warning',
|
||||
|
@ -21,9 +21,9 @@ export default ({ type, className, children }: AlertProps) => {
|
|||
)}
|
||||
>
|
||||
{type === 'danger' ? (
|
||||
<ShieldExclamationIcon className={'w-6 h-6 text-red-400 mr-2'} />
|
||||
<ShieldExclamationIcon className={'mr-2 h-6 w-6 text-red-400'} />
|
||||
) : (
|
||||
<ExclamationIcon className={'w-6 h-6 text-yellow-500 mr-2'} />
|
||||
<ExclamationIcon className={'mr-2 h-6 w-6 text-yellow-500'} />
|
||||
)}
|
||||
{children}
|
||||
</div>
|
||||
|
|
|
@ -73,8 +73,8 @@ export default ({
|
|||
open={open}
|
||||
onClose={onDialogClose}
|
||||
>
|
||||
<div className={'fixed inset-0 bg-slate-900/50 z-40'} />
|
||||
<div className={'fixed inset-0 overflow-y-auto z-50'}>
|
||||
<div className={'fixed inset-0 z-40 bg-slate-900/50'} />
|
||||
<div className={'fixed inset-0 z-50 overflow-y-auto'}>
|
||||
<div
|
||||
ref={container}
|
||||
className={styles.container}
|
||||
|
@ -89,9 +89,9 @@ export default ({
|
|||
variants={variants}
|
||||
className={styles.panel}
|
||||
>
|
||||
<div className={'flex p-6 pb-0 overflow-y-auto'}>
|
||||
<div className={'flex overflow-y-auto p-6 pb-0'}>
|
||||
{iconPosition === 'container' && icon}
|
||||
<div className={'flex-1 max-h-[70vh] min-w-0'}>
|
||||
<div className={'max-h-[70vh] min-w-0 flex-1'}>
|
||||
<div className={'flex items-center'}>
|
||||
{iconPosition !== 'container' && icon}
|
||||
<div>
|
||||
|
|
|
@ -8,7 +8,7 @@ export default ({ children }: { children: React.ReactNode }) => {
|
|||
|
||||
useDeepCompareEffect(() => {
|
||||
setFooter(
|
||||
<div className={'px-6 py-3 bg-slate-700 flex items-center justify-end space-x-3 rounded-b'}>
|
||||
<div className={'flex items-center justify-end space-x-3 rounded-b bg-slate-700 px-6 py-3'}>
|
||||
{children}
|
||||
</div>,
|
||||
);
|
||||
|
|
|
@ -18,7 +18,7 @@ export default ({ type, position, className }: DialogIconProps) => {
|
|||
|
||||
setIcon(
|
||||
<div className={classNames(styles.dialog_icon, styles[type], className)}>
|
||||
<Icon className={'w-6 h-6'} />
|
||||
<Icon className={'h-6 w-6'} />
|
||||
</div>,
|
||||
);
|
||||
}, [type, className]);
|
||||
|
|
|
@ -12,7 +12,7 @@ interface Props {
|
|||
}
|
||||
|
||||
const DropdownGap = ({ invisible }: { invisible?: boolean }) => (
|
||||
<div className={classNames('border m-2', { 'border-neutral-700': !invisible, 'border-transparent': invisible })} />
|
||||
<div className={classNames('m-2 border', { 'border-neutral-700': !invisible, 'border-transparent': invisible })} />
|
||||
);
|
||||
|
||||
type TypedChild = (React.ReactChild | React.ReactFragment | React.ReactPortal) & {
|
||||
|
|
|
@ -37,7 +37,7 @@ const PaginationFooter = ({ pagination, className, onPageSelect }: Props) => {
|
|||
});
|
||||
|
||||
return (
|
||||
<div className={classNames('flex items-center justify-between my-2', className)}>
|
||||
<div className={classNames('my-2 flex items-center justify-between', className)}>
|
||||
<p className={'text-sm text-neutral-500'}>
|
||||
Showing
|
||||
<span className={'font-semibold text-neutral-400'}>
|
||||
|
@ -50,7 +50,7 @@ const PaginationFooter = ({ pagination, className, onPageSelect }: Props) => {
|
|||
{pagination.totalPages > 1 && (
|
||||
<div className={'flex space-x-1'}>
|
||||
<Button.Text {...buttonProps(1)} disabled={pages.previous.length !== 2}>
|
||||
<ChevronDoubleLeftIcon className={'w-3 h-3'} />
|
||||
<ChevronDoubleLeftIcon className={'h-3 w-3'} />
|
||||
</Button.Text>
|
||||
{pages.previous.reverse().map(value => (
|
||||
<Button.Text key={`previous-${value}`} {...buttonProps(value)}>
|
||||
|
@ -66,7 +66,7 @@ const PaginationFooter = ({ pagination, className, onPageSelect }: Props) => {
|
|||
</Button.Text>
|
||||
))}
|
||||
<Button.Text {...buttonProps(total)} disabled={pages.next.length !== 2}>
|
||||
<ChevronDoubleRightIcon className={'w-3 h-3'} />
|
||||
<ChevronDoubleRightIcon className={'h-3 w-3'} />
|
||||
</Button.Text>
|
||||
</div>
|
||||
)}
|
||||
|
|
|
@ -3,14 +3,18 @@ import { PaginationDataSet } from '@/api/http';
|
|||
|
||||
const TFootPaginated = ({ pagination, span }: { span: number; pagination: PaginationDataSet }) => {
|
||||
const start = (pagination.currentPage - 1) * pagination.perPage;
|
||||
const end = ((pagination.currentPage - 1) * pagination.perPage) + pagination.count;
|
||||
const end = (pagination.currentPage - 1) * pagination.perPage + pagination.count;
|
||||
|
||||
return (
|
||||
<tfoot>
|
||||
<tr className={'bg-neutral-800'}>
|
||||
<td scope={'col'} colSpan={span} className={'px-4 py-2'}>
|
||||
<p className={'text-sm text-neutral-500'}>
|
||||
Showing <span className={'font-semibold text-neutral-400'}>{Math.max(start, Math.min(pagination.total, 1))}</span> to
|
||||
Showing{' '}
|
||||
<span className={'font-semibold text-neutral-400'}>
|
||||
{Math.max(start, Math.min(pagination.total, 1))}
|
||||
</span>{' '}
|
||||
to
|
||||
<span className={'font-semibold text-neutral-400'}>{end}</span> of
|
||||
<span className={'font-semibold text-neutral-400'}>{pagination.total}</span> results.
|
||||
</p>
|
||||
|
|
|
@ -108,7 +108,7 @@ export default ({ children, ...props }: Props) => {
|
|||
ay || 0,
|
||||
)}px) rotate(45deg)`,
|
||||
}}
|
||||
className={classNames('absolute bg-slate-900 w-3 h-3', side)}
|
||||
className={classNames('absolute h-3 w-3 bg-slate-900', side)}
|
||||
/>
|
||||
)}
|
||||
</motion.div>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue