Skip to content

Commit

Permalink
chore: enhance project release ui
Browse files Browse the repository at this point in the history
  • Loading branch information
abuaboud committed Dec 25, 2024
1 parent d127e2a commit 6bc58a7
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 110 deletions.
5 changes: 1 addition & 4 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,8 @@
"vscode": {
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"dbaeumer.vscode-eslint",
"Angular.ng-template",
"cipchk.cssrem",
"huizhou.githd",
"supermaven.supermaven"
"huizhou.githd"
]
}
},
Expand Down
77 changes: 60 additions & 17 deletions packages/react-ui/src/app/routes/project-release/apply-plan.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
import { useMutation } from '@tanstack/react-query';
import { useState } from 'react';
import { DiffReleaseRequest } from '@activepieces/shared';
import { t } from 'i18next';
import { useState, ReactNode } from 'react';

import { Button, ButtonProps } from '@/components/ui/button';
import { INTERNAL_ERROR_TOAST, useToast } from '@/components/ui/use-toast';
import { ConnectGitDialog } from '@/features/git-sync/components/connect-git-dialog';
import { gitSyncHooks } from '@/features/git-sync/lib/git-sync-hooks';
import { projectReleaseApi } from '@/features/project-version/lib/project-release-api';
import { authenticationSession } from '@/lib/authentication-session';
import {
DiffReleaseRequest,
isNil,
ProjectReleaseType,
} from '@activepieces/shared';

import { CreateReleaseDialog } from './create-release-dialog';
import { Button, ButtonProps } from '@/components/ui/button';
import { ReactNode } from 'react';

