@xapps-platform/marketplace-ui 0.1.9 → 0.1.11

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/dist/index.d.ts CHANGED
@@ -11,5 +11,5 @@ export { CatalogPage } from "./pages/CatalogPage";
11
11
  export { default as XappDetailPage, XappPlansPage } from "./pages/XappDetailPage";
12
12
  export { WidgetView } from "./pages/WidgetView";
13
13
  export { resolvePaymentLockStateFromGuardSummary, type PaymentLockResolution, type PaymentReconcileState, } from "./utils/paymentLock";
14
- export type { CatalogXapp, CatalogXappDetail, InstallationInfo, MarketplaceClient, MarketplaceEnv, MarketplaceHostAdapter, OperationalSurfaceDescriptor, OperationalSurfacePlacement, OperationalSurfacesDescriptor, } from "./types";
14
+ export type { CatalogXapp, CatalogXappDetail, InstallationInfo, MarketplaceClient, MarketplaceEnv, MarketplaceHostAdapter, MarketplaceInstallationPolicy, OperationalSurfaceDescriptor, OperationalSurfacePlacement, OperationalSurfacesDescriptor, } from "./types";
15
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,mBAAmB,CAAC;AAE3B,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,QAAQ,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClF,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EACL,uCAAuC,EACvC,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,GAC3B,MAAM,qBAAqB,CAAC;AAE7B,YAAY,EACV,WAAW,EACX,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,sBAAsB,EACtB,4BAA4B,EAC5B,2BAA2B,EAC3B,6BAA6B,GAC9B,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,mBAAmB,CAAC;AAE3B,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,QAAQ,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClF,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EACL,uCAAuC,EACvC,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,GAC3B,MAAM,qBAAqB,CAAC;AAE7B,YAAY,EACV,WAAW,EACX,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,sBAAsB,EACtB,6BAA6B,EAC7B,4BAA4B,EAC5B,2BAA2B,EAC3B,6BAA6B,GAC9B,MAAM,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -978,6 +978,14 @@ function getDefaultWidgetId(x) {
978
978
  const pick = def || widgets[0];
979
979
  return readFirstString(asRecord(pick).id) || null;
980
980
  }
981
+ function getDefaultWidgetName(x, locale) {
982
+ const rawWidgets = asRecord(x.manifest).widgets;
983
+ const widgets = Array.isArray(rawWidgets) ? rawWidgets : null;
984
+ if (!widgets || widgets.length === 0) return null;
985
+ const def = widgets.find((w) => asRecord(w).default === true);
986
+ const pick = asRecord(def || widgets[0]);
987
+ return resolveMarketplaceText(pick.title, locale) || readFirstString(pick.name, pick.id) || null;
988
+ }
981
989
  function buildCatalogFilterStorageKey(input) {
982
990
  const mode = input.isEmbedded ? "embed" : "portal";
983
991
  const scope = input.singleXappMode && input.xappId ? `xapp:${input.xappId}` : "catalog";
@@ -1011,6 +1019,11 @@ function CatalogPage() {
1011
1019
  const canMutate = host.canMutate ? host.canMutate() : true;
1012
1020
  const addAppLabel = env?.copy?.addAppLabel || "Add app";
1013
1021
  const removeAppLabel = env?.copy?.removeAppLabel || "Remove app";
1022
+ const openAppLabel = env?.copy?.openAppLabel || t("xapp.open_app", void 0, "Open app");
1023
+ const installationPolicyResolved = env?.installationPolicyResolved !== false;
1024
+ const mutationControlsReady = installationPolicyResolved || !host.subjectId || !canMutate;
1025
+ const autoUpdateMode = mutationControlsReady && (env?.installationPolicy ?? host.installationPolicy)?.update_mode === "auto_update_compatible" && Boolean(host.subjectId);
1026
+ const autoAvailableMode = mutationControlsReady && (env?.installationPolicy ?? host.installationPolicy)?.mode === "auto_available" && Boolean(host.subjectId);
1014
1027
  const loc = useLocation();
1015
1028
  const token = useQueryToken();
1016
1029
  const tokenSearch = buildTokenSearch(token, loc.search);
@@ -1075,6 +1088,14 @@ function CatalogPage() {
1075
1088
  setInstalledOnly(Boolean(stored?.addedOnly));
1076
1089
  setSelectedTag(typeof stored?.selectedTag === "string" ? stored.selectedTag : defaultTag);
1077
1090
  }, [defaultTag, storageKey]);
1091
+ useEffect3(() => {
1092
+ if (!autoAvailableMode || !installedOnly) return;
1093
+ setInstalledOnly(false);
1094
+ writeStoredCatalogFilters(storageKey, {
1095
+ addedOnly: false,
1096
+ selectedTag: selectedTag || ""
1097
+ });
1098
+ }, [autoAvailableMode, installedOnly, selectedTag, storageKey]);
1078
1099
  useEffect3(() => {
1079
1100
  const restrictedTags = env?.tags ?? [];
1080
1101
  if (selectedTag && restrictedTags.length > 0 && !restrictedTags.includes(selectedTag)) {
@@ -1192,7 +1213,7 @@ function CatalogPage() {
1192
1213
  }
1193
1214
  )
1194
1215
  ] }),
