@faskai/ui-commons 0.0.0-alpha.22 → 0.0.0-alpha.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,8 @@
1
+ interface AppIconProps {
2
+ src?: string;
3
+ icon?: string;
4
+ alt?: string;
5
+ className?: string;
6
+ }
7
+ export declare function AppIcon({ src, icon, alt, className }: AppIconProps): import("react/jsx-runtime").JSX.Element;
8
+ export {};
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.AppIcon = AppIcon;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const lucide_react_1 = require("lucide-react");
7
+ const utils_1 = require("../../lib/utils");
8
+ const iconMap = {
9
+ landmark: lucide_react_1.Landmark,
10
+ building2: lucide_react_1.Building2,
11
+ 'credit-card': lucide_react_1.CreditCard,
12
+ 'shopping-cart': lucide_react_1.ShoppingCart,
13
+ calendar: lucide_react_1.Calendar,
14
+ mail: lucide_react_1.Mail,
15
+ 'message-square': lucide_react_1.MessageSquare,
16
+ };
17
+ const FallbackIcon = lucide_react_1.Blocks;
18
+ function AppIcon({ src, icon, alt, className }) {
19
+ if (src) {
20
+ return (0, jsx_runtime_1.jsx)("img", { src: src, alt: alt, className: (0, utils_1.cn)('rounded', className) });
21
+ }
22
+ const Icon = (icon && iconMap[icon]) || FallbackIcon;
23
+ return (0, jsx_runtime_1.jsx)(Icon, { className: (0, utils_1.cn)('text-muted-foreground', className) });
24
+ }
@@ -0,0 +1,10 @@
1
+ import type { FaskSearchableApp } from '../../types/connections';
2
+ interface AppSearchGridProps {
3
+ connectedAppKeys: string[];
4
+ onSearch: (query: string) => Promise<FaskSearchableApp[]>;
5
+ onConnect: (app: FaskSearchableApp) => void;
6
+ connecting?: string | null;
7
+ initialApps?: FaskSearchableApp[];
8
+ }
9
+ export declare function AppSearchGrid({ connectedAppKeys, onSearch, onConnect, connecting, initialApps, }: AppSearchGridProps): import("react/jsx-runtime").JSX.Element;
10
+ export {};
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.AppSearchGrid = AppSearchGrid;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const react_1 = require("react");
7
+ const utils_1 = require("../../lib/utils");
8
+ const app_icon_1 = require("./app-icon");
9
+ function AppSearchGrid({ connectedAppKeys, onSearch, onConnect, connecting, initialApps, }) {
10
+ const [query, setQuery] = (0, react_1.useState)('');
11
+ const [apps, setApps] = (0, react_1.useState)(initialApps || []);
12
+ const [searching, setSearching] = (0, react_1.useState)(false);
13
+ const debounceRef = (0, react_1.useRef)(null);
14
+ (0, react_1.useEffect)(() => {
15
+ if (debounceRef.current)
16
+ clearTimeout(debounceRef.current);
17
+ debounceRef.current = setTimeout(async () => {
18
+ if (!query.trim()) {
19
+ setApps(initialApps || []);
20
+ return;
21
+ }
22
+ setSearching(true);
23
+ const results = await onSearch(query);
24
+ setApps(results);
25
+ setSearching(false);
26
+ }, 300);
27
+ return () => {
28
+ if (debounceRef.current)
29
+ clearTimeout(debounceRef.current);
30
+ };
31
+ }, [query, onSearch, initialApps]);
32
+ function isConnected(slug) {
33
+ return connectedAppKeys.includes(slug);
34
+ }
35
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h3", { className: "text-sm font-medium", children: "Connect Apps" }), (0, jsx_runtime_1.jsx)("p", { className: "text-muted-foreground text-xs", children: "Search and connect apps for your agent." })] }), (0, jsx_runtime_1.jsx)("input", { className: "border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex h-9 w-full rounded-md border px-3 py-1 text-sm shadow-sm transition-colors focus-visible:ring-1 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50", placeholder: "Search apps (e.g. Slack, Google Sheets, HubSpot)...", value: query, onChange: (e) => setQuery(e.target.value) }), searching && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 py-4", children: [(0, jsx_runtime_1.jsxs)("svg", { className: "size-4 animate-spin", fill: "none", viewBox: "0 0 24 24", children: [(0, jsx_runtime_1.jsx)("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), (0, jsx_runtime_1.jsx)("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })] }), (0, jsx_runtime_1.jsx)("span", { className: "text-muted-foreground text-sm", children: "Searching..." })] })), apps.length > 0 && ((0, jsx_runtime_1.jsx)("div", { className: "grid gap-2 sm:grid-cols-2 lg:grid-cols-3", children: apps.map((app) => ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3 rounded-lg border p-3", children: [(0, jsx_runtime_1.jsx)(app_icon_1.AppIcon, { src: app.img_src, alt: app.name, className: "size-8" }), (0, jsx_runtime_1.jsxs)("div", { className: "min-w-0 flex-1", children: [(0, jsx_runtime_1.jsx)("p", { className: "truncate text-sm font-medium", children: app.name }), isConnected(app.name_slug) && ((0, jsx_runtime_1.jsx)("span", { className: "text-muted-foreground text-xs", children: "Connected" }))] }), isConnected(app.name_slug) ? ((0, jsx_runtime_1.jsx)("span", { className: "bg-primary text-primary-foreground inline-flex items-center rounded-md px-2.5 py-0.5 text-xs font-medium", children: "Connected" })) : ((0, jsx_runtime_1.jsxs)("button", { className: (0, utils_1.cn)('inline-flex items-center rounded-md border px-3 py-1.5 text-sm font-medium', 'hover:bg-accent disabled:opacity-50'), onClick: () => onConnect(app), disabled: connecting === app.name_slug, children: [connecting === app.name_slug && ((0, jsx_runtime_1.jsxs)("svg", { className: "mr-1 size-3 animate-spin", fill: "none", viewBox: "0 0 24 24", children: [(0, jsx_runtime_1.jsx)("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), (0, jsx_runtime_1.jsx)("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })] })), "Connect"] }))] }, app.name_slug))) }))] }));
36
+ }
@@ -0,0 +1,8 @@
1
+ import type { FaskConnection } from '../../types/connections';
2
+ interface AvailableAppsListProps {
3
+ connections: FaskConnection[];
4
+ onConnect: (connection: FaskConnection) => void;
5
+ connecting?: string | null;
6
+ }
7
+ export declare function AvailableAppsList({ connections, onConnect, connecting, }: AvailableAppsListProps): import("react/jsx-runtime").JSX.Element | null;
8
+ export {};
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.AvailableAppsList = AvailableAppsList;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const app_icon_1 = require("./app-icon");
7
+ function AvailableAppsList({ connections, onConnect, connecting, }) {
8
+ const available = connections.filter((c) => c.status !== 'connected');
9
+ if (available.length === 0)
10
+ return null;
11
+ return ((0, jsx_runtime_1.jsx)("div", { className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3", children: available.map((conn) => ((0, jsx_runtime_1.jsxs)("div", { className: "rounded-lg border p-4 transition-all hover:shadow-md", children: [(0, jsx_runtime_1.jsxs)("div", { className: "mb-3 flex items-center gap-3", children: [(0, jsx_runtime_1.jsx)("div", { className: "bg-background flex size-12 shrink-0 items-center justify-center rounded-lg border p-2", children: (0, jsx_runtime_1.jsx)(app_icon_1.AppIcon, { src: conn.app?.img, icon: conn.app?.icon, alt: conn.app?.name, className: "size-full object-contain" }) }), (0, jsx_runtime_1.jsx)("div", { className: "min-w-0 flex-1", children: (0, jsx_runtime_1.jsx)("p", { className: "truncate text-base font-semibold", children: conn.app?.name }) })] }), (0, jsx_runtime_1.jsxs)("button", { onClick: () => onConnect(conn), disabled: connecting === conn.appKey, className: "bg-primary text-primary-foreground hover:bg-primary/90 flex w-full items-center justify-center gap-2 rounded-md px-3 py-2 text-sm font-medium disabled:opacity-50", children: [(0, jsx_runtime_1.jsx)("svg", { className: "size-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: (0, jsx_runtime_1.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" }) }), connecting === conn.appKey ? 'Connecting...' : 'Connect'] })] }, conn.id || conn.appKey))) }));
12
+ }
@@ -0,0 +1,11 @@
1
+ import type { FaskConnection } from '../../types/connections';
2
+ interface ConnectedAppsListProps {
3
+ connections: FaskConnection[];
4
+ variant: 'cards' | 'badges';
5
+ onReimport?: (connection: FaskConnection) => void;
6
+ onDisconnect?: (connection: FaskConnection) => void;
7
+ reimporting?: string | null;
8
+ disconnecting?: string | null;
9
+ }
10
+ export declare function ConnectedAppsList({ connections, variant, onReimport, onDisconnect, reimporting, disconnecting, }: ConnectedAppsListProps): import("react/jsx-runtime").JSX.Element | null;
11
+ export {};
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.ConnectedAppsList = ConnectedAppsList;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const utils_1 = require("../../lib/utils");
7
+ const app_icon_1 = require("./app-icon");
8
+ function ConnectedAppsList({ connections, variant, onReimport, onDisconnect, reimporting, disconnecting, }) {
9
+ const connected = connections.filter((c) => c.status === 'connected');
10
+ if (connected.length === 0)
11
+ return null;
12
+ if (variant === 'badges') {
13
+ return ((0, jsx_runtime_1.jsx)("div", { className: "flex flex-wrap gap-2", children: connected.map((conn) => ((0, jsx_runtime_1.jsxs)("span", { className: "bg-primary text-primary-foreground inline-flex items-center gap-1.5 rounded-md px-2.5 py-1 text-xs font-medium", children: [(0, jsx_runtime_1.jsx)(app_icon_1.AppIcon, { src: conn.app?.img, icon: conn.app?.icon, alt: conn.app?.name, className: "size-4" }), conn.app?.name] }, conn.appKey))) }));
14
+ }
15
+ // cards variant
16
+ return ((0, jsx_runtime_1.jsx)("div", { className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3", children: connected.map((conn) => ((0, jsx_runtime_1.jsxs)("div", { className: "relative rounded-lg border p-4 transition-all hover:shadow-md", children: [(0, jsx_runtime_1.jsx)("div", { className: "absolute top-0 right-0", children: (0, jsx_runtime_1.jsx)("div", { className: "bg-primary/10 rounded-bl-lg p-2", children: (0, jsx_runtime_1.jsx)("svg", { className: "text-primary size-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: (0, jsx_runtime_1.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }) }) }), (0, jsx_runtime_1.jsxs)("div", { className: "mb-3 flex items-center gap-3", children: [(0, jsx_runtime_1.jsx)("div", { className: "bg-background flex size-12 shrink-0 items-center justify-center rounded-lg border p-2", children: (0, jsx_runtime_1.jsx)(app_icon_1.AppIcon, { src: conn.app?.img, icon: conn.app?.icon, alt: conn.app?.name, className: "size-full object-contain" }) }), (0, jsx_runtime_1.jsx)("div", { className: "min-w-0 flex-1", children: (0, jsx_runtime_1.jsx)("p", { className: "truncate text-base font-semibold", children: conn.app?.name }) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "space-y-2", children: [(0, jsx_runtime_1.jsx)("span", { className: "inline-flex w-full items-center justify-center rounded-md border px-2.5 py-0.5 text-xs font-medium", children: "Connected" }), onReimport && ((0, jsx_runtime_1.jsxs)("button", { onClick: () => onReimport(conn), disabled: reimporting === (conn.providerConnectionId || conn.appKey), className: (0, utils_1.cn)('flex w-full items-center justify-center gap-2 rounded-md border px-3 py-1.5 text-sm', 'hover:bg-accent disabled:opacity-50'), children: [(0, jsx_runtime_1.jsx)("svg", { className: (0, utils_1.cn)('size-4', reimporting === (conn.providerConnectionId || conn.appKey) &&
17
+ 'animate-spin'), fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: (0, jsx_runtime_1.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" }) }), reimporting === (conn.providerConnectionId || conn.appKey)
18
+ ? 'Reimporting...'
19
+ : 'Reimport'] })), onDisconnect && ((0, jsx_runtime_1.jsxs)("button", { onClick: () => onDisconnect(conn), disabled: disconnecting === (conn.id || conn.appKey), className: (0, utils_1.cn)('text-destructive hover:text-destructive flex w-full items-center justify-center gap-2 rounded-md border px-3 py-1.5 text-sm', 'hover:bg-accent disabled:opacity-50'), children: [(0, jsx_runtime_1.jsx)("svg", { className: "size-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: (0, jsx_runtime_1.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M13.181 8.68a4 4 0 00-5.5-5.5M6.5 12.5l-2-2m8 8l-2-2m2-6l6 6m-2-6l2 2" }) }), disconnecting === (conn.id || conn.appKey)
20
+ ? 'Disconnecting...'
21
+ : 'Disconnect'] }))] })] }, conn.id || conn.appKey))) }));
22
+ }
@@ -0,0 +1,9 @@
1
+ import { type ReactNode } from 'react';
2
+ import type { ConnectionsApi } from '../../types/connections-api';
3
+ export declare function useConnectionsApi(): ConnectionsApi;
4
+ interface ConnectionsApiProviderProps {
5
+ api: ConnectionsApi;
6
+ children: ReactNode;
7
+ }
8
+ export declare function ConnectionsApiProvider({ api, children, }: ConnectionsApiProviderProps): import("react/jsx-runtime").JSX.Element;
9
+ export {};
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.useConnectionsApi = useConnectionsApi;
5
+ exports.ConnectionsApiProvider = ConnectionsApiProvider;
6
+ const jsx_runtime_1 = require("react/jsx-runtime");
7
+ const react_1 = require("react");
8
+ const ConnectionsApiContext = (0, react_1.createContext)(null);
9
+ function useConnectionsApi() {
10
+ const api = (0, react_1.useContext)(ConnectionsApiContext);
11
+ if (!api) {
12
+ throw new Error('useConnectionsApi must be used within a ConnectionsApiProvider');
13
+ }
14
+ return api;
15
+ }
16
+ function ConnectionsApiProvider({ api, children, }) {
17
+ return ((0, jsx_runtime_1.jsx)(ConnectionsApiContext.Provider, { value: api, children: children }));
18
+ }
@@ -0,0 +1,9 @@
1
+ import type { FaskConnection } from '../../types/connections';
2
+ interface ConnectionsPanelProps {
3
+ variant: 'full-page' | 'compact';
4
+ showSearch?: boolean;
5
+ showReimport?: boolean;
6
+ onConnectionsLoaded?: (connections: FaskConnection[]) => void;
7
+ }
8
+ export declare function ConnectionsPanel({ variant, showSearch, showReimport, onConnectionsLoaded, }: ConnectionsPanelProps): import("react/jsx-runtime").JSX.Element;
9
+ export {};
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.ConnectionsPanel = ConnectionsPanel;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const react_1 = require("react");
7
+ const connections_api_provider_1 = require("./connections-api-provider");
8
+ const connected_apps_list_1 = require("./connected-apps-list");
9
+ const available_apps_list_1 = require("./available-apps-list");
10
+ const app_search_grid_1 = require("./app-search-grid");
11
+ function ConnectionsPanel({ variant, showSearch, showReimport, onConnectionsLoaded, }) {
12
+ const api = (0, connections_api_provider_1.useConnectionsApi)();
13
+ const [connections, setConnections] = (0, react_1.useState)([]);
14
+ const [loading, setLoading] = (0, react_1.useState)(true);
15
+ const [connecting, setConnecting] = (0, react_1.useState)(null);
16
+ const [reimporting, setReimporting] = (0, react_1.useState)(null);
17
+ const [disconnecting, setDisconnecting] = (0, react_1.useState)(null);
18
+ const prevConnectionsRef = (0, react_1.useRef)([]);
19
+ const pollIntervalRef = (0, react_1.useRef)(null);
20
+ const loadData = (0, react_1.useCallback)(async () => {
21
+ setLoading(true);
22
+ const conns = await api.getConnections();
23
+ // Salesforce polling detection
24
+ const wasConnected = prevConnectionsRef.current.some((c) => c.appKey === 'salesforce' && c.status === 'connected');
25
+ const isConnected = conns.some((c) => c.appKey === 'salesforce' && c.status === 'connected');
26
+ if (prevConnectionsRef.current.length > 0 &&
27
+ !wasConnected &&
28
+ isConnected) {
29
+ if (pollIntervalRef.current)
30
+ clearInterval(pollIntervalRef.current);
31
+ }
32
+ prevConnectionsRef.current = conns;
33
+ setConnections(conns);
34
+ onConnectionsLoaded?.(conns);
35
+ setLoading(false);
36
+ }, [api, onConnectionsLoaded]);
37
+ (0, react_1.useEffect)(() => {
38
+ loadData();
39
+ return () => {
40
+ if (pollIntervalRef.current)
41
+ clearInterval(pollIntervalRef.current);
42
+ };
43
+ }, [loadData]);
44
+ const connectedAppKeys = connections
45
+ .filter((c) => c.status === 'connected')
46
+ .map((c) => c.appKey);
47
+ async function handleConnect(app) {
48
+ const appKey = 'appKey' in app ? app.appKey : app.name_slug;
49
+ setConnecting(appKey);
50
+ try {
51
+ const response = await api.connect(app);
52
+ window.open(response.connect_link, '_blank', 'width=600,height=700');
53
+ if (appKey === 'salesforce') {
54
+ prevConnectionsRef.current = connections;
55
+ pollIntervalRef.current = setInterval(loadData, 2000);
56
+ setTimeout(() => {
57
+ if (pollIntervalRef.current)
58
+ clearInterval(pollIntervalRef.current);
59
+ }, 60000);
60
+ }
61
+ else {
62
+ setTimeout(loadData, 3000);
63
+ }
64
+ }
65
+ finally {
66
+ setConnecting(null);
67
+ }
68
+ }
69
+ async function handleReimport(conn) {
70
+ const key = conn.providerConnectionId || conn.appKey;
71
+ setReimporting(key);
72
+ try {
73
+ await api.reimport?.(conn.providerConnectionId, conn.appKey);
74
+ }
75
+ finally {
76
+ setReimporting(null);
77
+ }
78
+ }
79
+ async function handleDisconnect(conn) {
80
+ const key = conn.id || conn.appKey;
81
+ setDisconnecting(key);
82
+ try {
83
+ await api.disconnect(conn.id);
84
+ await loadData();
85
+ }
86
+ finally {
87
+ setDisconnecting(null);
88
+ }
89
+ }
90
+ async function handleSearchConnect(app) {
91
+ await handleConnect(app);
92
+ }
93
+ if (loading) {
94
+ return ((0, jsx_runtime_1.jsx)("div", { className: "space-y-4", children: [1, 2, 3].map((i) => ((0, jsx_runtime_1.jsx)("div", { className: "bg-muted/50 h-20 animate-pulse rounded-lg" }, i))) }));
95
+ }
96
+ if (variant === 'compact') {
97
+ const availableAppsWithActions = connections.filter((c) => c.status !== 'connected' && c.actions && c.actions.length > 0);
98
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-6", children: [(connectedAppKeys.length > 0 ||
99
+ availableAppsWithActions.length > 0) && ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-3", children: [(0, jsx_runtime_1.jsx)("h3", { className: "text-sm font-medium", children: "Connected Apps" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-wrap gap-2", children: [connections
100
+ .filter((c) => c.status === 'connected')
101
+ .map((conn) => ((0, jsx_runtime_1.jsxs)("span", { className: "bg-primary text-primary-foreground inline-flex items-center gap-1.5 rounded-md px-2.5 py-1 text-xs font-medium", children: [(0, jsx_runtime_1.jsx)(AppIconInline, { src: conn.app?.img, icon: conn.app?.icon, alt: conn.app?.name }), conn.app?.name] }, conn.appKey))), availableAppsWithActions.map((conn) => ((0, jsx_runtime_1.jsxs)("span", { className: "bg-secondary text-secondary-foreground inline-flex items-center gap-1.5 rounded-md px-2.5 py-1 text-xs font-medium opacity-60", children: [(0, jsx_runtime_1.jsx)(AppIconInline, { src: conn.app?.img, icon: conn.app?.icon, alt: conn.app?.name }), conn.app?.name, (0, jsx_runtime_1.jsx)("span", { className: "text-[10px]", children: "Not connected" })] }, conn.appKey)))] })] })), showSearch && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("hr", { className: "border-border" }), (0, jsx_runtime_1.jsx)(app_search_grid_1.AppSearchGrid, { connectedAppKeys: connectedAppKeys, onSearch: (q) => api.searchApps(q), onConnect: handleSearchConnect, connecting: connecting })] }))] }));
102
+ }
103
+ // full-page variant
104
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-6", children: [(0, jsx_runtime_1.jsx)(connected_apps_list_1.ConnectedAppsList, { connections: connections, variant: "cards", onReimport: showReimport ? handleReimport : undefined, onDisconnect: handleDisconnect, reimporting: reimporting, disconnecting: disconnecting }), (0, jsx_runtime_1.jsx)(available_apps_list_1.AvailableAppsList, { connections: connections, onConnect: handleConnect, connecting: connecting }), showSearch && ((0, jsx_runtime_1.jsx)(app_search_grid_1.AppSearchGrid, { connectedAppKeys: connectedAppKeys, onSearch: (q) => api.searchApps(q), onConnect: handleSearchConnect, connecting: connecting }))] }));
105
+ }
106
+ /**
107
+ * Tiny inline icon for badge usage (avoids importing the full AppIcon component tree).
108
+ */
109
+ function AppIconInline({ src, icon, alt, }) {
110
+ if (src) {
111
+ return (0, jsx_runtime_1.jsx)("img", { src: src, alt: alt, className: "size-4 rounded" });
112
+ }
113
+ // For badges, just show a small placeholder square
114
+ return ((0, jsx_runtime_1.jsx)("span", { className: "bg-muted-foreground/20 inline-block size-4 rounded" }));
115
+ }
@@ -8,17 +8,17 @@ exports.betaOfferData = {
8
8
  callouts: [
9
9
  {
10
10
  emoji: '🌟',
11
- title: 'Help shape the future',
11
+ title: 'Help Shape the Future',
12
12
  description: 'Have significant influence in shaping our product roadmap and stay ahead of your competition.',
13
13
  },
14
14
  {
15
15
  emoji: '🔧',
16
- title: 'Deep customizations',
16
+ title: 'Deep Customizations',
17
17
  description: 'Deeply customize AI agents on Fask to perform any task, enhance your CX and grow your business.',
18
18
  },
19
19
  {
20
20
  emoji: '💰',
21
- title: '50% OFF First Year',
21
+ title: '50% Off First Year',
22
22
  description: 'Exclusive Beta pricing for early adopters. Save hundreds on your first year subscription.',
23
23
  },
24
24
  {
package/dist/index.d.ts CHANGED
@@ -1,2 +1,11 @@
1
1
  export { GTMProvider } from './components/gtm/gtm-provider';
2
2
  export { betaOfferData } from './data/betaMarketingData';
3
+ export { ConnectionsApiProvider, useConnectionsApi, } from './components/connections/connections-api-provider';
4
+ export { AppIcon } from './components/connections/app-icon';
5
+ export { ConnectedAppsList } from './components/connections/connected-apps-list';
6
+ export { AvailableAppsList } from './components/connections/available-apps-list';
7
+ export { AppSearchGrid } from './components/connections/app-search-grid';
8
+ export { ConnectionsPanel } from './components/connections/connections-panel';
9
+ export type { FaskConnection, FaskSearchableApp } from './types/connections';
10
+ export type { ConnectionsApi } from './types/connections-api';
11
+ export { cn } from './lib/utils';
package/dist/index.js CHANGED
@@ -1,7 +1,24 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.betaOfferData = exports.GTMProvider = void 0;
3
+ exports.cn = exports.ConnectionsPanel = exports.AppSearchGrid = exports.AvailableAppsList = exports.ConnectedAppsList = exports.AppIcon = exports.useConnectionsApi = exports.ConnectionsApiProvider = exports.betaOfferData = exports.GTMProvider = void 0;
4
4
  var gtm_provider_1 = require("./components/gtm/gtm-provider");
5
5
  Object.defineProperty(exports, "GTMProvider", { enumerable: true, get: function () { return gtm_provider_1.GTMProvider; } });
6
6
  var betaMarketingData_1 = require("./data/betaMarketingData");
7
7
  Object.defineProperty(exports, "betaOfferData", { enumerable: true, get: function () { return betaMarketingData_1.betaOfferData; } });
8
+ // Connections
9
+ var connections_api_provider_1 = require("./components/connections/connections-api-provider");
10
+ Object.defineProperty(exports, "ConnectionsApiProvider", { enumerable: true, get: function () { return connections_api_provider_1.ConnectionsApiProvider; } });
11
+ Object.defineProperty(exports, "useConnectionsApi", { enumerable: true, get: function () { return connections_api_provider_1.useConnectionsApi; } });
12
+ var app_icon_1 = require("./components/connections/app-icon");
13
+ Object.defineProperty(exports, "AppIcon", { enumerable: true, get: function () { return app_icon_1.AppIcon; } });
14
+ var connected_apps_list_1 = require("./components/connections/connected-apps-list");
15
+ Object.defineProperty(exports, "ConnectedAppsList", { enumerable: true, get: function () { return connected_apps_list_1.ConnectedAppsList; } });
16
+ var available_apps_list_1 = require("./components/connections/available-apps-list");
17
+ Object.defineProperty(exports, "AvailableAppsList", { enumerable: true, get: function () { return available_apps_list_1.AvailableAppsList; } });
18
+ var app_search_grid_1 = require("./components/connections/app-search-grid");
19
+ Object.defineProperty(exports, "AppSearchGrid", { enumerable: true, get: function () { return app_search_grid_1.AppSearchGrid; } });
20
+ var connections_panel_1 = require("./components/connections/connections-panel");
21
+ Object.defineProperty(exports, "ConnectionsPanel", { enumerable: true, get: function () { return connections_panel_1.ConnectionsPanel; } });
22
+ // Utilities
23
+ var utils_1 = require("./lib/utils");
24
+ Object.defineProperty(exports, "cn", { enumerable: true, get: function () { return utils_1.cn; } });
@@ -0,0 +1,2 @@
1
+ import { type ClassValue } from 'clsx';
2
+ export declare function cn(...inputs: ClassValue[]): string;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cn = cn;
4
+ const clsx_1 = require("clsx");
5
+ const tailwind_merge_1 = require("tailwind-merge");
6
+ function cn(...inputs) {
7
+ return (0, tailwind_merge_1.twMerge)((0, clsx_1.clsx)(inputs));
8
+ }
@@ -0,0 +1,10 @@
1
+ import type { FaskConnection, FaskSearchableApp } from './connections';
2
+ export interface ConnectionsApi {
3
+ getConnections(): Promise<FaskConnection[]>;
4
+ searchApps(query: string): Promise<FaskSearchableApp[]>;
5
+ connect(app: FaskConnection | FaskSearchableApp): Promise<{
6
+ connect_link: string;
7
+ }>;
8
+ disconnect(connectionId: string): Promise<void>;
9
+ reimport?(connectionId: string, appKey: string): Promise<void>;
10
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,24 @@
1
+ export interface FaskConnection {
2
+ id?: string;
3
+ appKey: string;
4
+ provider: string;
5
+ providerConnectionId?: string;
6
+ status: 'connected' | 'available' | 'disconnected' | 'pending' | 'error';
7
+ app: {
8
+ name: string;
9
+ img?: string;
10
+ icon?: string;
11
+ };
12
+ actions?: {
13
+ key: string;
14
+ appKey: string;
15
+ name: string;
16
+ description: string;
17
+ }[];
18
+ }
19
+ export interface FaskSearchableApp {
20
+ name_slug: string;
21
+ name: string;
22
+ img_src: string;
23
+ provider: string;
24
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@faskai/ui-commons",
3
3
  "author": "Fask AI <arko@fask.ai>",
4
- "version": "0.0.0-alpha.22",
4
+ "version": "0.0.0-alpha.24",
5
5
  "description": "Common UI components for Fask applications.",
6
6
  "private": false,
7
7
  "main": "dist/index.js",
@@ -14,12 +14,18 @@
14
14
  "build": "tsc"
15
15
  },
16
16
  "peerDependencies": {
17
+ "clsx": ">=2.0.0",
18
+ "lucide-react": ">=0.300.0",
17
19
  "next": ">=13.0.0",
18
- "react": ">=18.0.0"
20
+ "react": ">=18.0.0",
21
+ "tailwind-merge": ">=2.0.0"
19
22
  },
20
23
  "devDependencies": {
21
24
  "@types/react": "^18.0.0",
25
+ "clsx": "^2.1.0",
26
+ "lucide-react": "^0.400.0",
22
27
  "next": "^14.0.0",
28
+ "tailwind-merge": "^2.2.0",
23
29
  "typescript": "^5.0.0"
24
30
  },
25
31
  "dependencies": {}