* Add duplicate form support * Fix duplication logic * Change to feathericons everywhere and other fixes * Dont allow routes for fallback route * Fix banner * Fix Empty Screen * Text area + embded window fixes * Semi fix avatar * Fix all TS issues * Fix tests * Troubleshoot container + Active on count * Support routing using query params * Improve mobile * NITS * Fix padding on input * Support multiselect in router endpoint * Fix the issue where app goes in embed mode after viewing embed once * Fix icons * Add router url tests * Add Responses download and form toggling tests * Add required validation test * Change Icons everywhere * App typeform app * Improvements in cli * 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 * Add typeform how-to-use page * Add typeform how-to-use page and screenshots * Most of advanced tab * Solved RHF mismtach * Build fixes * RHF conditionals fixes * Improved legibility * Fix TS error * Add missing image * Update CliApp.tsx * 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 * Major locations cleanup, 10s of bug fixes and app-store improvements * Fix missing pieces * More fixes * Fix embed URL * Fix app toggles + number of active apps * Fix container padding on disabledBorder prop * Removes strict * more fixes * EventType Team page WIP * Fix embed * Use new Shell * NIT * Add Darkmode gray color * V2 Shell WIP * 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 * Get form-edit page working * Get route-builder page working * Fix scheduling type and remove multi select label * Fix overflow on teams url * Get UI as per designs for form-edit * Make route-builder upto date with design * Add no responses banner * Update forms list as per designs * Button shouldnt decide where it would be positioned, users of it might have different requirements * A single select box in a row(when no other select boxes are present) wasnt taking the correct width in comparison to when it had other select boxes * Small missing pieces * Revert console * Revert api * Fixes * Fix Embed TS errors * Fix TS errors * Fix Eslint errors * Fix TS errors for UI * Fix ESLINT error * Fix TS errors * Add missing import * Fix CLI * Add a default placeholder * Remove hardcoded daily:integrations * Fix message for payment page * Revert api and console to main * Update README * Fix TS errors * Fix Lint warnings * Fix Tests * Streamline actions and make them easy to manage * A much more simplified approach to implementing actions * Fix embed * Fix most TS errors * Fix more TS errors * Reduce TS errors to zero * Fix tests * Fix UI * Fix UI * Self review fixes * TS failures caught merge issues * Security hardening * Use V2 Shell everywhere * Add missing file * Problems created by new shell fixed * Fix Shell * Fix Routing Form Card up and down positons * Fix Embed and other design fixes * Fix dropdown old event-types * Fix type errors * Fix allowed chek * Fix dropdown not closing on clicking EMbed button * Fix dropdown not closing on embed button * Fix event-type button group layout * Add label for switch * Fix dropdown in mobile mode * Remove useless comments * Login with pro for tests * Remove bg gray till App-Store pages are revamped Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com> Co-authored-by: Peer Richelsen <peeroke@gmail.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com>
126 lines
3.6 KiB
TypeScript
126 lines
3.6 KiB
TypeScript
import { Prisma } from "@prisma/client";
|
|
import { TFunction } from "next-i18next";
|
|
|
|
import { defaultLocations, EventLocationType, LocationType } from "@calcom/app-store/locations";
|
|
import type { App, AppMeta } from "@calcom/types/App";
|
|
|
|
// If you import this file on any app it should produce circular dependency
|
|
// import appStore from "./index";
|
|
import { appStoreMetadata } from "./apps.browser.generated";
|
|
|
|
const ALL_APPS_MAP = Object.keys(appStoreMetadata).reduce((store, key) => {
|
|
store[key] = appStoreMetadata[key as keyof typeof appStoreMetadata];
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
//@ts-ignore
|
|
delete store[key]["/*"];
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
//@ts-ignore
|
|
delete store[key]["__createdUsingCli"];
|
|
return store;
|
|
}, {} as Record<string, AppMeta>);
|
|
|
|
const credentialData = Prisma.validator<Prisma.CredentialArgs>()({
|
|
select: { id: true, type: true, key: true, userId: true, appId: true },
|
|
});
|
|
|
|
type CredentialData = Prisma.CredentialGetPayload<typeof credentialData>;
|
|
|
|
export const ALL_APPS = Object.values(ALL_APPS_MAP);
|
|
|
|
type OptionTypeBase = {
|
|
label: string;
|
|
value: EventLocationType["type"];
|
|
disabled?: boolean;
|
|
};
|
|
|
|
function translateLocations(locations: OptionTypeBase[], t: TFunction) {
|
|
return locations.map((l) => ({
|
|
...l,
|
|
label: t(l.label),
|
|
}));
|
|
}
|
|
|
|
export function getLocationOptions(integrations: ReturnType<typeof getApps>, t: TFunction) {
|
|
const locations: OptionTypeBase[] = [];
|
|
defaultLocations.forEach((l) => {
|
|
locations.push({
|
|
label: l.label,
|
|
value: l.type,
|
|
});
|
|
});
|
|
integrations.forEach((app) => {
|
|
if (app.locationOption) {
|
|
locations.push(app.locationOption);
|
|
}
|
|
});
|
|
|
|
return translateLocations(locations, t);
|
|
}
|
|
|
|
/**
|
|
* This should get all available apps to the user based on his saved
|
|
* credentials, this should also get globally available apps.
|
|
*/
|
|
function getApps(userCredentials: CredentialData[]) {
|
|
const apps = ALL_APPS.map((appMeta) => {
|
|
const credentials = userCredentials.filter((credential) => credential.type === appMeta.type);
|
|
let locationOption: OptionTypeBase | null = null;
|
|
|
|
/** If the app is a globally installed one, let's inject it's key */
|
|
if (appMeta.isGlobal) {
|
|
credentials.push({
|
|
id: +new Date().getTime(),
|
|
type: appMeta.type,
|
|
key: appMeta.key!,
|
|
userId: +new Date().getTime(),
|
|
appId: appMeta.slug,
|
|
});
|
|
}
|
|
|
|
/** Check if app has location option AND add it if user has credentials for it */
|
|
if (credentials.length > 0 && appMeta?.appData?.location) {
|
|
locationOption = {
|
|
value: appMeta.appData.location.type,
|
|
label: appMeta.appData.location.label || "No label set",
|
|
disabled: false,
|
|
};
|
|
}
|
|
|
|
const credential: typeof credentials[number] | null = credentials[0] || null;
|
|
return {
|
|
...appMeta,
|
|
/**
|
|
* @deprecated use `credentials`
|
|
*/
|
|
credential,
|
|
credentials,
|
|
/** Option to display in `location` field while editing event types */
|
|
locationOption,
|
|
};
|
|
});
|
|
|
|
return apps;
|
|
}
|
|
|
|
export function hasIntegrationInstalled(type: App["type"]): boolean {
|
|
return ALL_APPS.some((app) => app.type === type && !!app.installed);
|
|
}
|
|
|
|
export function getAppName(name: string): string | null {
|
|
return ALL_APPS_MAP[name as keyof typeof ALL_APPS_MAP]?.name ?? null;
|
|
}
|
|
|
|
export function getAppType(name: string): string {
|
|
const type = ALL_APPS_MAP[name as keyof typeof ALL_APPS_MAP].type;
|
|
|
|
if (type.endsWith("_calendar")) {
|
|
return "Calendar";
|
|
}
|
|
if (type.endsWith("_payment")) {
|
|
return "Payment";
|
|
}
|
|
return "Unknown";
|
|
}
|
|
|
|
export default getApps;
|