1195
- /* @__PURE__ */ jsxs3("label", { className: "mx-checkbox-label", children: [
1216
+ mutationControlsReady && !autoAvailableMode ? /* @__PURE__ */ jsxs3("label", { className: "mx-checkbox-label", children: [
1196
1217
  /* @__PURE__ */ jsx6(
1197
1218
  "input",
1198
1219
  {
@@ -1210,7 +1231,7 @@ function CatalogPage() {
1210
1231
  }
1211
1232
  ),
1212
1233
  /* @__PURE__ */ jsx6("span", { className: "mx-label mx-label-inline", children: t("common.added_only", void 0, "Added only") })
1213
- ] })
1234
+ ] }) : null
1214
1235
  ] }) }),
1215
1236
  busy && items.length === 0 ? /* @__PURE__ */ jsx6("div", { className: "mx-grid", "aria-busy": "true", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsxs3("div", { className: "mx-skeleton-card", children: [
1216
1237
  /* @__PURE__ */ jsx6("div", { className: "mx-skeleton-card-image" }),
@@ -1240,7 +1261,7 @@ function CatalogPage() {
1240
1261
  /* @__PURE__ */ jsx6("div", { className: "mx-grid", children: filtered.length === 0 && !busy ? /* @__PURE__ */ jsxs3("div", { className: "mx-empty-catalog", children: [
1241
1262
  /* @__PURE__ */ jsx6("div", { className: "mx-empty-catalog-icon", children: "\u2315" }),
1242
1263
  /* @__PURE__ */ jsx6("div", { className: "mx-empty-catalog-title", children: t("catalog.no_apps_found", void 0, "No apps found") }),
1243
- /* @__PURE__ */ jsx6("div", { className: "mx-empty-catalog-desc", children: installedOnly && items.length > 0 ? t(
1264
+ /* @__PURE__ */ jsx6("div", { className: "mx-empty-catalog-desc", children: !autoAvailableMode && installedOnly && items.length > 0 ? t(
1244
1265
  "catalog.empty_added_only",
1245
1266
  void 0,
1246
1267
  "No apps are installed for the current subject yet. Turn off Added only to browse the full catalog."
@@ -1260,7 +1281,9 @@ function CatalogPage() {
1260
1281
  const image = typeof manifest.image === "string" ? manifest.image : "https://picsum.photos/seed/" + x.slug + "/560/320";
1261
1282
  const inst = installationsByXappId[String(x.id)];
1262
1283
  const installed = Boolean(inst);
1284
+ const updateAvailable = Boolean(inst?.updateAvailable);
1263
1285
  const defaultWidgetId = getDefaultWidgetId(x);
1286
+ const defaultWidgetName = getDefaultWidgetName(x, locale) || t("common.widget", void 0, "Widget");
1264
1287
  const xTerms = asRecord(manifest.terms);
1265
1288
  const requiresTerms = Boolean(
1266
1289
  Object.keys(xTerms).length > 0 || typeof xTerms.text === "string" && xTerms.text.trim() || typeof xTerms.url === "string" && xTerms.url.trim()
@@ -1293,7 +1316,7 @@ function CatalogPage() {
1293
1316
  )
1294
1317
  ] }) : /* @__PURE__ */ jsx6("div", { className: "mx-card-publisher", children: t("common.catalog_app", void 0, "Catalog app") }),
1295
1318
  /* @__PURE__ */ jsxs3("div", { className: "mx-card-badges", children: [
1296
- installed && /* @__PURE__ */ jsxs3("span", { className: "mx-card-installed-badge", children: [
1319
+ !autoAvailableMode && installed && /* @__PURE__ */ jsxs3("span", { className: "mx-card-installed-badge", children: [
1297
1320
  /* @__PURE__ */ jsx6("span", { className: "mx-card-installed-badge-dot" }),
1298
1321
  t("common.added", void 0, "Added")
1299
1322
  ] }),
@@ -1317,7 +1340,7 @@ function CatalogPage() {
1317
1340
  children: t("catalog.view_details", void 0, "View details")
1318
1341
  }
1319
1342
  ),
1320
- canMutate && (!installed ? /* @__PURE__ */ jsx6(
1343
+ canMutate && mutationControlsReady && (!installed ? /* @__PURE__ */ jsx6(
1321
1344
  "button",
1322
1345
  {
1323
1346
  className: "mx-btn mx-btn-primary mx-btn-sm",
@@ -1331,12 +1354,50 @@ function CatalogPage() {
1331
1354
  host.requestInstall({
1332
1355
  xappId: String(x.id),
1333
1356
  defaultWidgetId,
1357
+ xappTitle: title,
1358
+ widgetName: defaultWidgetName,
1359
+ openAfterInstall: autoAvailableMode && Boolean(defaultWidgetId),
1334
1360
  subjectId: host.subjectId ?? null
1335
1361
  });
1336
1362
  },
1337
- children: addAppLabel
1363
+ children: autoAvailableMode ? openAppLabel : addAppLabel
1364
+ }
1365
+ ) : autoAvailableMode ? /* @__PURE__ */ jsx6(
1366
+ "button",
1367
+ {
1368
+ className: "mx-btn mx-btn-primary mx-btn-sm",
1369
+ onClick: (e) => {
1370
+ e.preventDefault();
1371
+ e.stopPropagation();
1372
+ if (!defaultWidgetId || !inst?.installationId) {
1373
+ navigate(detailTo);
1374
+ return;
1375
+ }
1376
+ if (updateAvailable && host.requestUpdate && autoUpdateMode) {
1377
+ host.requestUpdate({
1378
+ installationId: inst.installationId,
1379
+ xappId: String(x.id),
1380
+ widgetId: defaultWidgetId,
1381
+ xappTitle: title,
1382
+ widgetName: defaultWidgetName
1383
+ });
1384
+ return;
1385
+ }
1386
+ if (updateAvailable) {
1387
+ navigate(detailTo);
1388
+ return;
1389
+ }
1390
+ host.openWidget({
1391
+ installationId: inst.installationId,
1392
+ widgetId: defaultWidgetId,
1393
+ xappId: String(x.id),
1394
+ xappTitle: title,
1395
+ widgetName: t("common.widget", void 0, "Widget")
1396
+ });
1397
+ },
1398
+ children: openAppLabel
1338
1399
  }
1339
- ) : /* @__PURE__ */ jsx6(
1400
+ ) : !autoAvailableMode ? /* @__PURE__ */ jsx6(
1340
1401
  "button",
1341
1402
  {
1342
1403
  className: "mx-btn mx-btn-outline mx-btn-sm mx-btn-danger-text",
@@ -1354,7 +1415,7 @@ function CatalogPage() {
1354
1415
  },
1355
1416
  children: removeAppLabel
1356
1417
  }
1357
- ))
1418
+ ) : null)
1358
1419
  ] })
1359
1420
  ] }, x.id);
1360
1421
  }) })
@@ -4878,6 +4939,10 @@ function XappDetailPageContent(props) {
4878
4939
  const removeAppLabel = env?.copy?.removeAppLabel || t("xapp.remove_from_workspace", void 0, "Remove from workspace");
4879
4940
  const updateAppLabel = env?.copy?.updateAppLabel || t("xapp.update_app", void 0, "Update app");
4880
4941
  const openAppLabel = env?.copy?.openAppLabel || t("xapp.open_app", void 0, "Open app");
4942
+ const hasSubject = Boolean(host.subjectId);
4943
+ const installationPolicyResolved = env?.installationPolicyResolved !== false;
4944
+ const mutationControlsReady = installationPolicyResolved || !hasSubject || !canMutate;
4945
+ const installationPolicy = env?.installationPolicy ?? host.installationPolicy ?? null;
4881
4946
  const [data, setData] = useState7(null);
4882
4947
  const [monetization, setMonetization] = useState7(null);
4883
4948
  const [error, setError] = useState7(null);
@@ -4886,13 +4951,14 @@ function XappDetailPageContent(props) {
4886
4951
  const [termsOpen, setTermsOpen] = useState7(false);
4887
4952
  const [termsAccepted, setTermsAccepted] = useState7(false);
4888
4953
  const [termsAction, setTermsAction] = useState7("none");
4954
+ const [termsWidgetId, setTermsWidgetId] = useState7(null);
4955
+ const [termsWidgetName, setTermsWidgetName] = useState7(null);
4889
4956
  const [removeConfirmOpen, setRemoveConfirmOpen] = useState7(false);
4890
4957
  const [guardSummaryOpen, setGuardSummaryOpen] = useState7(false);
4891
4958
  const [checkoutBusyPackageSlug, setCheckoutBusyPackageSlug] = useState7("");
4892
4959
  const [checkoutError, setCheckoutError] = useState7(null);
4893
4960
  const [checkoutNotice, setCheckoutNotice] = useState7(null);
4894
4961
  const checkoutFinalizeKeyRef = useRef("");
4895
- const hasSubject = Boolean(host.subjectId);
4896
4962
  const installationsByXappId = hasSubject ? host.getInstallationsByXappId() : {};
4897
4963
  const routeInstallationId = String(routeQuery.get("installationId") || "").trim();
4898
4964
  const installation = xappId && installationsByXappId[String(xappId)] ? installationsByXappId[String(xappId)] : xappId && routeInstallationId ? {
@@ -4900,7 +4966,9 @@ function XappDetailPageContent(props) {
4900
4966
  xappId: String(xappId)
4901
4967
  } : null;
4902
4968
  const updateAvailable = Boolean(installation?.updateAvailable);
4903
- const widgetsEnabled = Boolean(installation) && !updateAvailable && hasSubject;
4969
+ const autoAvailableMode = mutationControlsReady && installationPolicy?.mode === "auto_available" && Boolean(hasSubject) && canMutate;
4970
+ const autoUpdateMode = mutationControlsReady && installationPolicy?.update_mode === "auto_update_compatible" && Boolean(hasSubject) && canMutate;
4971
+ const widgetsEnabled = Boolean(hasSubject) && (Boolean(installation) || autoAvailableMode) && (!updateAvailable || autoUpdateMode);
4904
4972
  const isEmbedded = window.location.pathname.startsWith("/embed");
4905
4973
  const singleXappMode = env?.singleXappMode;
4906
4974
  async function refresh() {
@@ -5001,51 +5069,122 @@ function XappDetailPageContent(props) {
5001
5069
  const termsUrl = readString5(terms?.url);
5002
5070
  const hasTermsContent = Boolean(termsText || termsUrl);
5003
5071
  const requiresTerms = Boolean(terms || action === "install" || action === "update");
5072
+ function requestInstallForWidget(widgetId, widgetName = null, acceptedTerms = false, openAfterInstall = false) {
5073
+ host.requestInstall({
5074
+ xappId: String(xappId ?? ""),
5075
+ defaultWidgetId: widgetId,
5076
+ xappTitle: String(title),
5077
+ widgetName,
5078
+ openAfterInstall,
5079
+ subjectId: host.subjectId ?? null,
5080
+ ...acceptedTerms ? { termsAccepted: true } : {}
5081
+ });
5082
+ }
5083
+ function requestUpdateForWidget(widgetId, acceptedTerms = false) {
5084
+ if (!installation?.installationId || !host.requestUpdate) return;
5085
+ const activeWidget = widgetId && Array.isArray(widgets) ? widgets.find((entry) => readString5(entry.id) === widgetId) || null : null;
5086
+ host.requestUpdate({
5087
+ installationId: installation.installationId,
5088
+ xappId: String(xappId ?? ""),
5089
+ widgetId,
5090
+ xappTitle: String(title),
5091
+ widgetName: resolveMarketplaceText(activeWidget?.title, locale) || readString5(activeWidget?.name) || null,
5092
+ ...acceptedTerms ? { termsAccepted: true } : {}
5093
+ });
5094
+ }
5095
+ function openInstalledWidget(widgetId, widgetName, toolName) {
5096
+ if (!installation) return;
5097
+ if (env?.embedMode) {
5098
+ navigate({
5099
+ pathname: isEmbedded ? `/widget/${encodeURIComponent(installation.installationId)}/${encodeURIComponent(widgetId)}` : `/marketplace/widget/${encodeURIComponent(installation.installationId)}/${encodeURIComponent(widgetId)}`,
5100
+ search: tokenSearch
5101
+ });
5102
+ return;
5103
+ }
5104
+ host.openWidget({
5105
+ installationId: installation.installationId,
5106
+ widgetId,
5107
+ xappId: String(xappId ?? ""),
5108
+ xappTitle: String(title),
5109
+ widgetName,
5110
+ toolName
5111
+ });
5112
+ }
5113
+ function launchWidgetForSubject(widgetId, widgetName, toolName) {
5114
+ if (!hasSubject || !widgetId) return;
5115
+ if (!installation) {
5116
+ if (requiresTerms) {
5117
+ setTermsAccepted(false);
5118
+ setTermsAction("install");
5119
+ setTermsWidgetId(widgetId);
5120
+ setTermsWidgetName(widgetName);
5121
+ setTermsOpen(true);
5122
+ return;
5123
+ }
5124
+ requestInstallForWidget(widgetId, widgetName, false, true);
5125
+ return;
5126
+ }
5127
+ if (updateAvailable) {
5128
+ if (autoUpdateMode && host.requestUpdate) {
5129
+ if (requiresTerms) {
5130
+ setTermsAccepted(false);
5131
+ setTermsAction("update");
5132
+ setTermsWidgetId(widgetId);
5133
+ setTermsWidgetName(widgetName);
5134
+ setTermsOpen(true);
5135
+ return;
5136
+ }
5137
+ requestUpdateForWidget(widgetId);
5138
+ }
5139
+ return;
5140
+ }
5141
+ openInstalledWidget(widgetId, widgetName, toolName);
5142
+ }
5004
5143
  useEffect9(() => {
5005
5144
  if (action === "install") {
5006
5145
  setTermsAccepted(false);
5007
5146
  setTermsAction("install");
5147
+ setTermsWidgetId(readString5(defaultWidget?.id) || null);
5148
+ setTermsWidgetName(resolveMarketplaceText(defaultWidget?.title, locale) || null);
5008
5149
  setTermsOpen(true);
5009
5150
  return;
5010
5151
  }
5011
5152
  if (action === "update" && installation) {
5012
5153
  setTermsAccepted(false);
5013
5154
  setTermsAction("update");
5155
+ setTermsWidgetId(null);
5156
+ setTermsWidgetName(null);
5014
5157
  setTermsOpen(true);
5015
5158
  }
5016
- }, [action, installation]);
5159
+ }, [action, defaultWidget, installation, locale]);
5017
5160
  useEffect9(() => {
5018
5161
  if (action !== "open-widget") return;
5019
5162
  if (env?.embedMode) return;
5020
- if (!installation || !widgetsEnabled) return;
5163
+ if (!requestedWidget || !widgetsEnabled) return;
5021
5164
  const widget = requestedWidget;
5022
5165
  const widgetId = readString5(widget?.id);
5023
5166
  if (!widgetId) return;
5024
5167
  const key = [
5025
5168
  String(xappId ?? ""),
5026
- installation.installationId,
5169
+ installation?.installationId || "auto",
5027
5170
  widgetId,
5028
5171
  readString5(queryToolName)
5029
5172
  ].join(":");
5030
5173
  if (autoOpenedWidgetKeyRef.current === key) return;
5031
5174
  autoOpenedWidgetKeyRef.current = key;
5032
- host.openWidget({
5033
- installationId: installation.installationId,
5175
+ launchWidgetForSubject(
5034
5176
  widgetId,
5035
- xappId: String(xappId ?? ""),
5036
- xappTitle: String(title),
5037
- widgetName: resolveMarketplaceText(widget?.title, locale) || readString5(widget?.widget_name) || readString5(widget?.name) || t("common.widget", void 0, "Widget"),
5038
- toolName: readString5(widget?.bind_tool_name)
5039
- });
5177
+ resolveMarketplaceText(widget?.title, locale) || readString5(widget?.widget_name) || readString5(widget?.name) || t("common.widget", void 0, "Widget"),
5178
+ readString5(widget?.bind_tool_name)
5179
+ );
5040
5180
  }, [
5041
5181
  action,
5042
5182
  env?.embedMode,
5043
- host,
5044
5183
  installation,
5184
+ launchWidgetForSubject,
5045
5185
  locale,
5046
5186
  queryToolName,
5047
5187
  requestedWidget,
5048
- title,
5049
5188
  widgetsEnabled,
5050
5189
  xappId
5051
5190
  ]);
@@ -5630,8 +5769,8 @@ function XappDetailPageContent(props) {
5630
5769
  updateAvailable ? /* @__PURE__ */ jsx14("div", { className: "mx-detail-update-pill", children: t("xapp.update_available", void 0, "Update available") }) : null
5631
5770
  ] })
5632
5771
  ] }),
5633
- /* @__PURE__ */ jsx14("div", { className: "mx-detail-actions", children: canMutate ? /* @__PURE__ */ jsxs10(Fragment8, { children: [
5634
- installation && updateAvailable && host.requestUpdate ? /* @__PURE__ */ jsx14(
5772
+ /* @__PURE__ */ jsx14("div", { className: "mx-detail-actions", children: canMutate && mutationControlsReady ? /* @__PURE__ */ jsxs10(Fragment8, { children: [
5773
+ installation && updateAvailable && host.requestUpdate && installationPolicy?.update_mode !== "auto_update_compatible" ? /* @__PURE__ */ jsx14(
5635
5774
  "button",
5636
5775
  {
5637
5776
  className: "mx-btn mx-btn-primary",
@@ -5640,14 +5779,13 @@ function XappDetailPageContent(props) {
5640
5779
  if (requiresTerms) {
5641
5780
  setTermsAccepted(false);
5642
5781
  setTermsAction("update");
5782
+ setTermsWidgetId(null);
5783
+ setTermsWidgetName(null);
5643
5784
  setTermsOpen(true);
5644
5785
  return;
5645
5786
  }
5646
5787
  if (!installation.installationId) return;
5647
- host.requestUpdate?.({
5648
- installationId: installation.installationId,
5649
- xappId: String(xappId ?? "")
5650
- });
5788
+ requestUpdateForWidget(null);
5651
5789
  },
5652
5790
  children: updateAppLabel
5653
5791
  }
@@ -5661,18 +5799,23 @@ function XappDetailPageContent(props) {
5661
5799
  if (requiresTerms) {
5662
5800
  setTermsAccepted(false);
5663
5801
  setTermsAction("install");
5802
+ setTermsWidgetId(readString5(defaultWidget?.id) || null);
5803
+ setTermsWidgetName(
5804
+ resolveMarketplaceText(defaultWidget?.title, locale) || null
5805
+ );
5664
5806
  setTermsOpen(true);
5665
5807
  return;
5666
5808
  }
5667
- host.requestInstall({
5668
- xappId: String(xappId ?? ""),
5669
- defaultWidgetId: readString5(defaultWidget?.id) || null,
5670
- subjectId: host.subjectId ?? null
5671
- });
5809
+ requestInstallForWidget(
5810
+ readString5(defaultWidget?.id) || null,
5811
+ resolveMarketplaceText(defaultWidget?.title, locale) || null,
5812
+ false,
5813
+ autoAvailableMode
5814
+ );
5672
5815
  },
5673
- children: addAppLabel
5816
+ children: autoAvailableMode ? openAppLabel : addAppLabel
5674
5817
  }
5675
- ) : /* @__PURE__ */ jsx14(
5818
+ ) : !autoAvailableMode ? /* @__PURE__ */ jsx14(
5676
5819
  "button",
5677
5820
  {
5678
5821
  className: "mx-btn mx-btn-outline",
@@ -5684,7 +5827,7 @@ function XappDetailPageContent(props) {
5684
5827
  },
5685
5828
  children: removeAppLabel
5686
5829
  }
5687
- )
5830
+ ) : null
5688
5831
  ] }) : null })
5689
5832
  ] }),
5690
5833
  /* @__PURE__ */ jsxs10("div", { className: "mx-detail-grid", children: [
@@ -5695,11 +5838,19 @@ function XappDetailPageContent(props) {
5695
5838
  ] }),
5696
5839
  /* @__PURE__ */ jsxs10("section", { className: "mx-detail-section mx-detail-section-widgets", children: [
5697
5840
  /* @__PURE__ */ jsx14("h2", { className: "mx-section-title", children: t("xapp.available_views_title", void 0, "Available Views") }),
5698
- !widgetsEnabled ? /* @__PURE__ */ jsx14("div", { className: "mx-sidebar-card mx-detail-empty", children: !installation ? t(
5841
+ !widgetsEnabled ? /* @__PURE__ */ jsx14("div", { className: "mx-sidebar-card mx-detail-empty", children: !installation ? autoAvailableMode ? t(
5842
+ "xapp.open_to_access_views",
5843
+ void 0,
5844
+ "Open this app to start and install it automatically for your workspace."
5845
+ ) : t(
5699
5846
  "xapp.add_to_access_views",
5700
5847
  void 0,
5701
5848
  "Add this app to your workspace to access its available views."
5702
- ) : updateAvailable ? t(
5849
+ ) : updateAvailable ? autoUpdateMode ? t(
5850
+ "xapp.update_to_access_views_auto",
5851
+ void 0,
5852
+ "Open a view to update the app automatically for your workspace."
5853
+ ) : t(
5703
5854
  "xapp.update_to_access_views",
5704
5855
  void 0,
5705
5856
  "An update is available. Please update the app to access its available views."
@@ -5722,24 +5873,10 @@ function XappDetailPageContent(props) {
5722
5873
  disabled,
5723
5874
  className: `mx-detail-widget-card ${disabled ? "is-disabled" : ""} ${isDefault ? "is-default" : ""}`,
5724
5875
  onClick: () => {
5725
- if (!installation || !widgetsEnabled) return;
5876
+ if (!widgetsEnabled) return;
5726
5877
  const widgetId = readString5(w.id);
5727
5878
  if (!widgetId) return;
5728
- if (env?.embedMode && installation) {
5729
- navigate({
5730
- pathname: isEmbedded ? `/widget/${encodeURIComponent(installation.installationId)}/${encodeURIComponent(widgetId)}` : `/marketplace/widget/${encodeURIComponent(installation.installationId)}/${encodeURIComponent(widgetId)}`,
5731
- search: tokenSearch
5732
- });
5733
- return;
5734
- }
5735
- host.openWidget({
5736
- installationId: installation.installationId,
5737
- widgetId,
5738
- xappId: String(xappId ?? ""),
5739
- xappTitle: String(title),
5740
- widgetName: name,
5741
- toolName: readString5(w.bind_tool_name)
5742
- });
5879
+ launchWidgetForSubject(widgetId, name, readString5(w.bind_tool_name));
5743
5880
  },
5744
5881
  children: [
5745
5882
  /* @__PURE__ */ jsx14("div", { className: "mx-detail-widget-icon", children: widgetType === "read" ? /* @__PURE__ */ jsxs10(
@@ -6059,26 +6196,18 @@ function XappDetailPageContent(props) {
6059
6196
  ] }) : null
6060
6197
  ] }) : null,
6061
6198
  plansCard,
6062
- installation && defaultWidget && hasSubject && /* @__PURE__ */ jsx14(
6199
+ defaultWidget && hasSubject && (installation || autoAvailableMode) && /* @__PURE__ */ jsx14(
6063
6200
  "button",
6064
6201
  {
6065
6202
  className: "mx-btn mx-btn-primary mx-detail-primary-cta",
6066
6203
  onClick: () => {
6067
- if (env?.embedMode) {
6068
- navigate({
6069
- pathname: isEmbedded ? `/widget/${encodeURIComponent(installation.installationId)}/${encodeURIComponent(String(defaultWidget.id))}` : `/marketplace/widget/${encodeURIComponent(installation.installationId)}/${encodeURIComponent(String(defaultWidget.id))}`,
6070
- search: tokenSearch
6071
- });
6072
- return;
6073
- }
6074
- host.openWidget({
6075
- installationId: installation.installationId,
6076
- widgetId: readString5(defaultWidget.id),
6077
- xappId: String(xappId ?? ""),
6078
- xappTitle: String(title),
6079
- widgetName: resolveMarketplaceText(defaultWidget?.title, locale) || readString5(defaultWidget?.widget_name) || readString5(defaultWidget?.name) || t("common.widget", void 0, "Widget"),
6080
- toolName: readString5(defaultWidget?.bind_tool_name)
6081
- });
6204
+ const widgetId = readString5(defaultWidget.id);
6205
+ if (!widgetId) return;
6206
+ launchWidgetForSubject(
6207
+ widgetId,
6208
+ resolveMarketplaceText(defaultWidget?.title, locale) || readString5(defaultWidget?.widget_name) || readString5(defaultWidget?.name) || t("common.widget", void 0, "Widget"),
6209
+ readString5(defaultWidget?.bind_tool_name)
6210
+ );
6082
6211
  },
6083
6212
  children: openAppLabel
6084
6213
  }
@@ -6259,21 +6388,35 @@ function XappDetailPageContent(props) {
6259
6388
  ] })
6260
6389
  ] }),
6261
6390
  /* @__PURE__ */ jsxs10("div", { className: "mx-detail-modal-actions", children: [
6262
- /* @__PURE__ */ jsx14("button", { className: "mx-btn mx-btn-outline", onClick: () => setTermsOpen(false), children: t("common.cancel", void 0, "Cancel") }),
6391
+ /* @__PURE__ */ jsx14(
6392
+ "button",
6393
+ {
6394
+ className: "mx-btn mx-btn-outline",
6395
+ onClick: () => {
6396
+ setTermsOpen(false);
6397
+ setTermsAction("none");
6398
+ setTermsWidgetId(null);
6399
+ setTermsWidgetName(null);
6400
+ },
6401
+ children: t("common.cancel", void 0, "Cancel")
6402
+ }
6403
+ ),
6263
6404
  termsAction === "install" ? /* @__PURE__ */ jsx14(
6264
6405
  "button",
6265
6406
  {
6266
6407
  className: "mx-btn mx-btn-primary",
6267
6408
  disabled: !termsAccepted,
6268
6409
  onClick: () => {
6269
- host.requestInstall({
6270
- xappId: String(xappId ?? ""),
6271
- defaultWidgetId: readString5(defaultWidget?.id) || null,
6272
- subjectId: host.subjectId ?? null,
6273
- termsAccepted: true
6274
- });
6410
+ requestInstallForWidget(
6411
+ termsWidgetId ?? readString5(defaultWidget?.id) ?? null,
6412
+ termsWidgetName || resolveMarketplaceText(defaultWidget?.title, locale) || null,
6413
+ true,
6414
+ autoAvailableMode
6415
+ );
6275
6416
  setTermsOpen(false);
6276
6417
  setTermsAction("none");
6418
+ setTermsWidgetId(null);
6419
+ setTermsWidgetName(null);
6277
6420
  },
6278
6421
  children: t("xapp.accept_add_app", void 0, "Accept & Add app")
6279
6422
  }
@@ -6284,13 +6427,11 @@ function XappDetailPageContent(props) {
6284
6427
  disabled: !termsAccepted || !installation,
6285
6428
  onClick: () => {
6286
6429
  if (!installation) return;
6287
- host.requestUpdate?.({
6288
- installationId: installation.installationId,
6289
- xappId: String(xappId ?? ""),
6290
- termsAccepted: true
6291
- });
6430
+ requestUpdateForWidget(termsWidgetId, true);
6292
6431
  setTermsOpen(false);
6293
6432
  setTermsAction("none");
6433
+ setTermsWidgetId(null);
6434
+ setTermsWidgetName(null);
6294
6435
  },
6295
6436
  children: t("xapp.accept_update", void 0, "Accept & Update")
6296
6437
  }
@@ -6490,7 +6631,19 @@ function WidgetView() {
6490
6631
  let alive = true;
6491
6632
  void (async () => {
6492
6633
  try {
6493
- const { token: wToken, context } = await client.getWidgetToken(installationId, widgetId);
6634
+ const widgetTokenResponse = await client.getWidgetToken(installationId, widgetId);
6635
+ const resolvedWidgetId = readString(asRecord(widgetTokenResponse).widgetId);
6636
+ if (resolvedWidgetId && resolvedWidgetId !== widgetId) {
6637
+ navigate(
6638
+ {
6639
+ pathname: isEmbedded ? `/widget/${encodeURIComponent(installationId)}/${encodeURIComponent(resolvedWidgetId)}` : `/marketplace/widget/${encodeURIComponent(installationId)}/${encodeURIComponent(resolvedWidgetId)}`,
6640
+ search: tokenSearch
6641
+ },
6642
+ { replace: true }
6643
+ );
6644
+ return;
6645
+ }
6646
+ const { token: wToken, context } = widgetTokenResponse;
6494
6647
  if (!alive) return;
6495
6648
  setSessionExpired(null);
6496
6649
  setWidgetToken(wToken);
@@ -6504,7 +6657,7 @@ function WidgetView() {
6504
6657
  return () => {
6505
6658
  alive = false;
6506
6659
  };
6507
- }, [installationId, widgetId, client]);
6660
+ }, [installationId, widgetId, client, isEmbedded, navigate, tokenSearch]);
6508
6661
  async function remintWidgetSession() {
6509
6662
  if (!installationId || !widgetId) {
6510
6663
  throw new Error("Missing installationId/widgetId for widget refresh");