@growthub/cli 0.9.12 → 0.9.13

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.
Files changed (18) hide show
  1. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/settings/apis-webhooks/route.js +59 -0
  2. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/settings/workspace/route.js +70 -0
  3. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/page.jsx +22 -5
  4. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/global-error.jsx +21 -0
  5. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/globals.css +689 -6
  6. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/settings/apis-webhooks/apis-webhooks-form.jsx +208 -0
  7. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/settings/apis-webhooks/page.jsx +19 -0
  8. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/settings/apps/apps-list.jsx +43 -0
  9. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/settings/apps/page.jsx +109 -0
  10. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/settings/general/general-settings-form.jsx +134 -0
  11. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/settings/general/page.jsx +25 -0
  12. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/settings/integrations/page.jsx +22 -3
  13. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/settings/page.jsx +25 -0
  14. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/settings/settings-shell.jsx +33 -0
  15. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/workspace-builder.jsx +19 -4
  16. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-config.js +186 -1
  17. package/dist/index.js +3 -1
  18. package/package.json +1 -1
@@ -0,0 +1,59 @@
1
+ import { NextResponse } from "next/server";
2
+ import {
3
+ describePersistenceMode,
4
+ readWorkspaceConfig,
5
+ writeWorkspaceApiWebhookSettings
6
+ } from "@/lib/workspace-config";
7
+
8
+ async function GET() {
9
+ const workspaceConfig = await readWorkspaceConfig();
10
+ const refs = Array.isArray(workspaceConfig.integrations)
11
+ ? workspaceConfig.integrations.filter((item) => item?.sourceType === "custom-api-webhooks")
12
+ : [];
13
+ return NextResponse.json({
14
+ adapterScope: "local-workspace-config",
15
+ persistence: describePersistenceMode(),
16
+ refs
17
+ });
18
+ }
19
+
20
+ async function PATCH(request) {
21
+ let patch;
22
+ try {
23
+ patch = await request.json();
24
+ } catch {
25
+ return NextResponse.json({ error: "invalid json body" }, { status: 400 });
26
+ }
27
+
28
+ try {
29
+ const refs = await writeWorkspaceApiWebhookSettings(patch);
30
+ return NextResponse.json({
31
+ adapterScope: "local-workspace-config",
32
+ refs
33
+ });
34
+ } catch (error) {
35
+ if (error.code === "WORKSPACE_PERSISTENCE_READ_ONLY") {
36
+ return NextResponse.json(
37
+ {
38
+ error: "workspace config is read-only in this runtime",
39
+ reason: error.message,
40
+ adapter: error.adapter,
41
+ guidance: error.guidance
42
+ },
43
+ { status: 409 }
44
+ );
45
+ }
46
+ if (error.code === "INVALID_WORKSPACE_SETTINGS_PATCH") {
47
+ return NextResponse.json({ error: error.message, details: error.details || [] }, { status: 400 });
48
+ }
49
+ if (error.code === "WORKSPACE_PERSISTENCE_PATH_REFUSED") {
50
+ return NextResponse.json({ error: error.message }, { status: 500 });
51
+ }
52
+ if (error.code === "INVALID_WORKSPACE_CONFIG") {
53
+ return NextResponse.json({ error: error.message, details: error.details }, { status: 400 });
54
+ }
55
+ return NextResponse.json({ error: error.message || "failed to write API/Webhook settings" }, { status: 500 });
56
+ }
57
+ }
58
+
59
+ export { GET, PATCH };
@@ -0,0 +1,70 @@
1
+ import { NextResponse } from "next/server";
2
+ import { readAdapterConfig } from "@/lib/adapters/env";
3
+ import { describeIntegrationAdapter } from "@/lib/adapters/integrations";
4
+ import {
5
+ describePersistenceMode,
6
+ readWorkspaceConfig,
7
+ writeWorkspaceIdentitySettings
8
+ } from "@/lib/workspace-config";
9
+
10
+ async function GET() {
11
+ const workspaceConfig = await readWorkspaceConfig();
12
+ return NextResponse.json({
13
+ adapterScope: "local-workspace-config",
14
+ config: readAdapterConfig(),
15
+ integrationAdapter: describeIntegrationAdapter(),
16
+ persistence: describePersistenceMode(),
17
+ workspace: {
18
+ id: workspaceConfig.id,
19
+ name: workspaceConfig.name,
20
+ branding: workspaceConfig.branding || {},
21
+ provenance: workspaceConfig.provenance || {}
22
+ }
23
+ });
24
+ }
25
+
26
+ async function PATCH(request) {
27
+ let patch;
28
+ try {
29
+ patch = await request.json();
30
+ } catch {
31
+ return NextResponse.json({ error: "invalid json body" }, { status: 400 });
32
+ }
33
+
34
+ try {
35
+ const workspaceConfig = await writeWorkspaceIdentitySettings(patch);
36
+ return NextResponse.json({
37
+ adapterScope: "local-workspace-config",
38
+ workspace: {
39
+ id: workspaceConfig.id,
40
+ name: workspaceConfig.name,
41
+ branding: workspaceConfig.branding || {},
42
+ provenance: workspaceConfig.provenance || {}
43
+ }
44
+ });
45
+ } catch (error) {
46
+ if (error.code === "WORKSPACE_PERSISTENCE_READ_ONLY") {
47
+ return NextResponse.json(
48
+ {
49
+ error: "workspace config is read-only in this runtime",
50
+ reason: error.message,
51
+ adapter: error.adapter,
52
+ guidance: error.guidance
53
+ },
54
+ { status: 409 }
55
+ );
56
+ }
57
+ if (error.code === "INVALID_WORKSPACE_SETTINGS_PATCH") {
58
+ return NextResponse.json({ error: error.message, details: error.details || [] }, { status: 400 });
59
+ }
60
+ if (error.code === "WORKSPACE_PERSISTENCE_PATH_REFUSED") {
61
+ return NextResponse.json({ error: error.message }, { status: 500 });
62
+ }
63
+ if (error.code === "INVALID_WORKSPACE_CONFIG") {
64
+ return NextResponse.json({ error: error.message, details: error.details }, { status: 400 });
65
+ }
66
+ return NextResponse.json({ error: error.message || "failed to write workspace settings" }, { status: 500 });
67
+ }
68
+ }
69
+
70
+ export { GET, PATCH };
@@ -41,19 +41,36 @@ function SaveToast({ saving, message }) {
41
41
  return <span className={`dm-toast ${message.startsWith("Error") ? "error" : "ok"}`}>{message}</span>;
42
42
  }
