Feat: Add LoadingButton #4368 (#4384)

### What problem does this PR solve?

Feat: Add LoadingButton #4368

### Type of change


- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu 2025-01-07 12:53:06 +08:00 committed by GitHub
parent 16e1681fa4
commit d088a34fe2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 85 additions and 24 deletions

View File

@ -0,0 +1,75 @@
// https://github.com/hsuanyi-chou/shadcn-ui-expansions/blob/main/components/ui/loading-button.tsx
import { cn } from '@/lib/utils';
import { Slot, Slottable } from '@radix-ui/react-slot';
import { cva, type VariantProps } from 'class-variance-authority';
import { Loader2 } from 'lucide-react';
import * as React from 'react';
const buttonVariants = cva(
'inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
{
variants: {
variant: {
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
destructive:
'bg-destructive text-destructive-foreground hover:bg-destructive/90',
outline:
'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
secondary:
'bg-secondary text-secondary-foreground hover:bg-secondary/80',
ghost: 'hover:bg-accent hover:text-accent-foreground',
link: 'text-primary underline-offset-4 hover:underline',
},
size: {
default: 'h-10 px-4 py-2',
sm: 'h-9 rounded-md px-3',
lg: 'h-11 rounded-md px-8',
icon: 'h-10 w-10',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
},
);
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean;
loading?: boolean;
}
const LoadingButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
(
{
className,
loading = false,
children,
disabled,
variant,
size,
asChild = false,
...props
},
ref,
) => {
const Comp = asChild ? Slot : 'button';
return (
<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
disabled={loading || disabled}
{...props}
>
{loading && <Loader2 className="mr-2 h-5 w-5 animate-spin" />}
<Slottable>{children}</Slottable>
</Comp>
);
},
);
LoadingButton.displayName = 'LoadingButton';
export { LoadingButton, buttonVariants };

View File

@ -321,7 +321,7 @@ export const useRenameTag = () => {
isPending: loading,
mutateAsync,
} = useMutation({
mutationKey: ['deleteTag'],
mutationKey: ['renameTag'],
mutationFn: async (params: IRenameTag) => {
const { data } = await renameTag(knowledgeBaseId, params);
if (data.code === 0) {
@ -337,4 +337,8 @@ export const useRenameTag = () => {
return { data, loading, renameTag: mutateAsync };
};
export const useTagIsRenaming = () => {
return useIsMutating({ mutationKey: ['renameTag'] }) > 0;
};
//#endregion

View File

@ -2,7 +2,6 @@ import { LlmModelType } from '@/constants/knowledge';
import { useSetModalState } from '@/hooks/common-hooks';
import {
useFetchKnowledgeBaseConfiguration,
useRenameTag,
useUpdateKnowledge,
} from '@/hooks/knowledge-hooks';
import { useSelectLlmOptionsByModelType } from '@/hooks/llm-hooks';
@ -97,21 +96,6 @@ export const useRenameKnowledgeTag = () => {
hideModal: hideTagRenameModal,
showModal: showFileRenameModal,
} = useSetModalState();
const { renameTag, loading } = useRenameTag();
const onTagRenameOk = useCallback(
async (name: string) => {
const ret = await renameTag({
fromTag: tag,
toTag: name,
});
if (ret === 0) {
hideTagRenameModal();
}
},
[renameTag, tag, hideTagRenameModal],
);
const handleShowTagRenameModal = useCallback(
(record: string) => {
@ -122,9 +106,7 @@ export const useRenameKnowledgeTag = () => {
);
return {
renameLoading: loading,
initialName: tag,
onTagRenameOk,
tagRenameVisible,
hideTagRenameModal,
showTagRenameModal: handleShowTagRenameModal,

View File

@ -74,7 +74,6 @@ export function TagTable() {
showTagRenameModal,
hideTagRenameModal,
tagRenameVisible,
onTagRenameOk,
initialName,
} = useRenameKnowledgeTag();
@ -300,7 +299,6 @@ export function TagTable() {
{tagRenameVisible && (
<RenameDialog
hideModal={hideTagRenameModal}
onOk={onTagRenameOk}
initialName={initialName}
></RenameDialog>
)}

View File

@ -1,4 +1,3 @@
import { Button } from '@/components/ui/button';
import {
Dialog,
DialogContent,
@ -6,6 +5,8 @@ import {
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import { LoadingButton } from '@/components/ui/loading-button';
import { useTagIsRenaming } from '@/hooks/knowledge-hooks';
import { IModalProps } from '@/interfaces/common';
import { TagRenameId } from '@/pages/add-knowledge/constant';
import { useTranslation } from 'react-i18next';
@ -16,6 +17,7 @@ export function RenameDialog({
initialName,
}: IModalProps<any> & { initialName: string }) {
const { t } = useTranslation();
const loading = useTagIsRenaming();
return (
<Dialog open onOpenChange={hideModal}>
@ -28,9 +30,9 @@ export function RenameDialog({
hideModal={hideModal}
></RenameForm>
<DialogFooter>
<Button type="submit" form={TagRenameId}>
<LoadingButton type="submit" form={TagRenameId} loading={loading}>
{t('common.save')}
</Button>
</LoadingButton>
</DialogFooter>
</DialogContent>
</Dialog>