type ApplyButtonProps = ButtonProps & {
request: DiffReleaseRequest;
Expand All @@ -14,15 +23,33 @@ type ApplyButtonProps = ButtonProps & {
defaultName?: string;
};

export const ApplyButton = ({ request, children, onSuccess, defaultName, ...props }: ApplyButtonProps) => {
export const ApplyButton = ({
request,
children,
onSuccess,
defaultName,
...props
}: ApplyButtonProps) => {
const { toast } = useToast();
const projectId = authenticationSession.getProjectId()!;
const { gitSync } = gitSyncHooks.useGitSync(projectId, !isNil(projectId));
const [dialogOpen, setDialogOpen] = useState(false);
const [syncPlan, setSyncPlan] = useState<any>(null);
const [loadingRequestId, setLoadingRequestId] = useState<string | null>(null);

const { mutate: loadSyncPlan, isPending: isLoadingApplyPlan } = useMutation({
mutationFn: (request: DiffReleaseRequest) => projectReleaseApi.diff(request),
const { mutate: loadSyncPlan } = useMutation({
mutationFn: (request: DiffReleaseRequest) =>
projectReleaseApi.diff(request),
onSuccess: (plan) => {
if (!plan.operations || plan.operations.length === 0) {
toast({
title: t('No Changes Found'),
description: t('There are no differences to apply'),
variant: 'default',
});
setLoadingRequestId(null);
return;
}
setSyncPlan(plan);
setDialogOpen(true);
setLoadingRequestId(null);
Expand All @@ -33,6 +60,9 @@ export const ApplyButton = ({ request, children, onSuccess, defaultName, ...prop
},
});

const [gitDialogOpen, setGitDialogOpen] = useState(false);
const showGitDialog =
isNil(gitSync) && request.type === ProjectReleaseType.GIT;
const requestId = JSON.stringify(request);
const isLoading = loadingRequestId === requestId;

Expand All @@ -42,22 +72,35 @@ export const ApplyButton = ({ request, children, onSuccess, defaultName, ...prop
{...props}
loading={isLoading}
onClick={() => {
setLoadingRequestId(requestId);
loadSyncPlan(request);
if (showGitDialog) {
setGitDialogOpen(true);
} else {
setLoadingRequestId(requestId);
loadSyncPlan(request);
}
}}
>
{children}
</Button>

{dialogOpen && (
<CreateReleaseDialog
open={dialogOpen}
setOpen={setDialogOpen}
refetch={onSuccess}
plan={syncPlan}
defaultName={defaultName}
{gitDialogOpen ? (
<ConnectGitDialog
open={gitDialogOpen}
setOpen={setGitDialogOpen}
showButton={false}
/>
) : (
dialogOpen && (
<CreateReleaseDialog
open={dialogOpen}
setOpen={setDialogOpen}
refetch={onSuccess}
plan={syncPlan}
defaultName={defaultName}
diffRequest={request}
/>
)
)}
</>
);
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import { t } from 'i18next';
import { useState } from 'react';
import { useForm } from 'react-hook-form';
import * as z from 'zod';

import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
Expand All @@ -17,22 +18,20 @@ import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import { INTERNAL_ERROR_TOAST, toast } from '@/components/ui/use-toast';
import { ConnectGitDialog } from '@/features/git-sync/components/connect-git-dialog';
import { gitSyncHooks } from '@/features/git-sync/lib/git-sync-hooks';
import { projectReleaseApi } from '@/features/project-version/lib/project-release-api';
import { platformHooks } from '@/hooks/platform-hooks';
import { authenticationSession } from '@/lib/authentication-session';
import {
ProjectSyncPlan,
} from '@activepieces/ee-shared';
import { ProjectReleaseType } from '@activepieces/shared';
import { Checkbox } from '@/components/ui/checkbox';
import { ProjectSyncPlan } from '@activepieces/ee-shared';
import { DiffReleaseRequest, ProjectReleaseType } from '@activepieces/shared';

import { OperationChange } from './operation-change';

type GitReleaseDialogProps = {
type CreateReleaseDialogProps = {
open: boolean;
setOpen: (open: boolean) => void;
refetch: () => void;
diffRequest: DiffReleaseRequest;
plan: ProjectSyncPlan | undefined;
defaultName?: string;
};
Expand All @@ -50,8 +49,8 @@ const CreateReleaseDialog = ({
refetch,
plan,
defaultName = '',
}: GitReleaseDialogProps) => {
const [isApplyingChanges, setIsApplyingChanges] = useState(false);
diffRequest,
}: CreateReleaseDialogProps) => {
const { platform } = platformHooks.useCurrentPlatform();
const { gitSync } = gitSyncHooks.useGitSync(
authenticationSession.getProjectId()!,
Expand All @@ -66,54 +65,66 @@ const CreateReleaseDialog = ({
},
});

const { mutate: applyChanges } = useMutation({
const { mutate: applyChanges, isPending } = useMutation({
mutationFn: async () => {
setIsApplyingChanges(true);
if (gitSync) {
projectReleaseApi
.create({
switch (diffRequest.type) {
case ProjectReleaseType.GIT:
if (!gitSync) {
throw new Error('Git sync is not connected');
}
await projectReleaseApi.create({
name: form.getValues('name'),
description: form.getValues('description'),
selectedFlowsIds: Array.from(selectedChanges),
repoId: gitSync.id,
type: ProjectReleaseType.GIT,
})
.then(() => {
refetch();
setOpen(false);
setIsApplyingChanges(false);
type: diffRequest.type,
});
break;
case ProjectReleaseType.ROLLBACK:
await projectReleaseApi.create({
name: form.getValues('name'),
description: form.getValues('description'),
selectedFlowsIds: Array.from(selectedChanges),
projectReleaseId: diffRequest.projectReleaseId,
type: diffRequest.type,
});
break;
}
},
onSuccess: () => {
refetch();
setOpen(false);
},
onError: (error) => {
console.error(error);
toast(INTERNAL_ERROR_TOAST);
},
});

const [selectedChanges, setSelectedChanges] = useState<Set<string>>(new Set(plan?.operations.map(op => op.flow.id) || []));
const [selectedChanges, setSelectedChanges] = useState<Set<string>>(
new Set(plan?.operations.map((op) => op.flow.id) || []),
);

const handleSelectAll = (checked: boolean) => {
if (!plan) return;
setSelectedChanges(
new Set(checked ? plan.operations.map((op) => op.flow.id) : [])
new Set(checked ? plan.operations.map((op) => op.flow.id) : []),
);
};

if (!gitSync) {
return <ConnectGitDialog open={open} setOpen={setOpen} />;
}

return (
<Dialog open={open} onOpenChange={(newOpenState: boolean) => {
if (newOpenState) {
form.reset({
name: '',
description: '',
});
}
setOpen(newOpenState);
}}>
<Dialog
open={open}
onOpenChange={(newOpenState: boolean) => {
if (newOpenState) {
form.reset({
name: '',
description: '',
});
}
setOpen(newOpenState);
}}
>
<DialogContent>
<DialogHeader>
<DialogTitle>{t('Create Git Release')}</DialogTitle>
Expand Down Expand Up @@ -153,12 +164,13 @@ const CreateReleaseDialog = ({
<div className="max-h-[50vh] overflow-y-auto space-y-2">
<div className="flex flex-col gap-2">
<div className="flex items-center gap-2 py-2 border-b">
<Checkbox
<Checkbox
checked={selectedChanges.size === plan?.operations.length}
onCheckedChange={handleSelectAll}
/>
<Label className="text-sm font-medium">
{t('Changes')} ({selectedChanges.size}/{plan?.operations.length || 0})
{t('Changes')} ({selectedChanges.size}/
{plan?.operations.length || 0})
</Label>
</div>
</div>
Expand All @@ -173,8 +185,10 @@ const CreateReleaseDialog = ({
new Set(
checked
? [...selectedChanges, operation.flow.id]
: [...selectedChanges].filter((id) => id !== operation.flow.id)
)
: [...selectedChanges].filter(
(id) => id !== operation.flow.id,
),
),
);
}}
/>
Expand All @@ -197,7 +211,7 @@ const CreateReleaseDialog = ({
</Button>
<Button
size={'sm'}
loading={isApplyingChanges}
loading={isPending}
disabled={!form.formState.isValid || selectedChanges.size === 0}
onClick={() => {
applyChanges();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const OperationChange = React.memo(
<Checkbox checked={selected} onCheckedChange={onSelect} />
{renderDiffInfo(
change.flow.displayName,
<Plus className="w-4 h-4 shrink-0" />
<Plus className="w-4 h-4 shrink-0" />,
)}
</div>
)}
Expand All @@ -41,7 +41,7 @@ export const OperationChange = React.memo(
<Checkbox checked={selected} onCheckedChange={onSelect} />
{renderDiffInfo(
change.targetFlow.displayName,
<UpdateIcon className="w-4 h-4 shrink-0" />
<UpdateIcon className="w-4 h-4 shrink-0" />,
)}
</div>
)}
Expand All @@ -50,7 +50,7 @@ export const OperationChange = React.memo(
<Checkbox checked={selected} onCheckedChange={onSelect} />
{renderDiffInfo(
change.flow.displayName,
<Minus className="w-4 h-4 shrink-0" />
<Minus className="w-4 h-4 shrink-0" />,
)}
</div>
)}
Expand Down
Loading

0 comments on commit 6bc58a7

Please sign in to comment.