43
43
 
44
- function NavRail({ authority }) {
44
+ function textColorForAccent(accent) {
45
+ const hex = String(accent || "").replace("#", "");
46
+ if (!/^[0-9a-f]{6}$/i.test(hex)) return "#ffffff";
47
+ const red = parseInt(hex.slice(0, 2), 16);
48
+ const green = parseInt(hex.slice(2, 4), 16);
49
+ const blue = parseInt(hex.slice(4, 6), 16);
50
+ const luminance = (0.299 * red + 0.587 * green + 0.114 * blue) / 255;
51
+ return luminance > 0.62 ? "#252525" : "#ffffff";
52
+ }
53
+
54
+ function NavRail({ authority, workspaceConfig }) {
55
+ const branding = workspaceConfig?.branding || {};
56
+ const workspaceName = branding.name || workspaceConfig?.name || "Growthub Workspace";
45
57
  return (
46
58
  <aside className="workspace-rail" aria-label="Workspace navigation">
47
59
  <div className="workspace-brand">
48
- <span className="workspace-mark">G</span>
49
- <span>Growthub Workspace</span>
60
+ <span className="workspace-mark" style={{
61
+ background: branding.logoUrl ? undefined : branding.accent || undefined,
62
+ color: branding.logoUrl ? undefined : textColorForAccent(branding.accent)
63
+ }}>
64
+ {branding.logoUrl ? <img src={branding.logoUrl} alt="" /> : workspaceName.slice(0, 1).toUpperCase()}
65
+ </span>
66
+ <span>{workspaceName}</span>
50
67
  </div>
51
68
  <nav className="workspace-nav">
52
69
  <Link href="/">Dashboards</Link>
53
70
  <Link className="active" href="/data-model">Data Model</Link>
54
71
  <Link href="/settings/integrations">Integrations</Link>
55
- <span className="workspace-nav-static">Workspace Settings</span>
56
72
  <span className="workspace-nav-static">Management</span>
73
+ <Link className="workspace-nav-bottom" href="/settings/general">Workspace Settings</Link>
57
74
  </nav>
58
75
  <div className="workspace-rail-status"><span className="status-dot" />{authority || "local-catalog"}</div>
59
76
  </aside>
@@ -349,7 +366,7 @@ export default function DataModelPage() {
349
366
 
350
367
  return (
351
368
  <main className="workspace-builder workspace-settings-page">
352
- <NavRail authority={authority} />
369
+ <NavRail authority={authority} workspaceConfig={workspaceConfig} />
353
370
  <section className="workspace-surface">
354
371
  <header className="workspace-toolbar">
355
372
  <div><p>Workspace</p><h1>Data Model</h1></div>
@@ -0,0 +1,21 @@
1
+ "use client";
2
+
3
+ import "./globals.css";
4
+
5
+ function GlobalError() {
6
+ return <html lang="en">
7
+ <body>
8
+ <main className="workspace-error-page">
9
+ <section>
10
+ <h1>Workspace unavailable</h1>
11
+ <p>Reload the workspace or return to the dashboard.</p>
12
+ <a href="/">Open workspace</a>
13
+ </section>
14
+ </main>
15
+ </body>
16
+ </html>;
17
+ }
18
+
19
+ export {
20
+ GlobalError as default
21
+ };