@burdenoff/microfe-store 2026.510.113
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.
- package/README.md +217 -0
- package/dist/StoreAdminRoot.d.ts +22 -0
- package/dist/StoreAdminRoot.js +23 -0
- package/dist/StoreAdminRoot.js.map +1 -0
- package/dist/StoreAdminRoutes.d.ts +9 -0
- package/dist/StoreAdminRoutes.js +69 -0
- package/dist/StoreAdminRoutes.js.map +1 -0
- package/dist/StoreRoot.d.ts +31 -0
- package/dist/StoreRoot.js +139 -0
- package/dist/StoreRoot.js.map +1 -0
- package/dist/StoreRoutes.d.ts +12 -0
- package/dist/StoreRoutes.js +285 -0
- package/dist/StoreRoutes.js.map +1 -0
- package/dist/components/InstallAppModal.d.ts +26 -0
- package/dist/components/InstallAppModal.js +287 -0
- package/dist/components/InstallAppModal.js.map +1 -0
- package/dist/components/RouteGuards.d.ts +17 -0
- package/dist/components/RouteGuards.js +26 -0
- package/dist/components/RouteGuards.js.map +1 -0
- package/dist/components/cart/CartDrawer.d.ts +35 -0
- package/dist/components/cart/CartDrawer.js +162 -0
- package/dist/components/cart/CartDrawer.js.map +1 -0
- package/dist/components/index.d.ts +9 -0
- package/dist/components/index.js +3 -0
- package/dist/components/marketplace/ProductCard.d.ts +18 -0
- package/dist/components/marketplace/ProductCard.js +2 -0
- package/dist/dev/main.d.ts +1 -0
- package/dist/generated/global-operations.d.ts +2012 -0
- package/dist/generated/global-operations.js +1444 -0
- package/dist/generated/global-operations.js.map +1 -0
- package/dist/generated/global-types.d.ts +20856 -0
- package/dist/generated/global-types.js +14 -0
- package/dist/generated/global-types.js.map +1 -0
- package/dist/generated/wspace-operations.d.ts +1 -0
- package/dist/generated/wspace-types.d.ts +53362 -0
- package/dist/hooks/index.d.ts +12 -0
- package/dist/hooks/useBackendCart.d.ts +73 -0
- package/dist/hooks/useBackendCart.js +171 -0
- package/dist/hooks/useBackendCart.js.map +1 -0
- package/dist/hooks/useCart.d.ts +62 -0
- package/dist/hooks/useCart.js +90 -0
- package/dist/hooks/useCart.js.map +1 -0
- package/dist/hooks/useInstallations.d.ts +43 -0
- package/dist/hooks/useInstallations.js +140 -0
- package/dist/hooks/useInstallations.js.map +1 -0
- package/dist/hooks/useOrders.d.ts +40 -0
- package/dist/hooks/useOrders.js +73 -0
- package/dist/hooks/useOrders.js.map +1 -0
- package/dist/hooks/useProductSearch.d.ts +22 -0
- package/dist/hooks/useProductSearch.js +59 -0
- package/dist/hooks/useProductSearch.js.map +1 -0
- package/dist/hooks/useStoreGraphQL.d.ts +475 -0
- package/dist/hooks/useStoreGraphQL.js +751 -0
- package/dist/hooks/useStoreGraphQL.js.map +1 -0
- package/dist/hooks/useStoreGraphQLWithContext.d.ts +48 -0
- package/dist/hooks/useStoreGraphQLWithContext.js +39 -0
- package/dist/hooks/useStoreGraphQLWithContext.js.map +1 -0
- package/dist/hooks/useStorePermissions.d.ts +63 -0
- package/dist/hooks/useStorePermissions.js +88 -0
- package/dist/hooks/useStorePermissions.js.map +1 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.js +13 -0
- package/dist/pages/AdminDashboardPage.d.ts +3 -0
- package/dist/pages/AdminDashboardPage.js +491 -0
- package/dist/pages/AdminDashboardPage.js.map +1 -0
- package/dist/pages/AdminReviewModerationPage.d.ts +3 -0
- package/dist/pages/AdminReviewModerationPage.js +247 -0
- package/dist/pages/AdminReviewModerationPage.js.map +1 -0
- package/dist/pages/AdminStoresPage.d.ts +3 -0
- package/dist/pages/AdminStoresPage.js +442 -0
- package/dist/pages/AdminStoresPage.js.map +1 -0
- package/dist/pages/AdminSubmissionsQueuePage.d.ts +3 -0
- package/dist/pages/AdminSubmissionsQueuePage.js +387 -0
- package/dist/pages/AdminSubmissionsQueuePage.js.map +1 -0
- package/dist/pages/AppDetailPage.d.ts +3 -0
- package/dist/pages/AppDetailPage.js +166 -0
- package/dist/pages/AppDetailPage.js.map +1 -0
- package/dist/pages/AppSettingsPage.d.ts +3 -0
- package/dist/pages/AppSettingsPage.js +100 -0
- package/dist/pages/AppSettingsPage.js.map +1 -0
- package/dist/pages/CartPage.d.ts +8 -0
- package/dist/pages/CartPage.js +259 -0
- package/dist/pages/CartPage.js.map +1 -0
- package/dist/pages/InstalledAppsPage.d.ts +8 -0
- package/dist/pages/InstalledAppsPage.js +290 -0
- package/dist/pages/InstalledAppsPage.js.map +1 -0
- package/dist/pages/MarketplaceHomePage.d.ts +3 -0
- package/dist/pages/MarketplaceHomePage.js +1118 -0
- package/dist/pages/MarketplaceHomePage.js.map +1 -0
- package/dist/pages/MyLicensesPage.d.ts +3 -0
- package/dist/pages/MyLicensesPage.js +146 -0
- package/dist/pages/MyLicensesPage.js.map +1 -0
- package/dist/pages/OrderConfirmationPage.d.ts +3 -0
- package/dist/pages/OrderConfirmationPage.js +178 -0
- package/dist/pages/OrderConfirmationPage.js.map +1 -0
- package/dist/pages/OrdersPage.d.ts +8 -0
- package/dist/pages/OrdersPage.js +358 -0
- package/dist/pages/OrdersPage.js.map +1 -0
- package/dist/pages/ProductCategoryPage.d.ts +3 -0
- package/dist/pages/ProductCategoryPage.js +83 -0
- package/dist/pages/ProductCategoryPage.js.map +1 -0
- package/dist/pages/ProductDetailPage.d.ts +8 -0
- package/dist/pages/ProductDetailPage.js +1205 -0
- package/dist/pages/ProductDetailPage.js.map +1 -0
- package/dist/pages/ProductReviewsPage.d.ts +3 -0
- package/dist/pages/ProductReviewsPage.js +86 -0
- package/dist/pages/ProductReviewsPage.js.map +1 -0
- package/dist/pages/PublisherDashboardPage.d.ts +3 -0
- package/dist/pages/PublisherDashboardPage.js +154 -0
- package/dist/pages/PublisherDashboardPage.js.map +1 -0
- package/dist/pages/PublisherRevenuePage.d.ts +3 -0
- package/dist/pages/PublisherRevenuePage.js +138 -0
- package/dist/pages/PublisherRevenuePage.js.map +1 -0
- package/dist/pages/PublisherSubmissionsPage.d.ts +3 -0
- package/dist/pages/PublisherSubmissionsPage.js +174 -0
- package/dist/pages/PublisherSubmissionsPage.js.map +1 -0
- package/dist/pages/PublisherSubmitPage.d.ts +3 -0
- package/dist/pages/PublisherSubmitPage.js +224 -0
- package/dist/pages/PublisherSubmitPage.js.map +1 -0
- package/dist/pages/SearchResultsPage.d.ts +3 -0
- package/dist/pages/SearchResultsPage.js +125 -0
- package/dist/pages/SearchResultsPage.js.map +1 -0
- package/dist/pages/StoresPage.d.ts +3 -0
- package/dist/pages/StoresPage.js +154 -0
- package/dist/pages/StoresPage.js.map +1 -0
- package/dist/providers/StoreProvider.d.ts +38 -0
- package/dist/providers/StoreProvider.js +51 -0
- package/dist/providers/StoreProvider.js.map +1 -0
- package/dist/store/storeStore.d.ts +69 -0
- package/dist/store/storeStore.js +68 -0
- package/dist/store/storeStore.js.map +1 -0
- package/dist/translations/en.d.ts +518 -0
- package/dist/translations/en.js +514 -0
- package/dist/translations/en.js.map +1 -0
- package/dist/types/index.d.ts +575 -0
- package/dist/utils/index.d.ts +67 -0
- package/dist/utils/index.js +114 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/nativeBridge.d.ts +2 -0
- package/dist/utils/nativeBridge.js +2 -0
- package/package.json +105 -0
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
import { useStore as e } from "../providers/StoreProvider.js";
|
|
2
|
+
import { useInstallationStatusUpdatedSubscription as t } from "../generated/global-operations.js";
|
|
3
|
+
import { StoreInstallationStatus as n } from "../generated/global-types.js";
|
|
4
|
+
import { useInstallations as r } from "../hooks/useInstallations.js";
|
|
5
|
+
import { useMemo as i, useState as a } from "react";
|
|
6
|
+
import { useI18n as o } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
7
|
+
import { AlertCircle as s, Loader2 as c, Package as l, Plus as u, RefreshCw as d, Trash2 as f } from "lucide-react";
|
|
8
|
+
import { jsx as p, jsxs as m } from "react/jsx-runtime";
|
|
9
|
+
import { useNavigate as h } from "react-router-dom";
|
|
10
|
+
//#region src/pages/InstalledAppsPage.tsx
|
|
11
|
+
var g = [
|
|
12
|
+
{
|
|
13
|
+
label: "All",
|
|
14
|
+
value: "all"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
label: "Active",
|
|
18
|
+
value: n.Active
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
label: "Inactive",
|
|
22
|
+
value: n.Inactive
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
label: "Pending",
|
|
26
|
+
value: n.Pending
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
label: "Installing",
|
|
30
|
+
value: n.Installing
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
label: "Failed",
|
|
34
|
+
value: n.Failed
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
label: "Uninstalled",
|
|
38
|
+
value: n.Uninstalled
|
|
39
|
+
}
|
|
40
|
+
], _ = (e) => e === n.Active ? "bg-status-success-bg-subtle text-status-success-text" : e === n.Pending || e === n.Installing || e === n.Inactive ? "bg-status-warning-bg-subtle text-status-warning-text" : e === n.Failed ? "bg-status-error-bg-subtle text-status-error-text" : "bg-bg-sunken text-text-muted", v = () => {
|
|
41
|
+
let v = h(), { basePath: y, workspaceId: b } = e(), { t: x } = o(), [S, C] = a("all"), [w, T] = a(null), [E, D] = a(null), { installations: O, totalCount: k, hasMore: A, loading: j, error: M, uninstall: N, uninstallingIds: P, refetch: F, loadMore: I } = r({ filter: i(() => S === "all" ? void 0 : { status: S }, [S]) });
|
|
42
|
+
t({
|
|
43
|
+
variables: { workspaceId: b ?? "" },
|
|
44
|
+
skip: !b,
|
|
45
|
+
onData: () => {
|
|
46
|
+
F();
|
|
47
|
+
},
|
|
48
|
+
onError: (e) => {
|
|
49
|
+
console.warn("InstallationStatusUpdated subscription error:", e.message);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
let L = i(() => [...O].sort((e, t) => t.installedAt.localeCompare(e.installedAt)), [O]), R = () => {
|
|
53
|
+
v(`${y}/marketplace`);
|
|
54
|
+
}, z = async (e) => {
|
|
55
|
+
T(null), await N(e, "User requested uninstall from store UI") || T("Could not uninstall. Try again."), D(null);
|
|
56
|
+
};
|
|
57
|
+
return /* @__PURE__ */ m("div", {
|
|
58
|
+
className: "flex h-full flex-col",
|
|
59
|
+
children: [
|
|
60
|
+
/* @__PURE__ */ p("header", {
|
|
61
|
+
className: "border-b border-border-default bg-bg-surface px-6 py-4",
|
|
62
|
+
children: /* @__PURE__ */ m("div", {
|
|
63
|
+
className: "flex items-center justify-between",
|
|
64
|
+
children: [/* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("h1", {
|
|
65
|
+
className: "text-2xl font-bold text-text-primary",
|
|
66
|
+
children: x("pages.installed.title", { defaultValue: "Installed Apps" })
|
|
67
|
+
}), /* @__PURE__ */ p("p", {
|
|
68
|
+
className: "text-sm text-text-muted",
|
|
69
|
+
children: "Manage your installed applications"
|
|
70
|
+
})] }), /* @__PURE__ */ m("button", {
|
|
71
|
+
onClick: R,
|
|
72
|
+
className: "flex cursor-pointer items-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2 font-semibold text-action-primary-text transition-colors hover:opacity-90",
|
|
73
|
+
children: [/* @__PURE__ */ p(u, { className: "h-5 w-5" }), /* @__PURE__ */ p("span", { children: x("pages.installed.installNew", { defaultValue: "Install New App" }) })]
|
|
74
|
+
})]
|
|
75
|
+
})
|
|
76
|
+
}),
|
|
77
|
+
/* @__PURE__ */ p("main", {
|
|
78
|
+
className: "flex-1 overflow-y-auto p-6",
|
|
79
|
+
children: /* @__PURE__ */ m("div", {
|
|
80
|
+
className: "mx-auto max-w-6xl",
|
|
81
|
+
children: [
|
|
82
|
+
/* @__PURE__ */ m("div", {
|
|
83
|
+
className: "mb-4 flex flex-wrap items-center gap-2",
|
|
84
|
+
children: [g.map((e) => /* @__PURE__ */ p("button", {
|
|
85
|
+
onClick: () => C(e.value),
|
|
86
|
+
className: `cursor-pointer rounded-full px-3 py-1.5 text-sm font-medium transition-colors ${S === e.value ? "bg-action-primary-bg text-action-primary-text" : "bg-bg-sunken text-text-primary hover:bg-bg-surface"}`,
|
|
87
|
+
children: e.label
|
|
88
|
+
}, e.label)), /* @__PURE__ */ m("button", {
|
|
89
|
+
onClick: () => F(),
|
|
90
|
+
className: "ml-auto cursor-pointer inline-flex items-center gap-2 rounded-lg border border-border-default bg-bg-surface px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken",
|
|
91
|
+
children: [/* @__PURE__ */ p(d, { className: "h-4 w-4" }), "Refresh"]
|
|
92
|
+
})]
|
|
93
|
+
}),
|
|
94
|
+
w && /* @__PURE__ */ p("div", {
|
|
95
|
+
role: "alert",
|
|
96
|
+
className: "mb-4 rounded-lg border border-status-error-border bg-status-error-bg-subtle px-4 py-3 text-sm text-status-error-text",
|
|
97
|
+
children: w
|
|
98
|
+
}),
|
|
99
|
+
j ? /* @__PURE__ */ p("div", {
|
|
100
|
+
role: "status",
|
|
101
|
+
"aria-label": "Loading installed apps",
|
|
102
|
+
className: "flex items-center justify-center py-16",
|
|
103
|
+
children: /* @__PURE__ */ p(c, {
|
|
104
|
+
className: "h-8 w-8 animate-spin text-text-muted",
|
|
105
|
+
"aria-hidden": "true"
|
|
106
|
+
})
|
|
107
|
+
}) : M ? /* @__PURE__ */ m("div", {
|
|
108
|
+
role: "alert",
|
|
109
|
+
className: "flex flex-col items-center justify-center rounded-xl border border-status-error-border bg-status-error-bg-subtle py-16 text-center",
|
|
110
|
+
children: [
|
|
111
|
+
/* @__PURE__ */ p(s, { className: "mb-3 h-10 w-10 text-status-error-text" }),
|
|
112
|
+
/* @__PURE__ */ p("h3", {
|
|
113
|
+
className: "text-lg font-semibold text-status-error-text",
|
|
114
|
+
children: "Failed to load installations"
|
|
115
|
+
}),
|
|
116
|
+
/* @__PURE__ */ p("p", {
|
|
117
|
+
className: "mt-2 text-sm text-text-muted",
|
|
118
|
+
children: M.message
|
|
119
|
+
}),
|
|
120
|
+
/* @__PURE__ */ p("button", {
|
|
121
|
+
onClick: () => F(),
|
|
122
|
+
className: "mt-4 cursor-pointer rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text",
|
|
123
|
+
children: "Try Again"
|
|
124
|
+
})
|
|
125
|
+
]
|
|
126
|
+
}) : L.length === 0 ? /* @__PURE__ */ p("div", {
|
|
127
|
+
className: "flex items-center justify-center py-16",
|
|
128
|
+
children: /* @__PURE__ */ m("div", {
|
|
129
|
+
className: "text-center",
|
|
130
|
+
children: [
|
|
131
|
+
/* @__PURE__ */ p(l, { className: "mx-auto mb-4 h-16 w-16 text-text-muted" }),
|
|
132
|
+
/* @__PURE__ */ p("h3", {
|
|
133
|
+
className: "mb-2 text-lg font-semibold text-text-primary",
|
|
134
|
+
children: "No apps installed"
|
|
135
|
+
}),
|
|
136
|
+
/* @__PURE__ */ p("p", {
|
|
137
|
+
className: "mb-4 text-sm text-text-muted",
|
|
138
|
+
children: "Browse the marketplace to install your first app"
|
|
139
|
+
}),
|
|
140
|
+
/* @__PURE__ */ p("button", {
|
|
141
|
+
onClick: R,
|
|
142
|
+
className: "rounded-lg bg-action-primary-bg px-4 py-2 font-semibold text-action-primary-text transition-colors hover:opacity-90",
|
|
143
|
+
children: "Browse Marketplace"
|
|
144
|
+
})
|
|
145
|
+
]
|
|
146
|
+
})
|
|
147
|
+
}) : /* @__PURE__ */ m("div", {
|
|
148
|
+
className: "space-y-4 flex flex-col",
|
|
149
|
+
children: [
|
|
150
|
+
/* @__PURE__ */ m("p", {
|
|
151
|
+
"aria-live": "polite",
|
|
152
|
+
className: "text-sm text-text-muted",
|
|
153
|
+
children: [
|
|
154
|
+
k,
|
|
155
|
+
" installation",
|
|
156
|
+
k === 1 ? "" : "s",
|
|
157
|
+
" found"
|
|
158
|
+
]
|
|
159
|
+
}),
|
|
160
|
+
/* @__PURE__ */ p("ul", {
|
|
161
|
+
className: "space-y-4 flex flex-col",
|
|
162
|
+
children: L.map((e) => {
|
|
163
|
+
let t = P.has(`${e.workspaceId}:${e.productId}`);
|
|
164
|
+
return /* @__PURE__ */ p("li", {
|
|
165
|
+
className: "rounded-xl border border-border-default bg-bg-surface p-4",
|
|
166
|
+
children: /* @__PURE__ */ m("div", {
|
|
167
|
+
className: "flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between",
|
|
168
|
+
children: [/* @__PURE__ */ m("div", {
|
|
169
|
+
className: "flex items-start gap-3",
|
|
170
|
+
children: [/* @__PURE__ */ p("div", {
|
|
171
|
+
className: "flex h-12 w-12 items-center justify-center rounded-lg bg-bg-sunken text-lg font-semibold text-text-muted",
|
|
172
|
+
children: /* @__PURE__ */ p(l, { className: "h-6 w-6" })
|
|
173
|
+
}), /* @__PURE__ */ m("div", { children: [
|
|
174
|
+
/* @__PURE__ */ p("h3", {
|
|
175
|
+
className: "font-semibold text-text-primary",
|
|
176
|
+
children: e.workspaceName ?? e.workspaceId
|
|
177
|
+
}),
|
|
178
|
+
/* @__PURE__ */ m("p", {
|
|
179
|
+
className: "text-sm text-text-muted",
|
|
180
|
+
children: ["Product: ", e.productId]
|
|
181
|
+
}),
|
|
182
|
+
/* @__PURE__ */ m("div", {
|
|
183
|
+
className: "mt-2 flex flex-wrap items-center gap-2 text-xs text-text-muted",
|
|
184
|
+
children: [
|
|
185
|
+
/* @__PURE__ */ p("span", {
|
|
186
|
+
className: `rounded-full px-2 py-1 font-medium ${_(e.status)}`,
|
|
187
|
+
children: e.status
|
|
188
|
+
}),
|
|
189
|
+
e.version && /* @__PURE__ */ m("span", { children: ["v", e.version] }),
|
|
190
|
+
e.workspaceType && /* @__PURE__ */ p("span", { children: e.workspaceType })
|
|
191
|
+
]
|
|
192
|
+
})
|
|
193
|
+
] })]
|
|
194
|
+
}), /* @__PURE__ */ m("div", {
|
|
195
|
+
className: "flex items-center gap-2",
|
|
196
|
+
children: [
|
|
197
|
+
/* @__PURE__ */ p("button", {
|
|
198
|
+
onClick: () => v(`${y}/installed/${e.id}`),
|
|
199
|
+
className: "cursor-pointer rounded-lg border border-border-default px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken",
|
|
200
|
+
children: "Details"
|
|
201
|
+
}),
|
|
202
|
+
/* @__PURE__ */ p("button", {
|
|
203
|
+
onClick: () => v(`${y}/marketplace/product/${e.productId}`),
|
|
204
|
+
className: "cursor-pointer rounded-lg border border-border-default px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken",
|
|
205
|
+
children: "View Product"
|
|
206
|
+
}),
|
|
207
|
+
e.status !== n.Uninstalled && /* @__PURE__ */ m("button", {
|
|
208
|
+
onClick: () => D(e),
|
|
209
|
+
disabled: t,
|
|
210
|
+
className: "cursor-pointer inline-flex items-center gap-1.5 rounded-lg border border-status-error-border px-3 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg-subtle disabled:opacity-60",
|
|
211
|
+
children: [t ? /* @__PURE__ */ p(c, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ p(f, { className: "h-4 w-4" }), "Uninstall"]
|
|
212
|
+
})
|
|
213
|
+
]
|
|
214
|
+
})]
|
|
215
|
+
})
|
|
216
|
+
}, e.id);
|
|
217
|
+
})
|
|
218
|
+
}),
|
|
219
|
+
A && /* @__PURE__ */ p("div", {
|
|
220
|
+
className: "flex justify-center pt-6",
|
|
221
|
+
children: /* @__PURE__ */ p("button", {
|
|
222
|
+
type: "button",
|
|
223
|
+
onClick: I,
|
|
224
|
+
disabled: j,
|
|
225
|
+
className: "rounded-lg border border-border-default px-6 py-2.5 text-sm font-medium text-text-primary hover:bg-bg-subtle disabled:opacity-50",
|
|
226
|
+
children: j ? "Loading…" : "Load more"
|
|
227
|
+
})
|
|
228
|
+
})
|
|
229
|
+
]
|
|
230
|
+
})
|
|
231
|
+
]
|
|
232
|
+
})
|
|
233
|
+
}),
|
|
234
|
+
E && /* @__PURE__ */ m("div", {
|
|
235
|
+
className: "fixed inset-0 z-50 flex items-center justify-center p-4",
|
|
236
|
+
children: [/* @__PURE__ */ p("div", {
|
|
237
|
+
className: "absolute inset-0 bg-bg-overlay/50",
|
|
238
|
+
onClick: () => D(null)
|
|
239
|
+
}), /* @__PURE__ */ m("div", {
|
|
240
|
+
role: "dialog",
|
|
241
|
+
"aria-modal": "true",
|
|
242
|
+
"aria-labelledby": "installed-apps-uninstall-title",
|
|
243
|
+
className: "relative z-10 w-full max-w-md rounded-2xl border border-border-default bg-bg-surface p-6 shadow-2xl",
|
|
244
|
+
children: [
|
|
245
|
+
/* @__PURE__ */ p("h2", {
|
|
246
|
+
id: "installed-apps-uninstall-title",
|
|
247
|
+
className: "text-lg font-semibold text-text-primary",
|
|
248
|
+
children: "Uninstall app"
|
|
249
|
+
}),
|
|
250
|
+
/* @__PURE__ */ m("p", {
|
|
251
|
+
className: "mt-2 text-sm text-text-muted",
|
|
252
|
+
children: [
|
|
253
|
+
"Remove product",
|
|
254
|
+
" ",
|
|
255
|
+
/* @__PURE__ */ p("span", {
|
|
256
|
+
className: "font-medium text-text-primary",
|
|
257
|
+
children: E.productId
|
|
258
|
+
}),
|
|
259
|
+
" ",
|
|
260
|
+
"from workspace",
|
|
261
|
+
" ",
|
|
262
|
+
/* @__PURE__ */ p("span", {
|
|
263
|
+
className: "font-medium text-text-primary",
|
|
264
|
+
children: E.workspaceName ?? E.workspaceId
|
|
265
|
+
}),
|
|
266
|
+
"?"
|
|
267
|
+
]
|
|
268
|
+
}),
|
|
269
|
+
/* @__PURE__ */ m("div", {
|
|
270
|
+
className: "mt-6 flex flex-wrap justify-end gap-3",
|
|
271
|
+
children: [/* @__PURE__ */ p("button", {
|
|
272
|
+
onClick: () => D(null),
|
|
273
|
+
className: "cursor-pointer rounded-lg border border-border-default px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken",
|
|
274
|
+
children: "Cancel"
|
|
275
|
+
}), /* @__PURE__ */ p("button", {
|
|
276
|
+
onClick: () => z(E),
|
|
277
|
+
className: "cursor-pointer rounded-lg bg-status-error-bg px-4 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg-emphasis",
|
|
278
|
+
children: "Uninstall"
|
|
279
|
+
})]
|
|
280
|
+
})
|
|
281
|
+
]
|
|
282
|
+
})]
|
|
283
|
+
})
|
|
284
|
+
]
|
|
285
|
+
});
|
|
286
|
+
};
|
|
287
|
+
//#endregion
|
|
288
|
+
export { v as InstalledAppsPage };
|
|
289
|
+
|
|
290
|
+
//# sourceMappingURL=InstalledAppsPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InstalledAppsPage.js","names":[],"sources":["../../src/pages/InstalledAppsPage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useMemo, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { Package, Plus, RefreshCw, Trash2, AlertCircle, Loader2 } from 'lucide-react';\nimport { useStore } from '../providers/StoreProvider';\nimport { type InstalledApp, useInstallations } from '../hooks/useInstallations';\nimport { StoreInstallationStatus } from '../generated/global-types';\nimport type { InstallationFilterInput } from '../generated/global-types';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useInstallationStatusUpdatedSubscription } from '../generated/global-operations';\n\nconst STATUS_FILTERS: Array<{ label: string; value: StoreInstallationStatus | 'all' }> = [\n { label: 'All', value: 'all' },\n { label: 'Active', value: StoreInstallationStatus.Active },\n { label: 'Inactive', value: StoreInstallationStatus.Inactive },\n { label: 'Pending', value: StoreInstallationStatus.Pending },\n { label: 'Installing', value: StoreInstallationStatus.Installing },\n { label: 'Failed', value: StoreInstallationStatus.Failed },\n { label: 'Uninstalled', value: StoreInstallationStatus.Uninstalled },\n];\n\nconst statusBadgeClass = (status: StoreInstallationStatus): string => {\n if (status === StoreInstallationStatus.Active) {\n return 'bg-status-success-bg-subtle text-status-success-text';\n }\n if (\n status === StoreInstallationStatus.Pending ||\n status === StoreInstallationStatus.Installing ||\n status === StoreInstallationStatus.Inactive\n ) {\n return 'bg-status-warning-bg-subtle text-status-warning-text';\n }\n if (status === StoreInstallationStatus.Failed) {\n return 'bg-status-error-bg-subtle text-status-error-text';\n }\n return 'bg-bg-sunken text-text-muted';\n};\n\n/**\n * InstalledAppsPage component\n *\n * Displays installed applications for the current actor\n */\nexport const InstalledAppsPage: FC = () => {\n const navigate = useNavigate();\n const { basePath, workspaceId } = useStore();\n const { t } = useI18n();\n const [selectedStatus, setSelectedStatus] = useState<StoreInstallationStatus | 'all'>('all');\n const [errorMessage, setErrorMessage] = useState<string | null>(null);\n const [pendingUninstall, setPendingUninstall] = useState<InstalledApp | null>(null);\n\n const filter: InstallationFilterInput | undefined = useMemo(\n () => (selectedStatus === 'all' ? undefined : { status: selectedStatus }),\n [selectedStatus]\n );\n\n const {\n installations,\n totalCount,\n hasMore,\n loading,\n error,\n uninstall,\n uninstallingIds,\n refetch,\n loadMore,\n } = useInstallations({ filter });\n\n useInstallationStatusUpdatedSubscription({\n variables: { workspaceId: workspaceId ?? '' },\n skip: !workspaceId,\n onData: () => {\n void refetch();\n },\n onError: (err) => {\n console.warn('InstallationStatusUpdated subscription error:', err.message);\n },\n });\n\n const sortedInstallations = useMemo(\n () => [...installations].sort((a, b) => b.installedAt.localeCompare(a.installedAt)),\n [installations]\n );\n\n const handleInstallNew = () => {\n navigate(`${basePath}/marketplace`);\n };\n\n const handleUninstall = async (installation: InstalledApp) => {\n setErrorMessage(null);\n const ok = await uninstall(installation, 'User requested uninstall from store UI');\n if (!ok) {\n setErrorMessage(`Could not uninstall. Try again.`);\n }\n setPendingUninstall(null);\n };\n\n return (\n <div className=\"flex h-full flex-col\">\n {/* Header */}\n <header className=\"border-b border-border-default bg-bg-surface px-6 py-4\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold text-text-primary\">\n {t('pages.installed.title', { defaultValue: 'Installed Apps' })}\n </h1>\n <p className=\"text-sm text-text-muted\">Manage your installed applications</p>\n </div>\n\n <button\n onClick={handleInstallNew}\n className=\"flex cursor-pointer items-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2 font-semibold text-action-primary-text transition-colors hover:opacity-90\"\n >\n <Plus className=\"h-5 w-5\" />\n <span>{t('pages.installed.installNew', { defaultValue: 'Install New App' })}</span>\n </button>\n </div>\n </header>\n\n {/* Content */}\n <main className=\"flex-1 overflow-y-auto p-6\">\n <div className=\"mx-auto max-w-6xl\">\n <div className=\"mb-4 flex flex-wrap items-center gap-2\">\n {STATUS_FILTERS.map((filter) => (\n <button\n key={filter.label}\n onClick={() => setSelectedStatus(filter.value)}\n className={`cursor-pointer rounded-full px-3 py-1.5 text-sm font-medium transition-colors ${\n selectedStatus === filter.value\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-sunken text-text-primary hover:bg-bg-surface'\n }`}\n >\n {filter.label}\n </button>\n ))}\n <button\n onClick={() => refetch()}\n className=\"ml-auto cursor-pointer inline-flex items-center gap-2 rounded-lg border border-border-default bg-bg-surface px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken\"\n >\n <RefreshCw className=\"h-4 w-4\" />\n Refresh\n </button>\n </div>\n\n {errorMessage && (\n <div\n role=\"alert\"\n className=\"mb-4 rounded-lg border border-status-error-border bg-status-error-bg-subtle px-4 py-3 text-sm text-status-error-text\"\n >\n {errorMessage}\n </div>\n )}\n\n {loading ? (\n <div\n role=\"status\"\n aria-label=\"Loading installed apps\"\n className=\"flex items-center justify-center py-16\"\n >\n <Loader2 className=\"h-8 w-8 animate-spin text-text-muted\" aria-hidden=\"true\" />\n </div>\n ) : error ? (\n <div\n role=\"alert\"\n className=\"flex flex-col items-center justify-center rounded-xl border border-status-error-border bg-status-error-bg-subtle py-16 text-center\"\n >\n <AlertCircle className=\"mb-3 h-10 w-10 text-status-error-text\" />\n <h3 className=\"text-lg font-semibold text-status-error-text\">\n Failed to load installations\n </h3>\n <p className=\"mt-2 text-sm text-text-muted\">{error.message}</p>\n <button\n onClick={() => refetch()}\n className=\"mt-4 cursor-pointer rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text\"\n >\n Try Again\n </button>\n </div>\n ) : sortedInstallations.length === 0 ? (\n <div className=\"flex items-center justify-center py-16\">\n <div className=\"text-center\">\n <Package className=\"mx-auto mb-4 h-16 w-16 text-text-muted\" />\n <h3 className=\"mb-2 text-lg font-semibold text-text-primary\">No apps installed</h3>\n <p className=\"mb-4 text-sm text-text-muted\">\n Browse the marketplace to install your first app\n </p>\n <button\n onClick={handleInstallNew}\n className=\"rounded-lg bg-action-primary-bg px-4 py-2 font-semibold text-action-primary-text transition-colors hover:opacity-90\"\n >\n Browse Marketplace\n </button>\n </div>\n </div>\n ) : (\n <div className=\"space-y-4 flex flex-col\">\n <p aria-live=\"polite\" className=\"text-sm text-text-muted\">\n {totalCount} installation{totalCount === 1 ? '' : 's'} found\n </p>\n <ul className=\"space-y-4 flex flex-col\">\n {sortedInstallations.map((installation) => {\n const uninstalling = uninstallingIds.has(\n `${installation.workspaceId}:${installation.productId}`\n );\n return (\n <li\n key={installation.id}\n className=\"rounded-xl border border-border-default bg-bg-surface p-4\"\n >\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex items-start gap-3\">\n <div className=\"flex h-12 w-12 items-center justify-center rounded-lg bg-bg-sunken text-lg font-semibold text-text-muted\">\n <Package className=\"h-6 w-6\" />\n </div>\n <div>\n <h3 className=\"font-semibold text-text-primary\">\n {installation.workspaceName ?? installation.workspaceId}\n </h3>\n <p className=\"text-sm text-text-muted\">\n Product: {installation.productId}\n </p>\n <div className=\"mt-2 flex flex-wrap items-center gap-2 text-xs text-text-muted\">\n <span\n className={`rounded-full px-2 py-1 font-medium ${statusBadgeClass(installation.status)}`}\n >\n {installation.status}\n </span>\n {installation.version && <span>v{installation.version}</span>}\n {installation.workspaceType && (\n <span>{installation.workspaceType}</span>\n )}\n </div>\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <button\n onClick={() => navigate(`${basePath}/installed/${installation.id}`)}\n className=\"cursor-pointer rounded-lg border border-border-default px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken\"\n >\n Details\n </button>\n <button\n onClick={() =>\n navigate(`${basePath}/marketplace/product/${installation.productId}`)\n }\n className=\"cursor-pointer rounded-lg border border-border-default px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken\"\n >\n View Product\n </button>\n {installation.status !== StoreInstallationStatus.Uninstalled && (\n <button\n onClick={() => setPendingUninstall(installation)}\n disabled={uninstalling}\n className=\"cursor-pointer inline-flex items-center gap-1.5 rounded-lg border border-status-error-border px-3 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg-subtle disabled:opacity-60\"\n >\n {uninstalling ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Trash2 className=\"h-4 w-4\" />\n )}\n Uninstall\n </button>\n )}\n </div>\n </div>\n </li>\n );\n })}\n </ul>\n {hasMore && (\n <div className=\"flex justify-center pt-6\">\n <button\n type=\"button\"\n onClick={loadMore}\n disabled={loading}\n className=\"rounded-lg border border-border-default px-6 py-2.5 text-sm font-medium text-text-primary hover:bg-bg-subtle disabled:opacity-50\"\n >\n {loading ? 'Loading…' : 'Load more'}\n </button>\n </div>\n )}\n </div>\n )}\n </div>\n </main>\n\n {pendingUninstall && (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center p-4\">\n <div\n className=\"absolute inset-0 bg-bg-overlay/50\"\n onClick={() => setPendingUninstall(null)}\n />\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"installed-apps-uninstall-title\"\n className=\"relative z-10 w-full max-w-md rounded-2xl border border-border-default bg-bg-surface p-6 shadow-2xl\"\n >\n <h2\n id=\"installed-apps-uninstall-title\"\n className=\"text-lg font-semibold text-text-primary\"\n >\n Uninstall app\n </h2>\n <p className=\"mt-2 text-sm text-text-muted\">\n Remove product{' '}\n <span className=\"font-medium text-text-primary\">{pendingUninstall.productId}</span>{' '}\n from workspace{' '}\n <span className=\"font-medium text-text-primary\">\n {pendingUninstall.workspaceName ?? pendingUninstall.workspaceId}\n </span>\n ?\n </p>\n\n <div className=\"mt-6 flex flex-wrap justify-end gap-3\">\n <button\n onClick={() => setPendingUninstall(null)}\n className=\"cursor-pointer rounded-lg border border-border-default px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken\"\n >\n Cancel\n </button>\n <button\n onClick={() => handleUninstall(pendingUninstall)}\n className=\"cursor-pointer rounded-lg bg-status-error-bg px-4 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg-emphasis\"\n >\n Uninstall\n </button>\n </div>\n </div>\n </div>\n )}\n </div>\n );\n};\n"],"mappings":"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"}
|