refactor(appStore): EventTypeAppSettngsInterface

new-app-install-flow
Morgan Vernay 2023-10-20 11:19:55 +03:00
parent 2585d62007
commit 550a1fe6c0
5 changed files with 86 additions and 40 deletions

View File

@ -1,9 +1,7 @@
import { Trans } from "next-i18next";
import Link from "next/link";
import type { EventTypeSetupProps, FormValues } from "pages/event-types/[type]";
import { useFormContext } from "react-hook-form";
import type { EventTypeSetupProps } from "pages/event-types/[type]";
import type { GetAppData, SetAppData } from "@calcom/app-store/EventTypeAppContext";
import { EventTypeAppCard } from "@calcom/app-store/_components/EventTypeAppCardInterface";
import type { EventTypeAppCardComponentProps } from "@calcom/app-store/types";
import type { EventTypeAppsList } from "@calcom/app-store/utils";
@ -13,6 +11,8 @@ import { trpc } from "@calcom/trpc/react";
import { Button, EmptyScreen, Alert } from "@calcom/ui";
import { Grid, Lock } from "@calcom/ui/components/icon";
import useAppsData from "@lib/hooks/useAppsData";
export type EventType = Pick<EventTypeSetupProps, "eventType">["eventType"] &
EventTypeAppCardComponentProps["eventType"];
@ -23,44 +23,12 @@ export const EventAppsTab = ({ eventType }: { eventType: EventType }) => {
teamId: eventType.team?.id || eventType.parent?.teamId,
});
const methods = useFormContext<FormValues>();
const installedApps =
eventTypeApps?.items.filter((app) => app.userCredentialIds.length || app.teams.length) || [];
const notInstalledApps =
eventTypeApps?.items.filter((app) => !app.userCredentialIds.length && !app.teams.length) || [];
const allAppsData = methods.watch("metadata")?.apps || {};
const setAllAppsData = (_allAppsData: typeof allAppsData) => {
methods.setValue("metadata", {
...methods.getValues("metadata"),
apps: _allAppsData,
});
};
const getAppDataGetter = (appId: EventTypeAppsList): GetAppData => {
return function (key) {
const appData = allAppsData[appId as keyof typeof allAppsData] || {};
if (key) {
return appData[key as keyof typeof appData];
}
return appData;
};
};
const getAppDataSetter = (appId: EventTypeAppsList): SetAppData => {
return function (key, value) {
// Always get latest data available in Form because consequent calls to setData would update the Form but not allAppsData(it would update during next render)
const allAppsDataFromForm = methods.getValues("metadata")?.apps || {};
const appData = allAppsDataFromForm[appId];
setAllAppsData({
...allAppsDataFromForm,
[appId]: {
...appData,
[key]: value,
},
});
};
};
const { getAppDataGetter, getAppDataSetter } = useAppsData();
const { shouldLockDisableProps, isManagedEventType, isChildrenManagedEventType } = useLockedFieldsManager(
eventType,

View File

@ -0,0 +1,46 @@
import type { FormValues } from "pages/event-types/[type]";
import { useFormContext } from "react-hook-form";
import type { GetAppData, SetAppData } from "@calcom/app-store/EventTypeAppContext";
import type { EventTypeAppsList } from "@calcom/app-store/utils";
const useAppsData = () => {
const methods = useFormContext<FormValues>();
const allAppsData = methods.watch("metadata")?.apps || {};
const setAllAppsData = (_allAppsData: typeof allAppsData) => {
methods.setValue("metadata", {
...methods.getValues("metadata"),
apps: _allAppsData,
});
};
const getAppDataGetter = (appId: EventTypeAppsList): GetAppData => {
return function (key?: string) {
const appData = allAppsData[appId as keyof typeof allAppsData] || {};
if (key) {
return appData[key as keyof typeof appData];
}
return appData;
};
};
const getAppDataSetter = (appId: EventTypeAppsList): SetAppData => {
return function (key, value) {
// Always get latest data available in Form because consequent calls to setData would update the Form but not allAppsData(it would update during next render)
const allAppsDataFromForm = methods.getValues("metadata")?.apps || {};
const appData = allAppsDataFromForm[appId];
setAllAppsData({
...allAppsDataFromForm,
[appId]: {
...appData,
[key]: value,
},
});
};
};
return { getAppDataGetter, getAppDataSetter };
};
export default useAppsData;

View File

@ -104,10 +104,9 @@ function generateFiles() {
* If a file has index.ts or index.tsx, it can be imported after removing the index.ts* part
*/
function getModulePath(path: string, moduleName: string) {
return (
`./${path.replace(/\\/g, "/")}/` +
moduleName.replace(/\/index\.ts|\/index\.tsx/, "").replace(/\.tsx$|\.ts$/, "")
);
return `./${path.replace(/\\/g, "/")}/${moduleName
.replace(/\/index\.ts|\/index\.tsx/, "")
.replace(/\.tsx$|\.ts$/, "")}`;
}
type ImportConfig =
@ -329,6 +328,14 @@ function generateFiles() {
lazyImport: true,
})
);
browserOutput.push(
...getExportedObject("EventTypeSettingsMap", {
importConfig: {
fileToBeImported: "components/EventTypeAppSettingsInterface.tsx",
},
lazyImport: true,
})
);
const banner = `/**
This file is autogenerated using the command \`yarn app-store:build --watch\`.

View File

@ -0,0 +1,9 @@
import { EventTypeSettingsMap } from "@calcom/app-store/apps.browser.generated";
import type { EventTypeAppSettingsComponentProps } from "../types";
import { DynamicComponent } from "./DynamicComponent";
export const EventTypeAppSettings = (props: EventTypeAppSettingsComponentProps) => {
const { slug, ...rest } = props;
return <DynamicComponent slug={slug} componentMap={EventTypeSettingsMap} {...rest} />;
};

View File

@ -52,4 +52,20 @@ export type EventTypeAppCardComponentProps = {
disabled?: boolean;
LockedIcon?: JSX.Element | false;
};
export type EventTypeAppSettingsComponentProps = {
// Limit what data should be accessible to apps\
eventType: Pick<
z.infer<typeof EventTypeModel>,
"id" | "title" | "description" | "teamId" | "length" | "recurringEvent" | "seatsPerTimeSlot" | "team"
> & {
URL: string;
};
getAppData: GetAppData;
setAppData: SetAppData;
disabled?: boolean;
slug: string;
};
export type EventTypeAppCardComponent = React.FC<EventTypeAppCardComponentProps>;
export type EventTypeAppSettingsComponent = React.FC<EventTypeAppSettingsComponentProps>;