Files
calendar/packages/features/ee/workflows/components/v2/EventWorkflowsTab.tsx
T
+3 eeabb53c82 V2 Workflows (#4047)
* Fix breadcrumb colors

* HorizontalTabs

* Team List Item WIP

* Horizontal Tabs

* Cards

* Remove team list item WIP

* Login Page

* Add welcome back i118n

* EventType page work

* Update EventType Icons

* WIP Availability

* Horizontal Tab Work

* Add build command for in root

* Update build DIr/command

* Add Edit Button + change buttons to v2

* Availablitiy page

* Fix IPAD

* Make mobile look a little nicer

* WIP bookingshell

* Remove list items from breaking build

* Mian bulk of Booking Page.

* Few updates to components

* Fix chormatic feedback

* Fix banner

* Fix Empty Screen

* Text area + embded window fixes

* Semi fix avatar

* Troubleshoot container + Active on count

* Improve mobile

* NITS

* Fix padding on input

* Fix icons

* Starting to move event types settings to tabs

* Begin migration to single page form

* Single page tabs

* Limits Page

* Advanced tab

* Add RHF to dependancies

* Most of advanced tab

* Solved RHF mismtach

* Build fixes

* RHF conditionals fixes

* Improved legibility

* Major refactor/organisation into optional V2 UI

* Portal EditLocationModal

* Fix dialoug form

* Update imports

* Auto Animate + custom inputs WIP

* Custom Inputs

* WIP Apps

* Fixing stories imports

* Stripe app

* Remove duplicate dialog

* Remove duplicate dialog

* add Test action button + UI improvements

* add test action functionality

* Fix embed URL

* Fix app toggles + number of active apps

* Fix container padding on disabledBorder prop

* Removes strict

* add confirmation dialog before sending SMS

* code clean up

* show error message if test action fails

* disable test action button in edit mode

* fixes SMS testing

* use updated values

* fix wrongly updated data in useEffect

* fix typo

* code clean up

* EventType Team page WIP

* Fix embed

* NIT

* Add Darkmode gray color

* V2 Shell WIP

* setup folders for v2

* add lost translations from merge

* add all files to v2 + redesign /workflows

* use custom template as default template

* add first version of v2 for workflow editing page

* Fix headings on shell V2

* Fix mobile layout with V2 shell

* V2 create event type button

* Checked Team Select

* Hidden to happen on save - not on toggle

* Team Attendee Select animation

* Fix scheduling type and remove multi select label

* Fix overflow on teams url

* use fi icon for down arrow

* add v2 shell

* add trigger badge

* Even Type move order handles

* fix save button

* enable editing of workflow name

* improve delete workflow functionality

* adjust empty screen

* make trigger start with uppercase

* change trash icon

* Fix Embed TS errors

* Fix TS errors

* Fix Eslint errors

* Fix TS errors for UI

* Fix ESLINT error

* create component for time and timeUnit input/dropdown

* add workflows to v2 early access middleware

* fix type issues

* added SidebarCard for promo to v2 and storybook (#3906)

Co-authored-by: Julian Benegas <julianbenegas99@gmail.com>
Co-authored-by: Alan <alannnc@gmail.com>
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>

* Tooltip Provider - Wrapper due to dep upgrade

* public event type list darkmode

* V2 Color changes to public booking

* adjust delete and edit button

* create custom empty screen for worklows

* add workflow examples to empty page

* add loading state to button when creating first workflow

* Show action as workflow name when no name exists

* if no input leave name empty when updating workflow

* use reminder template when creating workflow

* improve time unit dropdown

* Remove unused component

* Fix typecheck

* add loading state to new workflow button

* add label before action dropdown

* fixing badges in worflow list

* use lighter color for untitled workflows

* fix not showing nr of active eventtypes in workflow list

* add workflows to event types

* implement v2 desing for AddActionDialog

* improve phone input

* rounded borders for phoneInput in add action dialog

* improve message input

* fix mobile view for editing page

* use md breakpoint for mobile view

* finish workflows in event type settings

* code cleanup

* code cleanup

* fix bug in testing workflow action

* add v2 design for addition inputs as variables dialog

* add V2 design for add variable dropdown

* add notification icons to trigger badge

* improve mobile version of workflows in eventtypes

* remove ring from time before input

* fix bug when workflow has no steps

* Final UI improvements/fixes

* code clean-up

* code clean-up

* code clean-up

* use v2 design for license required

* fix translation issues

* fix adding variables in different language in old design

* limit for pro users only for now

* fix import

* fix mobile view for empty screen

* ues destructive button color for deleting workfow

* remove padding at button of creation dialog

* V2 Settings - Security View (#4018)

* Create change password screen

* Add two factor auth screen

* Add two factor auth screen

* Remove header file

* Updates middleware and rewrites

* Adds Meta component to handle layout headings/metadata (#4021)

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
Co-authored-by: zomars <zomars@me.com>

* fix: rate limit auth (#3820)

* fix: rate limit auth

* fix: replace lru-cache w memory-cache

* remove comments

* fix: yarn.lock

* fix: remove changes yarn lock

* fix: add missing EOL empty liune

* fix: move rate limiter so it kicks the last, limit to 10 tries per minute

* fix: move limiter w rest of code

* test: trying fix onboardong

* fix: undo changes in globalSetup.ts

* test: fix disable login for onboarding

* fix: use username instead of email for token check

* fix: tests

* fix: don't run on test

* fix: add missing comma

* fix: remove uniqueTokenPerInterval

* fix: add errorcode to packages lib auth

* Update packages/lib/rateLimit.ts

fix: improve readability

Co-authored-by: Omar López <zomars@me.com>

* Update packages/lib/rateLimit.ts

fix: no unnecessary any

Co-authored-by: Omar López <zomars@me.com>

* Update packages/lib/rateLimit.ts

fix: improve readability

Co-authored-by: Omar López <zomars@me.com>

* fix: rename interval -> intervalInMs

* fix: check user.email not username which could be empty

* fix: rateLimit update all naming

Co-authored-by: Agusti Fernandez Pardo <git@agusti.me>
Co-authored-by: Omar López <zomars@me.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>

* Adds deprecation comments

Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: zomars <zomars@me.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
Co-authored-by: Julian Benegas <julianbenegas99@gmail.com>
Co-authored-by: Alan <alannnc@gmail.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com>
Co-authored-by: Agusti Fernandez Pardo <6601142+agustif@users.noreply.github.com>
Co-authored-by: Agusti Fernandez Pardo <git@agusti.me>
2022-08-31 13:42:37 -06:00

204 lines
6.6 KiB
TypeScript

import { WorkflowActions } from "@prisma/client";
import Link from "next/link";
import { useRouter } from "next/router";
import { useState, useEffect } from "react";
import classNames from "@calcom/lib/classNames";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { HttpError } from "@calcom/lib/http-error";
import { trpc } from "@calcom/trpc/react";
import { Icon } from "@calcom/ui";
import { Button, Loader, showToast, Switch, Tooltip } from "@calcom/ui/v2";
import LicenseRequired from "../../../common/components/v2/LicenseRequired";
import { getActionIcon } from "../../lib/getActionIcon";
import EmptyScreen from "./EmptyScreen";
import { WorkflowType } from "./WorkflowListPage";
type ItemProps = {
workflow: WorkflowType;
eventType: {
id: number;
title: string;
};
};
const WorkflowListItem = (props: ItemProps) => {
const { workflow, eventType } = props;
const { t } = useLocale();
const [activeEventTypeIds, setActiveEventTypeIds] = useState(
workflow.activeOn.map((active) => {
if (active.eventType) {
return active.eventType.id;
}
})
);
const isActive = activeEventTypeIds.includes(eventType.id);
const activateEventTypeMutation = trpc.useMutation("viewer.workflows.activateEventType");
const sendTo: Set<string> = new Set();
workflow.steps.forEach((step) => {
switch (step.action) {
case WorkflowActions.EMAIL_HOST:
sendTo.add(t("organizer_name_workflow"));
break;
case WorkflowActions.EMAIL_ATTENDEE:
sendTo.add(t("attendee_name_workflow"));
break;
case WorkflowActions.SMS_ATTENDEE:
sendTo.add(t("attendee_name_workflow"));
break;
case WorkflowActions.SMS_NUMBER:
sendTo.add(step.sendTo || "");
break;
}
});
return (
<div className="mb-4 flex w-full items-center rounded-md border border-gray-200 p-4">
<div className="mt-[3px] mr-5 flex h-10 w-10 items-center justify-center rounded-full bg-gray-100 p-1 text-xs font-medium">
{getActionIcon(
workflow.steps,
isActive ? "h-7 w-7 stroke-[1.5px] text-gray-700" : "h-7 w-7 stroke-[1.5px] text-gray-400"
)}
</div>
<div className="ml-4 grow">
<div
className={classNames(
"w-full truncate text-sm font-medium leading-6 text-gray-900 md:max-w-max",
workflow.name && isActive ? "text-gray-900" : "text-neutral-500"
)}>
{workflow.name
? workflow.name
: "Untitled (" +
`${t(`${workflow.steps[0].action.toLowerCase()}_action`)}`.charAt(0).toUpperCase() +
`${t(`${workflow.steps[0].action.toLowerCase()}_action`)}`.slice(1) +
")"}
</div>
<div
className={classNames(
"mb-1 flex w-fit items-center whitespace-nowrap rounded-sm py-px text-sm",
isActive ? "text-gray-600" : "text-gray-400"
)}>
<span className="mr-1">{t("to")}:</span>
{Array.from(sendTo).map((sendToPerson, index) => {
return <span key={index}>{`${index ? ", " : ""}${sendToPerson}`}</span>;
})}
</div>
</div>
<div className="flex-none sm:mr-3">
<Link href={`/workflows/${workflow.id}`} passHref={true}>
<a target="_blank">
<Button type="button" color="minimal" className="text-sm text-gray-900 hover:bg-transparent">
{t("edit")}
<Icon.FiExternalLink className="ml-2 -mt-[2px] h-4 w-4 stroke-2 text-gray-600" />
</Button>
</a>
</Link>
</div>
<Tooltip content={t("turn_off") as string}>
<div className="">
<Switch
checked={isActive}
onCheckedChange={() => {
activateEventTypeMutation.mutate({ workflowId: workflow.id, eventTypeId: eventType.id });
if (activeEventTypeIds.includes(eventType.id)) {
const newActiveEventTypeIds = activeEventTypeIds.filter((id) => {
return id !== eventType.id;
});
setActiveEventTypeIds(newActiveEventTypeIds);
} else {
const newActiveEventTypeIds = activeEventTypeIds;
newActiveEventTypeIds.push(eventType.id);
setActiveEventTypeIds(newActiveEventTypeIds);
}
}}
/>
</div>
</Tooltip>
</div>
);
};
type Props = {
eventType: {
id: number;
title: string;
};
workflows: WorkflowType[];
};
function EventWorkflowsTab(props: Props) {
const { workflows } = props;
const { t } = useLocale();
const { data, isLoading } = trpc.useQuery(["viewer.workflows.list"]);
const router = useRouter();
const [sortedWorkflows, setSortedWorkflows] = useState<Array<WorkflowType>>([]);
useEffect(() => {
if (data?.workflows) {
const activeWorkflows = workflows.map((workflowOnEventType) => {
return workflowOnEventType;
});
const disabledWorkflows = data.workflows.filter(
(workflow) =>
!workflows
.map((workflow) => {
return workflow.id;
})
.includes(workflow.id)
);
setSortedWorkflows(activeWorkflows.concat(disabledWorkflows));
}
}, [isLoading]);
const createMutation = trpc.useMutation("viewer.workflows.createV2", {
onSuccess: async ({ workflow }) => {
await router.replace("/workflows/" + workflow.id);
},
onError: (err) => {
if (err instanceof HttpError) {
const message = `${err.statusCode}: ${err.message}`;
showToast(message, "error");
}
if (err.data?.code === "UNAUTHORIZED") {
const message = `${err.data.code}: You are not able to create this workflow`;
showToast(message, "error");
}
},
});
return (
<LicenseRequired>
{!isLoading ? (
data?.workflows && data?.workflows.length > 0 ? (
<div className="mt-6">
{sortedWorkflows.map((workflow) => {
return <WorkflowListItem key={workflow.id} workflow={workflow} eventType={props.eventType} />;
})}
</div>
) : (
<EmptyScreen
buttonText={t("create_workflow")}
buttonOnClick={() => createMutation.mutate()}
IconHeading={Icon.FiZap}
headline={t("workflows")}
description={t("no_workflows_description")}
isLoading={createMutation.isLoading}
showExampleWorkflows={false}
/>
)
) : (
<Loader />
)}
</LicenseRequired>
);
}
export default EventWorkflowsTab;