mirror of
https://git.mirrors.martin98.com/https://github.com/infiniflow/ragflow.git
synced 2025-08-14 09:56:05 +08:00
### What problem does this PR solve? Feat: Replace the submit form button with ButtonLoading #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
parent
332e6ffbd4
commit
c2c63b07c3
@ -43,8 +43,8 @@ import {
|
|||||||
import RaptorFormFields, {
|
import RaptorFormFields, {
|
||||||
showRaptorParseConfiguration,
|
showRaptorParseConfiguration,
|
||||||
} from '../parse-configuration/raptor-form-fields';
|
} from '../parse-configuration/raptor-form-fields';
|
||||||
|
import { ButtonLoading } from '../ui/button';
|
||||||
import { Input } from '../ui/input';
|
import { Input } from '../ui/input';
|
||||||
import { LoadingButton } from '../ui/loading-button';
|
|
||||||
import { RAGFlowSelect } from '../ui/select';
|
import { RAGFlowSelect } from '../ui/select';
|
||||||
import { DynamicPageRange } from './dynamic-page-range';
|
import { DynamicPageRange } from './dynamic-page-range';
|
||||||
import { useFetchParserListOnMount, useShowAutoKeywords } from './hooks';
|
import { useFetchParserListOnMount, useShowAutoKeywords } from './hooks';
|
||||||
@ -324,9 +324,9 @@ export function ChunkMethodDialog({
|
|||||||
</form>
|
</form>
|
||||||
</Form>
|
</Form>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
<LoadingButton type="submit" form={FormId} loading={loading}>
|
<ButtonLoading type="submit" form={FormId} loading={loading}>
|
||||||
{t('common.save')}
|
{t('common.save')}
|
||||||
</LoadingButton>
|
</ButtonLoading>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Button } from '@/components/ui/button';
|
import { ButtonLoading } from '@/components/ui/button';
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
@ -38,7 +38,11 @@ export function UploaderTabs({ setFiles }: UploaderTabsProps) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function FileUploadDialog({ hideModal, onOk }: IModalProps<File[]>) {
|
export function FileUploadDialog({
|
||||||
|
hideModal,
|
||||||
|
onOk,
|
||||||
|
loading,
|
||||||
|
}: IModalProps<File[]>) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [files, setFiles] = useState<File[]>([]);
|
const [files, setFiles] = useState<File[]>([]);
|
||||||
|
|
||||||
@ -54,14 +58,9 @@ export function FileUploadDialog({ hideModal, onOk }: IModalProps<File[]>) {
|
|||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<UploaderTabs setFiles={setFiles}></UploaderTabs>
|
<UploaderTabs setFiles={setFiles}></UploaderTabs>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
<Button
|
<ButtonLoading type="submit" onClick={handleOk} loading={loading}>
|
||||||
type="submit"
|
|
||||||
variant={'tertiary'}
|
|
||||||
size={'sm'}
|
|
||||||
onClick={handleOk}
|
|
||||||
>
|
|
||||||
{t('common.save')}
|
{t('common.save')}
|
||||||
</Button>
|
</ButtonLoading>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
@ -5,11 +5,11 @@ import {
|
|||||||
DialogHeader,
|
DialogHeader,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
} from '@/components/ui/dialog';
|
} from '@/components/ui/dialog';
|
||||||
import { LoadingButton } from '@/components/ui/loading-button';
|
|
||||||
import { IModalProps } from '@/interfaces/common';
|
import { IModalProps } from '@/interfaces/common';
|
||||||
import { TagRenameId } from '@/pages/add-knowledge/constant';
|
import { TagRenameId } from '@/pages/add-knowledge/constant';
|
||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { ButtonLoading } from '../ui/button';
|
||||||
import { RenameForm } from './rename-form';
|
import { RenameForm } from './rename-form';
|
||||||
|
|
||||||
export function RenameDialog({
|
export function RenameDialog({
|
||||||
@ -33,9 +33,9 @@ export function RenameDialog({
|
|||||||
onOk={onOk}
|
onOk={onOk}
|
||||||
></RenameForm>
|
></RenameForm>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
<LoadingButton type="submit" form={TagRenameId} loading={loading}>
|
<ButtonLoading type="submit" form={TagRenameId} loading={loading}>
|
||||||
{t('common.save')}
|
{t('common.save')}
|
||||||
</LoadingButton>
|
</ButtonLoading>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
@ -3,6 +3,7 @@ import { cva, type VariantProps } from 'class-variance-authority';
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
import { Loader2 } from 'lucide-react';
|
||||||
|
|
||||||
const buttonVariants = cva(
|
const buttonVariants = cva(
|
||||||
'inline-flex items-center justify-center gap-2 whitespace-nowrap 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 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
|
'inline-flex items-center justify-center gap-2 whitespace-nowrap 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 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
|
||||||
@ -57,4 +58,38 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|||||||
);
|
);
|
||||||
Button.displayName = 'Button';
|
Button.displayName = 'Button';
|
||||||
|
|
||||||
|
export const ButtonLoading = React.forwardRef<
|
||||||
|
HTMLButtonElement,
|
||||||
|
ButtonProps & { loading?: boolean }
|
||||||
|
>(
|
||||||
|
(
|
||||||
|
{
|
||||||
|
className,
|
||||||
|
variant,
|
||||||
|
size,
|
||||||
|
asChild = false,
|
||||||
|
children,
|
||||||
|
loading = false,
|
||||||
|
disabled,
|
||||||
|
...props
|
||||||
|
},
|
||||||
|
ref,
|
||||||
|
) => {
|
||||||
|
const Comp = asChild ? Slot : 'button';
|
||||||
|
return (
|
||||||
|
<Comp
|
||||||
|
className={cn(buttonVariants({ variant, size, className }))}
|
||||||
|
ref={ref}
|
||||||
|
{...props}
|
||||||
|
disabled={loading || disabled}
|
||||||
|
>
|
||||||
|
{loading && <Loader2 className="animate-spin" />}
|
||||||
|
{children}
|
||||||
|
</Comp>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
ButtonLoading.displayName = 'ButtonLoading';
|
||||||
|
|
||||||
export { Button, buttonVariants };
|
export { Button, buttonVariants };
|
||||||
|
@ -5,7 +5,6 @@ import {
|
|||||||
DialogHeader,
|
DialogHeader,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
} from '@/components/ui/dialog';
|
} from '@/components/ui/dialog';
|
||||||
import { LoadingButton } from '@/components/ui/loading-button';
|
|
||||||
import { IModalProps } from '@/interfaces/common';
|
import { IModalProps } from '@/interfaces/common';
|
||||||
import { TagRenameId } from '@/pages/add-knowledge/constant';
|
import { TagRenameId } from '@/pages/add-knowledge/constant';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
@ -14,6 +13,7 @@ import { zodResolver } from '@hookform/resolvers/zod';
|
|||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { ButtonLoading } from '@/components/ui/button';
|
||||||
import {
|
import {
|
||||||
Form,
|
Form,
|
||||||
FormControl,
|
FormControl,
|
||||||
@ -118,9 +118,9 @@ export function SetMetaDialog({
|
|||||||
</form>
|
</form>
|
||||||
</Form>
|
</Form>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
<LoadingButton type="submit" form={TagRenameId} loading={loading}>
|
<ButtonLoading type="submit" form={TagRenameId} loading={loading}>
|
||||||
{t('common.save')}
|
{t('common.save')}
|
||||||
</LoadingButton>
|
</ButtonLoading>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { ButtonLoading } from '@/components/ui/button';
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
@ -13,7 +14,6 @@ import {
|
|||||||
FormLabel,
|
FormLabel,
|
||||||
FormMessage,
|
FormMessage,
|
||||||
} from '@/components/ui/form';
|
} from '@/components/ui/form';
|
||||||
import { LoadingButton } from '@/components/ui/loading-button';
|
|
||||||
import { MultiSelect } from '@/components/ui/multi-select';
|
import { MultiSelect } from '@/components/ui/multi-select';
|
||||||
import { useSelectKnowledgeOptions } from '@/hooks/knowledge-hooks';
|
import { useSelectKnowledgeOptions } from '@/hooks/knowledge-hooks';
|
||||||
import { IModalProps } from '@/interfaces/common';
|
import { IModalProps } from '@/interfaces/common';
|
||||||
@ -113,16 +113,11 @@ export function LinkToDatasetDialog({
|
|||||||
onConnectToKnowledgeOk={onConnectToKnowledgeOk}
|
onConnectToKnowledgeOk={onConnectToKnowledgeOk}
|
||||||
></LinkToDatasetForm>
|
></LinkToDatasetForm>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
<LoadingButton
|
<ButtonLoading type="submit" form={FormId} loading={loading}>
|
||||||
type="submit"
|
|
||||||
variant={'tertiary'}
|
|
||||||
form={FormId}
|
|
||||||
loading={loading}
|
|
||||||
>
|
|
||||||
<div className="flex gap-2 items-center">
|
<div className="flex gap-2 items-center">
|
||||||
<Link2 /> Save
|
<Link2 /> Save
|
||||||
</div>
|
</div>
|
||||||
</LoadingButton>
|
</ButtonLoading>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
@ -2,7 +2,7 @@ import {
|
|||||||
AsyncTreeSelect,
|
AsyncTreeSelect,
|
||||||
TreeNodeType,
|
TreeNodeType,
|
||||||
} from '@/components/ui/async-tree-select';
|
} from '@/components/ui/async-tree-select';
|
||||||
import { Button } from '@/components/ui/button';
|
import { ButtonLoading } from '@/components/ui/button';
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
@ -17,7 +17,7 @@ import { isEmpty } from 'lodash';
|
|||||||
import { useCallback, useState } from 'react';
|
import { useCallback, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export function MoveDialog({ hideModal, onOk }: IModalProps<any>) {
|
export function MoveDialog({ hideModal, onOk, loading }: IModalProps<any>) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const { fetchList } = useFetchPureFileList();
|
const { fetchList } = useFetchPureFileList();
|
||||||
@ -69,13 +69,14 @@ export function MoveDialog({ hideModal, onOk }: IModalProps<any>) {
|
|||||||
></AsyncTreeSelect>
|
></AsyncTreeSelect>
|
||||||
</div>
|
</div>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
<Button
|
<ButtonLoading
|
||||||
type="submit"
|
type="submit"
|
||||||
onClick={handleSubmit}
|
onClick={handleSubmit}
|
||||||
disabled={isEmpty(treeValue)}
|
disabled={isEmpty(treeValue)}
|
||||||
|
loading={loading}
|
||||||
>
|
>
|
||||||
{t('common.save')}
|
{t('common.save')}
|
||||||
</Button>
|
</ButtonLoading>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user