You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
83 lines
2.1 KiB
83 lines
2.1 KiB
4 years ago
|
import { IconDefinition } from "@fortawesome/fontawesome-svg-core";
|
||
|
import { faSpinner } from "@fortawesome/free-solid-svg-icons";
|
||
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||
|
import React, {
|
||
|
FunctionComponent,
|
||
|
MouseEvent,
|
||
|
PropsWithChildren,
|
||
|
useCallback,
|
||
3 years ago
|
useRef,
|
||
4 years ago
|
useState,
|
||
|
} from "react";
|
||
|
import { Button } from "react-bootstrap";
|
||
|
|
||
|
interface CHButtonProps {
|
||
|
disabled?: boolean;
|
||
|
hidden?: boolean;
|
||
|
icon: IconDefinition;
|
||
|
updating?: boolean;
|
||
|
updatingIcon?: IconDefinition;
|
||
|
onClick?: (e: MouseEvent) => void;
|
||
|
}
|
||
|
|
||
|
const ContentHeaderButton: FunctionComponent<CHButtonProps> = (props) => {
|
||
|
const { children, icon, disabled, updating, updatingIcon, onClick } = props;
|
||
|
|
||
|
let displayIcon = icon;
|
||
|
if (updating) {
|
||
|
displayIcon = updatingIcon ? updatingIcon : faSpinner;
|
||
|
}
|
||
|
|
||
|
return (
|
||
|
<Button
|
||
|
variant="dark"
|
||
|
className="d-flex flex-column text-nowrap py-1"
|
||
|
disabled={disabled || updating}
|
||
|
onClick={onClick}
|
||
|
>
|
||
|
<FontAwesomeIcon
|
||
|
className="mx-auto my-1"
|
||
|
icon={displayIcon}
|
||
|
spin={updating}
|
||
|
></FontAwesomeIcon>
|
||
|
<span className="align-bottom text-themecolor small text-center">
|
||
|
{children}
|
||
|
</span>
|
||
|
</Button>
|
||
|
);
|
||
|
};
|
||
|
|
||
|
type CHAsyncButtonProps<T extends () => Promise<any>> = {
|
||
|
promise: T;
|
||
|
onSuccess?: (item: PromiseType<ReturnType<T>>) => void;
|
||
|
} & Omit<CHButtonProps, "updating" | "updatingIcon" | "onClick">;
|
||
|
|
||
|
export function ContentHeaderAsyncButton<T extends () => Promise<any>>(
|
||
|
props: PropsWithChildren<CHAsyncButtonProps<T>>
|
||
|
): JSX.Element {
|
||
|
const { promise, onSuccess, ...button } = props;
|
||
|
|
||
|
const [updating, setUpdate] = useState(false);
|
||
|
|
||
3 years ago
|
const promiseRef = useRef(promise);
|
||
|
const successRef = useRef(onSuccess);
|
||
|
|
||
4 years ago
|
const click = useCallback(() => {
|
||
|
setUpdate(true);
|
||
3 years ago
|
promiseRef.current().then((val) => {
|
||
4 years ago
|
setUpdate(false);
|
||
3 years ago
|
successRef.current && successRef.current(val);
|
||
4 years ago
|
});
|
||
3 years ago
|
}, [successRef, promiseRef]);
|
||
4 years ago
|
|
||
|
return (
|
||
|
<ContentHeaderButton
|
||
|
updating={updating}
|
||
|
onClick={click}
|
||
|
{...button}
|
||
|
></ContentHeaderButton>
|
||
|
);
|
||
|
}
|
||
|
|
||
|
export default ContentHeaderButton;
|