feat: recently added apps (#11118)
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com> Co-authored-by: Peer Richelsen <peeroke@gmail.com>
This commit is contained in:
parent
bd9cd00c04
commit
a030861423
|
@ -12,7 +12,14 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||||
import type { AppCategories } from "@calcom/prisma/enums";
|
import type { AppCategories } from "@calcom/prisma/enums";
|
||||||
import type { inferSSRProps } from "@calcom/types/inferSSRProps";
|
import type { inferSSRProps } from "@calcom/types/inferSSRProps";
|
||||||
import type { HorizontalTabItemProps } from "@calcom/ui";
|
import type { HorizontalTabItemProps } from "@calcom/ui";
|
||||||
import { AllApps, AppStoreCategories, HorizontalTabs, TextField, PopularAppsSlider } from "@calcom/ui";
|
import {
|
||||||
|
AllApps,
|
||||||
|
AppStoreCategories,
|
||||||
|
HorizontalTabs,
|
||||||
|
TextField,
|
||||||
|
PopularAppsSlider,
|
||||||
|
RecentAppsSlider,
|
||||||
|
} from "@calcom/ui";
|
||||||
import { Search } from "@calcom/ui/components/icon";
|
import { Search } from "@calcom/ui/components/icon";
|
||||||
|
|
||||||
import PageWrapper from "@components/PageWrapper";
|
import PageWrapper from "@components/PageWrapper";
|
||||||
|
@ -81,6 +88,7 @@ export default function Apps({
|
||||||
<>
|
<>
|
||||||
<AppStoreCategories categories={categories} />
|
<AppStoreCategories categories={categories} />
|
||||||
<PopularAppsSlider items={appStore} />
|
<PopularAppsSlider items={appStore} />
|
||||||
|
<RecentAppsSlider items={appStore} />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<AllApps
|
<AllApps
|
||||||
|
|
|
@ -2037,5 +2037,6 @@
|
||||||
"team_no_event_types": "This team has no event types",
|
"team_no_event_types": "This team has no event types",
|
||||||
"seat_options_doesnt_multiple_durations": "Seat option doesn't support multiple durations",
|
"seat_options_doesnt_multiple_durations": "Seat option doesn't support multiple durations",
|
||||||
"include_calendar_event": "Include calendar event",
|
"include_calendar_event": "Include calendar event",
|
||||||
|
"recently_added":"Recently added",
|
||||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Add your new strings above here ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Add your new strings above here ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ export async function getAppWithMetadata(app: { dirName: string } | { slug: stri
|
||||||
export async function getAppRegistry() {
|
export async function getAppRegistry() {
|
||||||
const dbApps = await prisma.app.findMany({
|
const dbApps = await prisma.app.findMany({
|
||||||
where: { enabled: true },
|
where: { enabled: true },
|
||||||
select: { dirName: true, slug: true, categories: true, enabled: true },
|
select: { dirName: true, slug: true, categories: true, enabled: true, createdAt: true },
|
||||||
});
|
});
|
||||||
const apps = [] as App[];
|
const apps = [] as App[];
|
||||||
const installCountPerApp = await getInstallCountPerApp();
|
const installCountPerApp = await getInstallCountPerApp();
|
||||||
|
@ -44,7 +44,7 @@ export async function getAppRegistry() {
|
||||||
// Skip if app isn't installed
|
// Skip if app isn't installed
|
||||||
/* This is now handled from the DB */
|
/* This is now handled from the DB */
|
||||||
// if (!app.installed) return apps;
|
// if (!app.installed) return apps;
|
||||||
|
app.createdAt = dbapp.createdAt.toISOString();
|
||||||
apps.push({
|
apps.push({
|
||||||
...app,
|
...app,
|
||||||
category: app.category || "other",
|
category: app.category || "other",
|
||||||
|
@ -101,6 +101,7 @@ export async function getAppRegistryWithCredentials(userId: number, userAdminTea
|
||||||
// Skip if app isn't installed
|
// Skip if app isn't installed
|
||||||
/* This is now handled from the DB */
|
/* This is now handled from the DB */
|
||||||
// if (!app.installed) return apps;
|
// if (!app.installed) return apps;
|
||||||
|
app.createdAt = dbapp.createdAt.toISOString();
|
||||||
let dependencyData: {
|
let dependencyData: {
|
||||||
name?: string;
|
name?: string;
|
||||||
installed?: boolean;
|
installed?: boolean;
|
||||||
|
|
|
@ -153,6 +153,8 @@ export interface App {
|
||||||
dependencies?: string[];
|
dependencies?: string[];
|
||||||
/** Enables video apps to be used for team events. Non Video/Conferencing apps don't honor this as they support team installation always. */
|
/** Enables video apps to be used for team events. Non Video/Conferencing apps don't honor this as they support team installation always. */
|
||||||
concurrentMeetings?: boolean;
|
concurrentMeetings?: boolean;
|
||||||
|
|
||||||
|
createdAt?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AppFrontendPayload = Omit<App, "key"> & {
|
export type AppFrontendPayload = Omit<App, "key"> & {
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||||
|
import type { AppFrontendPayload as App } from "@calcom/types/App";
|
||||||
|
|
||||||
|
import { AppCard } from "./AppCard";
|
||||||
|
import { Slider } from "./Slider";
|
||||||
|
|
||||||
|
export const RecentAppsSlider = <T extends App>({ items }: { items: T[] }) => {
|
||||||
|
const { t } = useLocale();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Slider<T>
|
||||||
|
title={t("recently_added")}
|
||||||
|
items={items.sort(
|
||||||
|
(a, b) => new Date(b?.createdAt || 0).valueOf() - new Date(a?.createdAt || 0).valueOf()
|
||||||
|
)}
|
||||||
|
itemKey={(app) => app.name}
|
||||||
|
options={{
|
||||||
|
perView: 3,
|
||||||
|
breakpoints: {
|
||||||
|
768 /* and below */: {
|
||||||
|
perView: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
renderItem={(app) => <AppCard app={app} />}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
|
@ -4,4 +4,5 @@ export { Slider } from "./Slider";
|
||||||
export { SkeletonLoader as AppSkeletonLoader } from "./SkeletonLoader";
|
export { SkeletonLoader as AppSkeletonLoader } from "./SkeletonLoader";
|
||||||
export { SkeletonLoader } from "./SkeletonLoader";
|
export { SkeletonLoader } from "./SkeletonLoader";
|
||||||
export { PopularAppsSlider } from "./PopularAppsSlider";
|
export { PopularAppsSlider } from "./PopularAppsSlider";
|
||||||
|
export { RecentAppsSlider } from "./RecentAppsSlider";
|
||||||
export { AppStoreCategories } from "./Categories";
|
export { AppStoreCategories } from "./Categories";
|
||||||
|
|
|
@ -69,6 +69,7 @@ export {
|
||||||
SkeletonLoader,
|
SkeletonLoader,
|
||||||
Slider,
|
Slider,
|
||||||
PopularAppsSlider,
|
PopularAppsSlider,
|
||||||
|
RecentAppsSlider,
|
||||||
useShouldShowArrows,
|
useShouldShowArrows,
|
||||||
AppStoreCategories,
|
AppStoreCategories,
|
||||||
} from "./components/apps";
|
} from "./components/apps";
|
||||||
|
|
Loading…
Reference in New Issue
Block a user