@growthub/cli 0.14.9 → 0.14.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/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/add-ons/[providerId]/callback/route.js +35 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/add-ons/[providerId]/failure/route.js +35 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/add-ons/[providerId]/schedule/route.js +423 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/add-ons/providers/[providerId]/connect/route.js +78 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/add-ons/providers/[providerId]/credentials/route.js +276 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/add-ons/providers/[providerId]/products/[productId]/resources/route.js +173 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/add-ons/providers/[providerId]/products/sync/route.js +347 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/add-ons/providers/[providerId]/sync/route.js +293 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/add-ons/upstash/provider/connect/route.js +7 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/add-ons/upstash/provider/sync/route.js +7 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/add-ons/upstash/sync/route.js +197 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/apps/route.js +1 -1
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/patch/preflight/route.js +38 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/sandbox-run/route.js +3 -20
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/test-api-record/route.js +3 -20
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/workflow/publish/route.js +407 -290
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/workflows/[providerId]/route.js +209 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/components/WorkspaceAddOnsMarketplace.jsx +806 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/ApiRegistryActionCard.jsx +141 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/CeoCockpit.jsx +15 -3
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/HelperSidecar.jsx +42 -5
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/OrchestrationGraphCanvas.jsx +5 -1
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/OrchestrationNodeConfigPanel.jsx +86 -20
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/ScheduleCockpit.jsx +363 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/helper-commands.js +8 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/globals.css +322 -1
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/page.jsx +2 -2
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/settings/add-ons/add-ons-client.jsx +197 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/settings/add-ons/page.jsx +23 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/settings/settings-shell.jsx +1 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/workflows/WorkflowSurface.jsx +734 -61
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/workspace-rail.jsx +15 -10
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/env-status.js +2 -7
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/orchestration-graph-runner.js +29 -19
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/sandbox-serverless-flow.js +8 -4
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/schedule-cockpit-console.js +287 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/scheduler-orchestration.js +449 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/server-secrets.js +77 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/serverless-readiness.js +583 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-add-on-callback.js +63 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-add-on-scheduler.js +519 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-add-ons.js +957 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-app-readiness.js +212 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-config.js +607 -63
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-contract-compliance.js +168 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-data-model.js +21 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-operator-auth.js +32 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-patch-impact.js +133 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-provenance-lineage.js +214 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-stale-surfaces.js +217 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-workflow-impact.js +170 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/public/integrations/upstash/provider.png +0 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/public/integrations/upstash/qstash.png +0 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/public/integrations/upstash/redis.png +0 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/public/integrations/upstash/search.png +0 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/public/integrations/upstash/vector.png +0 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/scripts/scheduler-ingress-smoke.mjs +26 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/kit.json +6 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/skills/governed-workspace-mutation/SKILL.md +3 -1
- package/dist/index.js +3024 -4191
- package/package.json +1 -1
package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/globals.css
CHANGED
|
@@ -5125,6 +5125,160 @@ body.workspace-rail-collapsed .workspace-builder.dm-workflow-page {
|
|
|
5125
5125
|
.dm-workflow-upgrade-panel-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 14px 0; }
|
|
5126
5126
|
.dm-workflow-upgrade-panel-head .dm-api-action-card-eyebrow { margin: 0; }
|
|
5127
5127
|
.dm-workflow-upgrade-panel .dm-api-action-card { margin: 8px; box-shadow: none; }
|
|
5128
|
+
.dm-workflow-schedule-backdrop { position: fixed; inset: 0; z-index: 60; display: grid; place-items: center; padding: 24px; background: rgba(15, 23, 42, .28); }
|
|
5129
|
+
.dm-workflow-schedule-modal { width: min(560px, 100%); max-height: min(760px, calc(100vh - 48px)); display: grid; grid-template-rows: auto minmax(0, 1fr) auto; overflow: hidden; border: 1px solid #d1d5db; border-radius: 8px; background: #fff; box-shadow: 0 24px 80px rgba(15,23,42,.22); }
|
|
5130
|
+
.dm-workflow-schedule-modal header,
|
|
5131
|
+
.dm-workflow-schedule-modal footer { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 16px; border-bottom: 1px solid #edf0f3; }
|
|
5132
|
+
.dm-workflow-schedule-modal footer { justify-content: flex-end; border-top: 1px solid #edf0f3; border-bottom: 0; background: #fafafa; }
|
|
5133
|
+
.dm-workflow-schedule-modal h3 { margin: 2px 0 0; font-size: 16px; color: #111827; }
|
|
5134
|
+
.dm-workflow-schedule-body { display: grid; gap: 12px; padding: 16px; overflow: auto; }
|
|
5135
|
+
.dm-marketplace-field textarea { width: 100%; border: 1px solid #e5e7eb; border-radius: 6px; padding: 10px; background: #fff; color: #111827; font: inherit; resize: vertical; box-sizing: border-box; }
|
|
5136
|
+
.dm-marketplace-field textarea:focus { outline: none; border-color: #9ca3af; box-shadow: 0 0 0 3px rgba(17,24,39,.06); }
|
|
5137
|
+
.dm-workflow-schedule-error { margin: 0; border: 1px solid #fecaca; border-radius: 6px; background: #fef2f2; color: #991b1b; padding: 10px; font-size: 12px; line-height: 1.4; }
|
|
5138
|
+
.dm-marketplace-backdrop { position: fixed; inset: 0; z-index: 90; display: grid; place-items: center; padding: 24px; background: rgba(15,23,42,.28); }
|
|
5139
|
+
.dm-marketplace-modal { position: relative; width: min(1040px, calc(100vw - 48px)); max-height: min(820px, calc(100vh - 48px)); overflow: hidden; display: flex; flex-direction: column; border: 1px solid #e5e7eb; border-radius: 8px; background: #fff; box-shadow: 0 24px 80px rgba(15,23,42,.24); }
|
|
5140
|
+
.dm-marketplace-page { position: relative; min-height: 680px; overflow: hidden; display: flex; flex-direction: column; border: 1px solid #e5e7eb; border-radius: 8px; background: #fff; box-shadow: 0 2px 8px rgba(15,23,42,.06); }
|
|
5141
|
+
.dm-marketplace-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding: 22px 24px 18px; border-bottom: 1px solid #edf0f3; }
|
|
5142
|
+
.dm-marketplace-header h2 { margin: 2px 0 0; font-size: 24px; line-height: 1.15; color: #111827; }
|
|
5143
|
+
.dm-marketplace-breadcrumbs { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin-bottom: 18px; color: #4b5563; font-size: 12px; }
|
|
5144
|
+
.dm-marketplace-breadcrumbs svg { transform: rotate(-90deg); color: #9ca3af; }
|
|
5145
|
+
.dm-marketplace-breadcrumbs strong { color: #111827; font-weight: 500; }
|
|
5146
|
+
.dm-marketplace-breadcrumbs button { border: 0; padding: 0; background: transparent; color: #2563eb; font: inherit; cursor: pointer; }
|
|
5147
|
+
.dm-marketplace-provider-title { display: flex; align-items: center; gap: 12px; }
|
|
5148
|
+
.dm-marketplace-provider-title p { margin: 5px 0 0; color: #4b5563; font-size: 13px; }
|
|
5149
|
+
.dm-marketplace-subtitle { margin: 5px 0 0; color: #4b5563; font-size: 13px; }
|
|
5150
|
+
.dm-marketplace-provider-mark { width: 34px; height: 34px; display: inline-flex; align-items: center; justify-content: center; border-radius: 999px; background: #030712; color: #34d399; font-weight: 800; box-shadow: inset 0 0 0 2px #34d399; }
|
|
5151
|
+
.dm-marketplace-provider-actions { display: flex; align-items: center; gap: 8px; }
|
|
5152
|
+
.dm-marketplace-provider-actions a,
|
|
5153
|
+
.dm-marketplace-provider-actions button { display: inline-flex; align-items: center; gap: 6px; text-decoration: none; white-space: nowrap; }
|
|
5154
|
+
.dm-marketplace-layout { display: grid; grid-template-columns: 220px minmax(0, 1fr); min-height: 0; flex: 1; }
|
|
5155
|
+
.dm-marketplace-sidebar { padding: 16px 12px; border-right: 1px solid #edf0f3; display: grid; gap: 6px; align-content: start; background: #fafafa; }
|
|
5156
|
+
.dm-marketplace-sidebar button { display: flex; align-items: center; gap: 10px; width: 100%; border: 0; border-radius: 6px; padding: 10px 12px; background: transparent; color: #374151; font-size: 14px; font-weight: 650; cursor: pointer; text-align: left; }
|
|
5157
|
+
.dm-marketplace-sidebar button:hover,
|
|
5158
|
+
.dm-marketplace-sidebar button.is-active { background: #ecebea; color: #111827; }
|
|
5159
|
+
.dm-marketplace-setup-nav { margin-top: 14px; padding: 12px; border-top: 1px solid #e5e7eb; color: #64748b; font-size: 11px; text-transform: uppercase; letter-spacing: .08em; }
|
|
5160
|
+
.dm-marketplace-setup-nav ol { display: grid; gap: 8px; margin: 10px 0 0; padding: 0; list-style: none; text-transform: none; letter-spacing: 0; font-size: 12px; }
|
|
5161
|
+
.dm-marketplace-setup-nav li { display: flex; align-items: center; gap: 8px; color: #64748b; }
|
|
5162
|
+
.dm-marketplace-setup-nav li::before { content: ""; width: 8px; height: 8px; border: 1px solid #cbd5e1; border-radius: 999px; background: #fff; }
|
|
5163
|
+
.dm-marketplace-setup-nav li.is-active { color: #111827; font-weight: 700; }
|
|
5164
|
+
.dm-marketplace-setup-nav li.is-active::before { border-color: #111827; background: #111827; }
|
|
5165
|
+
.dm-marketplace-content { min-width: 0; overflow-y: auto; padding: 18px 22px 24px; display: grid; gap: 14px; align-content: start; }
|
|
5166
|
+
.dm-marketplace-error { border: 1px solid #fecaca; border-radius: 7px; padding: 10px 12px; background: #fef2f2; color: #991b1b; font-size: 13px; line-height: 1.35; }
|
|
5167
|
+
.dm-marketplace-search-row { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: 10px; align-items: center; }
|
|
5168
|
+
.dm-marketplace-search { min-width: 0; display: flex; align-items: center; gap: 8px; height: 38px; padding: 0 12px; border: 1px solid #bfdbfe; border-radius: 7px; color: #111827; box-shadow: 0 0 0 2px rgba(59,130,246,.12); }
|
|
5169
|
+
.dm-marketplace-filter { height: 38px; display: inline-flex; align-items: center; gap: 8px; border: 1px solid #e5e7eb; border-radius: 7px; padding: 0 12px; background: #fff; color: #6b7280; cursor: pointer; }
|
|
5170
|
+
.dm-marketplace-install-card { border: 1px solid #e5e7eb; border-radius: 8px; background: #fff; box-shadow: 0 2px 8px rgba(15,23,42,.06); overflow: hidden; }
|
|
5171
|
+
.dm-marketplace-provider-layout { display: grid; grid-template-columns: minmax(0, 1fr) 280px; gap: 28px; align-items: start; }
|
|
5172
|
+
.dm-marketplace-provider-main { display: grid; gap: 24px; }
|
|
5173
|
+
.dm-marketplace-details { display: grid; gap: 0; }
|
|
5174
|
+
.dm-marketplace-details h3,
|
|
5175
|
+
.dm-marketplace-overview h3 { margin: 0 0 10px; font-size: 16px; color: #111827; }
|
|
5176
|
+
.dm-marketplace-details div { min-height: 42px; display: grid; grid-template-columns: minmax(0, .85fr) minmax(0, 1fr); gap: 12px; align-items: center; border-bottom: 1px solid #e5e7eb; font-size: 12px; }
|
|
5177
|
+
.dm-marketplace-details span { color: #111827; }
|
|
5178
|
+
.dm-marketplace-details strong { color: #111827; font-weight: 500; text-align: right; }
|
|
5179
|
+
.dm-marketplace-details a { display: inline-flex; justify-content: flex-end; align-items: center; gap: 4px; color: #2563eb; text-decoration: none; text-align: right; }
|
|
5180
|
+
.dm-marketplace-overview { display: grid; gap: 6px; }
|
|
5181
|
+
.dm-marketplace-overview p { margin: 0; color: #4b5563; font-size: 13px; line-height: 1.5; }
|
|
5182
|
+
.dm-marketplace-products { display: grid; gap: 10px; }
|
|
5183
|
+
.dm-marketplace-products h3 { margin: 8px 0 0; font-size: 16px; color: #111827; }
|
|
5184
|
+
.dm-marketplace-product-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 14px; }
|
|
5185
|
+
.dm-marketplace-provider-grid { display: grid; grid-template-columns: minmax(0, 520px); gap: 12px; }
|
|
5186
|
+
.dm-marketplace-provider-card { min-height: 124px; display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 14px; align-items: center; border: 1px solid #e5e7eb; border-radius: 8px; background: #fff; padding: 18px; cursor: pointer; text-align: left; }
|
|
5187
|
+
.dm-marketplace-provider-card:hover { border-color: #cbd5e1; box-shadow: 0 8px 24px rgba(15,23,42,.08); }
|
|
5188
|
+
.dm-marketplace-provider-card strong { display: block; color: #111827; font-size: 15px; }
|
|
5189
|
+
.dm-marketplace-provider-card p { margin: 4px 0 0; color: #4b5563; font-size: 13px; }
|
|
5190
|
+
.dm-marketplace-provider-card small { display: block; margin-top: 12px; color: #64748b; font-size: 12px; }
|
|
5191
|
+
.dm-marketplace-product-card { min-height: 116px; display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 12px; align-items: start; border: 1px solid #e5e7eb; border-radius: 8px; background: #fff; padding: 14px; }
|
|
5192
|
+
.dm-marketplace-product-card.is-muted { background: #fcfcfc; }
|
|
5193
|
+
.dm-marketplace-product-card strong { display: block; font-size: 13px; color: #111827; }
|
|
5194
|
+
.dm-marketplace-product-card p { margin: 3px 0 0; font-size: 12px; color: #4b5563; }
|
|
5195
|
+
.dm-marketplace-product-card small { display: block; margin-top: 22px; color: #4b5563; font-size: 12px; }
|
|
5196
|
+
.dm-marketplace-card-actions { display: grid; justify-items: end; gap: 8px; }
|
|
5197
|
+
.dm-marketplace-gear { opacity: 0; transform: translateY(-2px); transition: opacity .14s ease, transform .14s ease; }
|
|
5198
|
+
.dm-marketplace-product-card:hover .dm-marketplace-gear,
|
|
5199
|
+
.dm-marketplace-gear:focus-visible { opacity: 1; transform: translateY(0); }
|
|
5200
|
+
.dm-marketplace-product-head { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 12px; align-items: center; padding: 16px; border-bottom: 1px solid #edf0f3; }
|
|
5201
|
+
.dm-marketplace-product-head h3 { margin: 0; font-size: 15px; color: #111827; }
|
|
5202
|
+
.dm-marketplace-product-head p { margin: 3px 0 0; font-size: 12px; line-height: 1.35; color: #4b5563; }
|
|
5203
|
+
.dm-marketplace-product-icon { width: 34px; height: 34px; display: inline-flex; align-items: center; justify-content: center; border-radius: 8px; overflow: hidden; font-weight: 800; color: #fff; }
|
|
5204
|
+
.dm-marketplace-product-icon img { width: 100%; height: 100%; object-fit: cover; display: block; }
|
|
5205
|
+
.dm-marketplace-product-icon.is-upstash { background: #7c3aed; }
|
|
5206
|
+
.dm-marketplace-product-icon.is-provider { border-radius: 999px; background: #030712; }
|
|
5207
|
+
.dm-marketplace-product-icon.is-custom { background: #111827; }
|
|
5208
|
+
.dm-marketplace-product-icon.is-redis { background: #dc2626; }
|
|
5209
|
+
.dm-marketplace-product-icon.is-search { background: #eab308; }
|
|
5210
|
+
.dm-marketplace-product-icon.is-vector { background: #ea580c; }
|
|
5211
|
+
.dm-marketplace-config { padding: 16px; display: grid; gap: 12px; }
|
|
5212
|
+
.dm-marketplace-section-title { margin: 0; display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 700; color: #111827; }
|
|
5213
|
+
.dm-marketplace-field { display: grid; gap: 7px; font-size: 12px; color: #4b5563; }
|
|
5214
|
+
.dm-marketplace-field select,
|
|
5215
|
+
.dm-marketplace-field input { height: 38px; width: 100%; border: 1px solid #e5e7eb; border-radius: 6px; padding: 0 10px; background: #fff; color: #111827; font: inherit; box-sizing: border-box; }
|
|
5216
|
+
.dm-marketplace-field input:focus,
|
|
5217
|
+
.dm-marketplace-field select:focus { outline: none; border-color: #9ca3af; box-shadow: 0 0 0 3px rgba(17,24,39,.06); }
|
|
5218
|
+
.dm-marketplace-credential-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
|
|
5219
|
+
@media (max-width: 760px) { .dm-marketplace-credential-grid { grid-template-columns: 1fr; } }
|
|
5220
|
+
.dm-marketplace-install-choice { display: grid; gap: 10px; border: 1px solid #e5e7eb; border-radius: 7px; padding: 12px; background: #fff; }
|
|
5221
|
+
.dm-marketplace-install-choice strong { display: block; color: #111827; font-size: 13px; }
|
|
5222
|
+
.dm-marketplace-install-choice span { display: block; margin-top: 3px; color: #64748b; font-size: 12px; line-height: 1.4; }
|
|
5223
|
+
.dm-marketplace-toggle { display: inline-flex; align-items: center; gap: 8px; font-size: 12px; color: #4b5563; }
|
|
5224
|
+
.dm-marketplace-toggle input { width: 34px; height: 20px; }
|
|
5225
|
+
.dm-marketplace-resource-divider { display: flex; align-items: center; gap: 10px; color: #64748b; font-size: 12px; font-weight: 650; }
|
|
5226
|
+
.dm-marketplace-resource-divider::before,
|
|
5227
|
+
.dm-marketplace-resource-divider::after { content: ""; height: 1px; flex: 1 1 auto; background: #e5e7eb; }
|
|
5228
|
+
.dm-marketplace-resource-divider span { white-space: nowrap; }
|
|
5229
|
+
.dm-marketplace-plan-list { display: grid; gap: 8px; padding-top: 6px; }
|
|
5230
|
+
.dm-marketplace-plan { min-height: 54px; display: flex; align-items: center; justify-content: space-between; gap: 10px; border: 1px solid #e5e7eb; border-radius: 6px; background: #fff; padding: 10px; color: #374151; cursor: pointer; text-align: left; }
|
|
5231
|
+
.dm-marketplace-plan.is-selected { border-color: #c7d2fe; background: #f8fafc; color: #111827; }
|
|
5232
|
+
.dm-marketplace-plan:disabled { color: #9ca3af; cursor: not-allowed; }
|
|
5233
|
+
.dm-marketplace-plan b { color: #111827; }
|
|
5234
|
+
.dm-marketplace-radio { width: 13px; height: 13px; flex: 0 0 auto; border: 1px solid #9ca3af; border-radius: 999px; }
|
|
5235
|
+
.dm-marketplace-env { display: flex; align-items: center; justify-content: space-between; gap: 10px; border: 1px solid #e5e7eb; border-radius: 6px; background: #f8fafc; color: #334155; padding: 10px; font-size: 12px; }
|
|
5236
|
+
.dm-marketplace-env.is-ready { border-color: #bbf7d0; background: #f0fdf4; color: #166534; }
|
|
5237
|
+
.dm-marketplace-env code { color: inherit; word-break: break-all; }
|
|
5238
|
+
.dm-marketplace-config-summary { display: grid; gap: 6px; border: 1px solid #e5e7eb; border-radius: 7px; padding: 10px; background: #fafafa; }
|
|
5239
|
+
.dm-marketplace-config-summary div { display: grid; grid-template-columns: 92px minmax(0, 1fr); gap: 8px; align-items: start; font-size: 12px; }
|
|
5240
|
+
.dm-marketplace-config-summary span { color: #64748b; }
|
|
5241
|
+
.dm-marketplace-config-summary code { color: #111827; white-space: normal; word-break: break-word; }
|
|
5242
|
+
.dm-marketplace-install-drawer { position: absolute; inset: 0 0 0 auto; z-index: 2; width: min(430px, 100%); padding: 14px; background: rgba(255,255,255,.84); box-shadow: -16px 0 50px rgba(15,23,42,.16); backdrop-filter: blur(2px); overflow-y: auto; }
|
|
5243
|
+
.dm-marketplace-modal .dm-marketplace-install-drawer { position: absolute; }
|
|
5244
|
+
.dm-marketplace-drawer-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 14px 16px; border-bottom: 1px solid #edf0f3; }
|
|
5245
|
+
.dm-marketplace-drawer-head h3 { margin: 0; font-size: 16px; color: #111827; }
|
|
5246
|
+
.dm-marketplace-provision-steps { display: grid; gap: 10px; padding: 12px 16px; border-top: 1px solid #edf0f3; }
|
|
5247
|
+
.dm-marketplace-provision-steps div { border: 1px solid #e5e7eb; border-radius: 7px; padding: 12px; color: #9ca3af; font-size: 13px; font-weight: 650; }
|
|
5248
|
+
.dm-marketplace-provision-steps div.is-active { color: #111827; border-color: #d1d5db; background: #fafafa; }
|
|
5249
|
+
.dm-marketplace-provision-steps div.is-complete { color: #374151; border-color: #d1d5db; background: #f8fafc; }
|
|
5250
|
+
.dm-marketplace-provision-steps .dm-marketplace-step-action-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 8px 8px 8px 12px; }
|
|
5251
|
+
.dm-marketplace-step-action-row .dm-btn-primary-sm { min-height: 34px; white-space: nowrap; }
|
|
5252
|
+
.dm-marketplace-adapters { padding: 16px; display: grid; gap: 8px; }
|
|
5253
|
+
.dm-marketplace-adapter { display: grid; grid-template-columns: minmax(0, .8fr) minmax(0, 1fr); gap: 10px; align-items: center; border: 1px solid #e5e7eb; border-radius: 6px; padding: 10px; background: #fff; }
|
|
5254
|
+
.dm-marketplace-adapter.is-ready { border-color: #bbf7d0; background: #f8fffb; }
|
|
5255
|
+
.dm-marketplace-adapter div { display: grid; gap: 2px; }
|
|
5256
|
+
.dm-marketplace-adapter strong { font-size: 13px; color: #111827; }
|
|
5257
|
+
.dm-marketplace-adapter span,
|
|
5258
|
+
.dm-marketplace-adapter code { font-size: 11px; color: #64748b; }
|
|
5259
|
+
.dm-marketplace-adapter code { text-align: right; white-space: normal; word-break: break-word; }
|
|
5260
|
+
.dm-marketplace-actions { display: flex; justify-content: flex-end; gap: 8px; padding: 14px 16px; border-top: 1px solid #edf0f3; background: #fafafa; }
|
|
5261
|
+
.dm-marketplace-console-link { margin-right: auto; display: inline-flex; align-items: center; gap: 6px; text-decoration: none; }
|
|
5262
|
+
.dm-marketplace-create-new-btn { justify-content: center; }
|
|
5263
|
+
.dm-marketplace-primary-link { text-decoration: none; justify-content: center; }
|
|
5264
|
+
@media (min-width: 761px) {
|
|
5265
|
+
.dm-marketplace-page { min-height: min(760px, calc(100vh - 112px)); height: min(920px, calc(100vh - 112px)); }
|
|
5266
|
+
}
|
|
5267
|
+
@media (max-width: 760px) {
|
|
5268
|
+
.dm-marketplace-backdrop { padding: 10px; align-items: stretch; }
|
|
5269
|
+
.dm-marketplace-modal { width: 100%; max-height: calc(100vh - 20px); }
|
|
5270
|
+
.dm-marketplace-layout { grid-template-columns: 1fr; }
|
|
5271
|
+
.dm-marketplace-sidebar { grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); border-right: 0; border-bottom: 1px solid #edf0f3; }
|
|
5272
|
+
.dm-marketplace-setup-nav { grid-column: 1 / -1; }
|
|
5273
|
+
.dm-marketplace-provider-actions { flex-wrap: wrap; justify-content: flex-start; }
|
|
5274
|
+
.dm-marketplace-provider-layout { grid-template-columns: 1fr; }
|
|
5275
|
+
.dm-marketplace-search-row { grid-template-columns: 1fr; }
|
|
5276
|
+
.dm-marketplace-product-grid { grid-template-columns: 1fr; }
|
|
5277
|
+
.dm-marketplace-adapter,
|
|
5278
|
+
.dm-marketplace-product-head { grid-template-columns: auto minmax(0, 1fr); }
|
|
5279
|
+
.dm-marketplace-product-head .dm-db-status { grid-column: 1 / -1; justify-self: start; }
|
|
5280
|
+
.dm-marketplace-adapter code { text-align: left; }
|
|
5281
|
+
}
|
|
5128
5282
|
|
|
5129
5283
|
.dm-api-review-banner {
|
|
5130
5284
|
display: grid;
|
|
@@ -5201,7 +5355,31 @@ body.workspace-rail-collapsed .workspace-builder.dm-workflow-page {
|
|
|
5201
5355
|
.dm-orchestration-config__fieldmap,
|
|
5202
5356
|
.dm-orchestration-config__payload { display: grid; gap: 8px; }
|
|
5203
5357
|
.dm-orchestration-config__fieldmap-row,
|
|
5204
|
-
.dm-orchestration-config__payload-row { display: grid; grid-template-columns:
|
|
5358
|
+
.dm-orchestration-config__payload-row { display: grid; grid-template-columns: minmax(112px, .72fr) minmax(0, 1fr) auto; gap: 6px; align-items: center; min-width: 0; }
|
|
5359
|
+
.dm-orchestration-config__payload-row > input {
|
|
5360
|
+
min-width: 0;
|
|
5361
|
+
width: 100%;
|
|
5362
|
+
height: 34px;
|
|
5363
|
+
border: 1px solid #cbd5e1;
|
|
5364
|
+
border-radius: 6px;
|
|
5365
|
+
background: #fff;
|
|
5366
|
+
color: #111827;
|
|
5367
|
+
font: inherit;
|
|
5368
|
+
font-size: 12px;
|
|
5369
|
+
padding: 7px 9px;
|
|
5370
|
+
box-sizing: border-box;
|
|
5371
|
+
}
|
|
5372
|
+
.dm-orchestration-config__payload-row > input:focus {
|
|
5373
|
+
outline: none;
|
|
5374
|
+
border-color: #64748b;
|
|
5375
|
+
box-shadow: 0 0 0 3px rgba(100, 116, 139, .12);
|
|
5376
|
+
}
|
|
5377
|
+
.dm-orchestration-config__payload-row > .dm-btn-ghost {
|
|
5378
|
+
height: 34px;
|
|
5379
|
+
min-width: 70px;
|
|
5380
|
+
justify-content: center;
|
|
5381
|
+
white-space: nowrap;
|
|
5382
|
+
}
|
|
5205
5383
|
.dm-orchestration-config__advanced-json summary { cursor: pointer; font-size: 11px; font-weight: 650; color: #374151; }
|
|
5206
5384
|
.dm-orchestration-preview { margin: 0; padding: 10px; background: #f9fafb; border: 1px solid #e5e7eb; border-radius: 5px; font-size: 10px; overflow: auto; max-height: 160px; white-space: pre-wrap; word-break: break-word; }
|
|
5207
5385
|
.dm-orchestration-preview > span { display: block; font-size: 10px; font-weight: 700; text-transform: uppercase; color: #6b7280; margin-bottom: 6px; }
|
|
@@ -5808,6 +5986,24 @@ body.workspace-rail-collapsed .workspace-builder.dm-workflow-page {
|
|
|
5808
5986
|
border-color: #64748b;
|
|
5809
5987
|
box-shadow: 0 0 0 3px rgba(100, 116, 139, .12);
|
|
5810
5988
|
}
|
|
5989
|
+
|
|
5990
|
+
.dm-workflow-orchestration .dm-input-mode-select .dm-select-option.selected {
|
|
5991
|
+
background: #f5f5f5;
|
|
5992
|
+
color: #111827;
|
|
5993
|
+
}
|
|
5994
|
+
|
|
5995
|
+
.dm-workflow-orchestration .dm-input-mode-select {
|
|
5996
|
+
z-index: 130;
|
|
5997
|
+
}
|
|
5998
|
+
|
|
5999
|
+
.dm-workflow-orchestration .dm-input-mode-select .dm-select-option {
|
|
6000
|
+
grid-template-columns: 18px minmax(0, 1fr);
|
|
6001
|
+
align-items: center;
|
|
6002
|
+
}
|
|
6003
|
+
|
|
6004
|
+
.dm-workflow-orchestration .dm-input-mode-select .dm-select-option svg {
|
|
6005
|
+
color: #64748b;
|
|
6006
|
+
}
|
|
5811
6007
|
.dm-workflow-orchestration .dm-orchestration-config__field input:disabled,
|
|
5812
6008
|
.dm-workflow-orchestration .dm-orchestration-config__field textarea:disabled,
|
|
5813
6009
|
.dm-workflow-orchestration .dm-orchestration-config__field select:disabled {
|
|
@@ -9447,3 +9643,128 @@ body.workspace-rail-collapsed .workspace-builder.workspace-lens-page,
|
|
|
9447
9643
|
.dm-db-empty-state strong { font-size: 15px; color: var(--dm-ink); font-weight: 650; }
|
|
9448
9644
|
.dm-db-empty-state span { font-size: 12.5px; color: var(--dm-muted); max-width: 360px; }
|
|
9449
9645
|
.dm-db-empty-actions { display: inline-flex; gap: 8px; margin-top: 8px; }
|
|
9646
|
+
|
|
9647
|
+
/* Input-node serverless schedule fields — shown below the config panel only
|
|
9648
|
+
when Input mode = serverless schedule. Inherits the sidecar field styles. */
|
|
9649
|
+
.dm-trigger-schedule-config {
|
|
9650
|
+
display: flex;
|
|
9651
|
+
flex-direction: column;
|
|
9652
|
+
gap: 10px;
|
|
9653
|
+
margin-top: 12px;
|
|
9654
|
+
padding: 0;
|
|
9655
|
+
border: 0;
|
|
9656
|
+
background: transparent;
|
|
9657
|
+
min-height: 0;
|
|
9658
|
+
}
|
|
9659
|
+
.dm-workflow-schedule-state {
|
|
9660
|
+
display: grid;
|
|
9661
|
+
gap: 5px;
|
|
9662
|
+
margin: 0;
|
|
9663
|
+
padding: 0;
|
|
9664
|
+
}
|
|
9665
|
+
.dm-workflow-schedule-state div {
|
|
9666
|
+
display: grid;
|
|
9667
|
+
grid-template-columns: 86px minmax(0, 1fr);
|
|
9668
|
+
gap: 8px;
|
|
9669
|
+
align-items: baseline;
|
|
9670
|
+
min-width: 0;
|
|
9671
|
+
}
|
|
9672
|
+
.dm-workflow-schedule-state dt {
|
|
9673
|
+
color: #64748b;
|
|
9674
|
+
font-size: 10px;
|
|
9675
|
+
font-weight: 700;
|
|
9676
|
+
line-height: 1.25;
|
|
9677
|
+
margin: 0;
|
|
9678
|
+
text-transform: uppercase;
|
|
9679
|
+
}
|
|
9680
|
+
.dm-workflow-schedule-state dd {
|
|
9681
|
+
min-width: 0;
|
|
9682
|
+
margin: 0;
|
|
9683
|
+
color: #111827;
|
|
9684
|
+
font-size: 12px;
|
|
9685
|
+
line-height: 1.35;
|
|
9686
|
+
overflow-wrap: anywhere;
|
|
9687
|
+
}
|
|
9688
|
+
.dm-workflow-schedule-last-run {
|
|
9689
|
+
display: flex;
|
|
9690
|
+
align-items: center;
|
|
9691
|
+
justify-content: space-between;
|
|
9692
|
+
gap: 10px;
|
|
9693
|
+
min-height: 30px;
|
|
9694
|
+
padding: 0;
|
|
9695
|
+
color: #475569;
|
|
9696
|
+
}
|
|
9697
|
+
.dm-workflow-schedule-last-run span { font-size: 11px; font-weight: 650; color: #475569; }
|
|
9698
|
+
.dm-workflow-schedule-last-run strong { color: #111827; font-size: 12px; font-weight: 650; }
|
|
9699
|
+
.dm-workflow-schedule-submit {
|
|
9700
|
+
width: 100%;
|
|
9701
|
+
justify-content: center;
|
|
9702
|
+
}
|
|
9703
|
+
.dm-workflow-schedule-actions {
|
|
9704
|
+
display: grid;
|
|
9705
|
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
9706
|
+
gap: 8px;
|
|
9707
|
+
}
|
|
9708
|
+
.dm-workflow-schedule-actions .dm-btn-outline {
|
|
9709
|
+
justify-content: center;
|
|
9710
|
+
min-width: 0;
|
|
9711
|
+
}
|
|
9712
|
+
.dm-btn-outline.is-danger {
|
|
9713
|
+
border-color: #fecaca;
|
|
9714
|
+
color: #991b1b;
|
|
9715
|
+
}
|
|
9716
|
+
.dm-btn-outline.is-danger:hover:not(:disabled) {
|
|
9717
|
+
border-color: #fca5a5;
|
|
9718
|
+
background: #fef2f2;
|
|
9719
|
+
}
|
|
9720
|
+
|
|
9721
|
+
.dm-workflow-orchestration .dm-orchestration-config__field select {
|
|
9722
|
+
border-color: #cbd5e1;
|
|
9723
|
+
background: #fff;
|
|
9724
|
+
color: #111827;
|
|
9725
|
+
box-shadow: none;
|
|
9726
|
+
}
|
|
9727
|
+
|
|
9728
|
+
.dm-workflow-orchestration .dm-orchestration-config__field select:focus {
|
|
9729
|
+
outline: none;
|
|
9730
|
+
border-color: #64748b;
|
|
9731
|
+
box-shadow: 0 0 0 3px rgba(100, 116, 139, .12);
|
|
9732
|
+
}
|
|
9733
|
+
|
|
9734
|
+
/* ------------------------------------------------------------------ *
|
|
9735
|
+
* Serverless-readiness flagging — ultrathin orange only. *
|
|
9736
|
+
* The color IS the guidance: a flagged node gets an ultrathin orange *
|
|
9737
|
+
* border (nothing else added), and ONLY the exact main field(s) / *
|
|
9738
|
+
* delta-tag shield(s) the readiness scan mapped get a light-orange *
|
|
9739
|
+
* fill. No badges, no copy — handled atomically under the hood. *
|
|
9740
|
+
* ------------------------------------------------------------------ */
|
|
9741
|
+
.dm-orchestration-node--readiness { border-color: #f59e0b; box-shadow: 0 0 0 1px rgba(245, 158, 11, 0.55); }
|
|
9742
|
+
.dm-orchestration-node--readiness.is-warning { border-color: #fbbf24; box-shadow: 0 0 0 1px rgba(251, 191, 36, 0.42); }
|
|
9743
|
+
.dm-orchestration-node--readiness:hover { border-color: #f59e0b; }
|
|
9744
|
+
.dm-orchestration-node--readiness.dm-orchestration-node--selected { border-color: #f59e0b; box-shadow: 0 0 0 1px #f59e0b, 0 2px 8px rgba(245, 158, 11, 0.16); }
|
|
9745
|
+
|
|
9746
|
+
.dm-orchestration-config__field.dm-field--readiness input,
|
|
9747
|
+
.dm-orchestration-config__field.dm-field--readiness textarea,
|
|
9748
|
+
.dm-orchestration-config__field.dm-field--readiness select { border-color: #f59e0b; background: #fffbeb; }
|
|
9749
|
+
.dm-orchestration-config__field.dm-field--readiness.is-warning input,
|
|
9750
|
+
.dm-orchestration-config__field.dm-field--readiness.is-warning textarea,
|
|
9751
|
+
.dm-orchestration-config__field.dm-field--readiness.is-warning select { border-color: #fcd34d; background: #fffdf5; }
|
|
9752
|
+
|
|
9753
|
+
.dm-orchestration-config__payload.dm-field--readiness { border-radius: 6px; padding: 6px; background: #fffbeb; box-shadow: inset 0 0 0 1px rgba(245, 158, 11, 0.4); }
|
|
9754
|
+
.dm-orchestration-config__payload.dm-field--readiness.is-warning { background: #fffdf5; box-shadow: inset 0 0 0 1px rgba(252, 211, 77, 0.45); }
|
|
9755
|
+
|
|
9756
|
+
/* ------------------------------------------------------------------ *
|
|
9757
|
+
* Schedule cockpit (/schedule) — sidecar operations surface. Reuses *
|
|
9758
|
+
* the swarm/CEO card grammar; only the search/filter/tag chrome is new.*
|
|
9759
|
+
* ------------------------------------------------------------------ */
|
|
9760
|
+
.dm-schedule-search { display: flex; align-items: center; gap: 6px; padding: 6px 9px; border: 1px solid #e5e7eb; border-radius: 6px; background: #fff; color: #6b7280; margin-bottom: 8px; }
|
|
9761
|
+
.dm-schedule-search input { flex: 1; min-width: 0; border: 0; outline: none; font-size: 12px; color: #111827; background: transparent; }
|
|
9762
|
+
.dm-schedule-filters { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
|
|
9763
|
+
.dm-schedule-filter { border: 1px solid #e5e7eb; border-radius: 999px; padding: 3px 10px; font-size: 11px; font-weight: 600; color: #475569; background: #fff; cursor: pointer; }
|
|
9764
|
+
.dm-schedule-filter:hover { border-color: #cbd5e1; }
|
|
9765
|
+
.dm-schedule-filter.is-active { border-color: #2563eb; color: #1d4ed8; background: #eff6ff; }
|
|
9766
|
+
.dm-schedule-tags { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
|
|
9767
|
+
.dm-schedule-tag { font-size: 10px; font-weight: 600; line-height: 1.4; padding: 1px 7px; border-radius: 999px; border: 1px solid #e5e7eb; color: #475569; background: #f8fafc; }
|
|
9768
|
+
.dm-schedule-tag[data-tag-tone="alert"] { border-color: #fde68a; color: #92400e; background: #fffbeb; }
|
|
9769
|
+
.dm-schedule-tag[data-tag-tone="ok"] { border-color: #bbf7d0; color: #166534; background: #f0fdf4; }
|
|
9770
|
+
.dm-schedule-card-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { Suspense } from "react";
|
|
2
|
-
import workspaceConfig from "../growthub.config.json";
|
|
3
2
|
import { readAdapterConfig } from "@/lib/adapters/env";
|
|
4
3
|
import { describeIntegrationAdapter, listGovernedWorkspaceIntegrations } from "@/lib/adapters/integrations";
|
|
5
4
|
import { groupIntegrationsByLane } from "@/lib/domain/integrations";
|
|
6
|
-
import { describePersistenceMode, readWorkspaceSourceRecords } from "@/lib/workspace-config";
|
|
5
|
+
import { describePersistenceMode, readWorkspaceConfig, readWorkspaceSourceRecords } from "@/lib/workspace-config";
|
|
7
6
|
import WorkspaceBuilder from "./workspace-builder.jsx";
|
|
8
7
|
|
|
9
8
|
async function Home() {
|
|
@@ -11,6 +10,7 @@ async function Home() {
|
|
|
11
10
|
const integrationAdapter = describeIntegrationAdapter();
|
|
12
11
|
const integrations = await listGovernedWorkspaceIntegrations();
|
|
13
12
|
const persistence = describePersistenceMode();
|
|
13
|
+
const workspaceConfig = await readWorkspaceConfig();
|
|
14
14
|
let initialSourceRecords = {};
|
|
15
15
|
try {
|
|
16
16
|
initialSourceRecords = (await readWorkspaceSourceRecords()) || {};
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import { useRouter } from "next/navigation";
|
|
5
|
+
import { WorkspaceAddOnsMarketplace } from "../../components/WorkspaceAddOnsMarketplace.jsx";
|
|
6
|
+
|
|
7
|
+
function AddOnsSettingsClient({ initialWorkspaceConfig, envSignals }) {
|
|
8
|
+
const router = useRouter();
|
|
9
|
+
const [workspaceConfig, setWorkspaceConfig] = useState(initialWorkspaceConfig || {});
|
|
10
|
+
const [activeAction, setActiveAction] = useState("");
|
|
11
|
+
const [errorMessage, setErrorMessage] = useState("");
|
|
12
|
+
const [pendingProviderId, setPendingProviderId] = useState("");
|
|
13
|
+
const [setupMessage, setSetupMessage] = useState("");
|
|
14
|
+
const [providerSetupWindow, setProviderSetupWindow] = useState(null);
|
|
15
|
+
const normalizedEnvSignals = {
|
|
16
|
+
configuredEnvRefs: envSignals?.configuredEnvRefs || [],
|
|
17
|
+
persistenceAdapters: envSignals?.persistenceAdapters || [],
|
|
18
|
+
providerProductReadiness: envSignals?.providerProductReadiness || {},
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
async function connectProvider(setup = {}) {
|
|
22
|
+
const providerId = setup.providerId;
|
|
23
|
+
if (!providerId) return;
|
|
24
|
+
if (!setup.openedExternally) setActiveAction("connect");
|
|
25
|
+
setErrorMessage("");
|
|
26
|
+
setPendingProviderId(providerId);
|
|
27
|
+
setSetupMessage("Provider account setup is open. Return here after the account page is ready; the workspace will sync automatically.");
|
|
28
|
+
try {
|
|
29
|
+
const response = await fetch(`/api/workspace/add-ons/providers/${encodeURIComponent(providerId)}/connect`, {
|
|
30
|
+
method: "POST",
|
|
31
|
+
headers: { "content-type": "application/json" },
|
|
32
|
+
body: JSON.stringify(setup),
|
|
33
|
+
});
|
|
34
|
+
const payload = await response.json();
|
|
35
|
+
if (!response.ok) {
|
|
36
|
+
setErrorMessage(payload?.error || "Provider setup state could not be recorded.");
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (payload.workspaceConfig) {
|
|
40
|
+
setWorkspaceConfig(payload.workspaceConfig);
|
|
41
|
+
}
|
|
42
|
+
if (payload.accountState === "setup-opened") {
|
|
43
|
+
setPendingProviderId(providerId);
|
|
44
|
+
setSetupMessage("Provider account setup is open. Return here after the account page is ready; the workspace will sync automatically.");
|
|
45
|
+
} else {
|
|
46
|
+
setPendingProviderId("");
|
|
47
|
+
setSetupMessage("");
|
|
48
|
+
}
|
|
49
|
+
if (!setup.openedExternally && payload.connectUrl) {
|
|
50
|
+
const setupWindow = window.open(payload.connectUrl, `${providerId}-provider-setup`, "popup,width=1160,height=820");
|
|
51
|
+
setProviderSetupWindow(setupWindow || null);
|
|
52
|
+
}
|
|
53
|
+
} catch (error) {
|
|
54
|
+
console.warn(error);
|
|
55
|
+
setErrorMessage(error?.message || "Provider setup failed.");
|
|
56
|
+
} finally {
|
|
57
|
+
if (!setup.openedExternally) setActiveAction("");
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async function syncProvider(setup = {}, options = {}) {
|
|
62
|
+
const providerId = setup.providerId;
|
|
63
|
+
if (!providerId) return;
|
|
64
|
+
setActiveAction("sync-provider");
|
|
65
|
+
setErrorMessage("");
|
|
66
|
+
try {
|
|
67
|
+
const response = await fetch(`/api/workspace/add-ons/providers/${encodeURIComponent(providerId)}/sync`, {
|
|
68
|
+
method: "POST",
|
|
69
|
+
headers: { "content-type": "application/json" },
|
|
70
|
+
body: JSON.stringify(setup),
|
|
71
|
+
});
|
|
72
|
+
const payload = await response.json();
|
|
73
|
+
if (!response.ok) {
|
|
74
|
+
if (!options.silent) {
|
|
75
|
+
setErrorMessage(payload?.error || payload?.sync?.summary || "Provider sync failed.");
|
|
76
|
+
}
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
setWorkspaceConfig(payload.workspaceConfig || workspaceConfig);
|
|
80
|
+
setPendingProviderId("");
|
|
81
|
+
setSetupMessage("");
|
|
82
|
+
setProviderSetupWindow(null);
|
|
83
|
+
} catch (error) {
|
|
84
|
+
console.warn(error);
|
|
85
|
+
if (!options.silent) {
|
|
86
|
+
setErrorMessage(error?.message || "Provider sync failed.");
|
|
87
|
+
}
|
|
88
|
+
} finally {
|
|
89
|
+
setActiveAction("");
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async function saveProviderCredentials(setup = {}) {
|
|
94
|
+
const providerId = setup.providerId;
|
|
95
|
+
if (!providerId) return;
|
|
96
|
+
setActiveAction("save-provider");
|
|
97
|
+
setErrorMessage("");
|
|
98
|
+
try {
|
|
99
|
+
const response = await fetch(`/api/workspace/add-ons/providers/${encodeURIComponent(providerId)}/credentials`, {
|
|
100
|
+
method: "POST",
|
|
101
|
+
headers: { "content-type": "application/json" },
|
|
102
|
+
body: JSON.stringify({ credentials: setup.credentials || {} }),
|
|
103
|
+
});
|
|
104
|
+
const payload = await response.json();
|
|
105
|
+
if (!response.ok) {
|
|
106
|
+
setErrorMessage(payload?.error || "Provider account could not be verified.");
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
setWorkspaceConfig(payload.workspaceConfig || workspaceConfig);
|
|
110
|
+
setPendingProviderId("");
|
|
111
|
+
setSetupMessage("");
|
|
112
|
+
setProviderSetupWindow(null);
|
|
113
|
+
} catch (error) {
|
|
114
|
+
console.warn(error);
|
|
115
|
+
setErrorMessage(error?.message || "Provider account setup failed.");
|
|
116
|
+
} finally {
|
|
117
|
+
setActiveAction("");
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
async function syncProduct({ providerId, productId, region, plan, selectedResourceId, selectedResourceLabel, selectedResourceSource }) {
|
|
122
|
+
if (!providerId || !productId) return;
|
|
123
|
+
setActiveAction("sync-product");
|
|
124
|
+
setErrorMessage("");
|
|
125
|
+
try {
|
|
126
|
+
const response = await fetch(`/api/workspace/add-ons/providers/${encodeURIComponent(providerId)}/products/sync`, {
|
|
127
|
+
method: "POST",
|
|
128
|
+
headers: { "content-type": "application/json" },
|
|
129
|
+
body: JSON.stringify({ productId, region, plan, selectedResourceId, selectedResourceLabel, selectedResourceSource }),
|
|
130
|
+
});
|
|
131
|
+
const payload = await response.json();
|
|
132
|
+
if (!response.ok) {
|
|
133
|
+
const missing = Array.isArray(payload?.missingEnv) && payload.missingEnv.length
|
|
134
|
+
? ` Missing env: ${payload.missingEnv.join(", ")}.`
|
|
135
|
+
: "";
|
|
136
|
+
setErrorMessage(`${payload?.error || payload?.sync?.summary || "Product sync failed."}${missing}`);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
setWorkspaceConfig(payload.workspaceConfig || workspaceConfig);
|
|
140
|
+
} catch (error) {
|
|
141
|
+
console.warn(error);
|
|
142
|
+
setErrorMessage(error?.message || "Product sync failed.");
|
|
143
|
+
} finally {
|
|
144
|
+
setActiveAction("");
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
useEffect(() => {
|
|
149
|
+
if (!pendingProviderId) return undefined;
|
|
150
|
+
let didSync = false;
|
|
151
|
+
const trySync = () => {
|
|
152
|
+
if (didSync || document.visibilityState === "hidden") return;
|
|
153
|
+
didSync = true;
|
|
154
|
+
syncProvider({ providerId: pendingProviderId });
|
|
155
|
+
};
|
|
156
|
+
const onFocus = () => trySync();
|
|
157
|
+
const onVisibilityChange = () => {
|
|
158
|
+
if (document.visibilityState === "visible") trySync();
|
|
159
|
+
};
|
|
160
|
+
const pollWindow = window.setInterval(() => {
|
|
161
|
+
if (providerSetupWindow?.closed) {
|
|
162
|
+
window.clearInterval(pollWindow);
|
|
163
|
+
trySync();
|
|
164
|
+
}
|
|
165
|
+
}, 1000);
|
|
166
|
+
window.addEventListener("focus", onFocus);
|
|
167
|
+
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
168
|
+
return () => {
|
|
169
|
+
window.clearInterval(pollWindow);
|
|
170
|
+
window.removeEventListener("focus", onFocus);
|
|
171
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
172
|
+
};
|
|
173
|
+
}, [pendingProviderId, providerSetupWindow]);
|
|
174
|
+
|
|
175
|
+
return (
|
|
176
|
+
<>
|
|
177
|
+
<WorkspaceAddOnsMarketplace
|
|
178
|
+
shell="page"
|
|
179
|
+
workspaceConfig={workspaceConfig}
|
|
180
|
+
envSignals={normalizedEnvSignals}
|
|
181
|
+
installing={Boolean(activeAction)}
|
|
182
|
+
activeAction={activeAction}
|
|
183
|
+
errorMessage={errorMessage}
|
|
184
|
+
setupMessage={setupMessage}
|
|
185
|
+
onConnectProvider={connectProvider}
|
|
186
|
+
onSyncProvider={syncProvider}
|
|
187
|
+
onSaveProviderCredentials={saveProviderCredentials}
|
|
188
|
+
onSyncProduct={syncProduct}
|
|
189
|
+
onCustomSetup={() => router.push("/settings/apis-webhooks")}
|
|
190
|
+
/>
|
|
191
|
+
</>
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export {
|
|
196
|
+
AddOnsSettingsClient
|
|
197
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { SettingsShell } from "../settings-shell.jsx";
|
|
2
|
+
import { readWorkspaceConfig } from "@/lib/workspace-config";
|
|
3
|
+
import { computeConfiguredEnvRefs, listPersistenceAdapterReadiness } from "@/lib/env-status";
|
|
4
|
+
import { listAllProviderProductReadiness } from "@/lib/workspace-add-ons";
|
|
5
|
+
import { AddOnsSettingsClient } from "./add-ons-client.jsx";
|
|
6
|
+
|
|
7
|
+
async function AddOnsSettingsPage() {
|
|
8
|
+
const workspaceConfig = await readWorkspaceConfig();
|
|
9
|
+
const envSignals = {
|
|
10
|
+
configuredEnvRefs: computeConfiguredEnvRefs(workspaceConfig, process.env),
|
|
11
|
+
persistenceAdapters: listPersistenceAdapterReadiness(process.env),
|
|
12
|
+
// Key MUST match what add-ons-client.jsx normalizes (`providerProductReadiness`).
|
|
13
|
+
// Provider-keyed so every marketplace provider's per-product readiness renders.
|
|
14
|
+
providerProductReadiness: listAllProviderProductReadiness(process.env),
|
|
15
|
+
};
|
|
16
|
+
return <SettingsShell active="/settings/add-ons" eyebrow="Settings" title="Marketplace">
|
|
17
|
+
<AddOnsSettingsClient initialWorkspaceConfig={workspaceConfig} envSignals={envSignals} />
|
|
18
|
+
</SettingsShell>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export {
|
|
22
|
+
AddOnsSettingsPage as default
|
|
23
|
+
};
|
|
@@ -4,6 +4,7 @@ import { X } from "lucide-react";
|
|
|
4
4
|
const SETTINGS_TABS = [
|
|
5
5
|
{ href: "/settings/general", label: "General" },
|
|
6
6
|
{ href: "/settings/apis-webhooks", label: "APIs & Webhooks" },
|
|
7
|
+
{ href: "/settings/add-ons", label: "Marketplace" },
|
|
7
8
|
{ href: "/settings/apps", label: "Apps" },
|
|
8
9
|
{ href: "/settings/ownership", label: "Ownership" }
|
|
9
10
|
];
|