@powerhousedao/vetra-builder-package 0.0.4 → 0.0.6
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/document-models/builder-account/src/reducers/packages.js +44 -16
- package/dist/document-models/builder-account/src/reducers/profile.js +13 -0
- package/dist/document-models/builder-account/src/reducers/spaces.js +21 -15
- package/dist/editors/builder-account-editor/editor.js +3 -4
- package/dist/editors/builder-account-editor/index.js +1 -1
- package/dist/processors/factory.js +3 -3
- package/dist/processors/vetra-read-model/index.js +42 -42
- package/dist/subgraphs/vetra-read-model/resolvers.js +62 -53
- package/dist/subgraphs/vetra-read-model/schema.js +12 -3
- package/package.json +1 -1
|
@@ -1,11 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { toPascalCase } from "document-drive/utils/misc";
|
|
2
2
|
export const reducer = {
|
|
3
3
|
addPackageOperation(state, action, dispatch) {
|
|
4
4
|
const { spaceId } = action.input;
|
|
5
|
-
const packageId =
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
const packageId = spaceId + "-" + toPascalCase(action.input.name);
|
|
6
|
+
// Find the space index
|
|
7
|
+
const spaceIndex = state.spaces.findIndex((space) => space.id === spaceId);
|
|
8
|
+
if (spaceIndex === -1) {
|
|
9
|
+
console.warn(`Space with id ${spaceId} not found`);
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
// Create the new package
|
|
13
|
+
const newPackage = {
|
|
9
14
|
id: packageId,
|
|
10
15
|
...action.input,
|
|
11
16
|
category: action.input.category ?? "",
|
|
@@ -24,11 +29,22 @@ export const reducer = {
|
|
|
24
29
|
},
|
|
25
30
|
keywords: action.input.keywords?.map((keyword) => {
|
|
26
31
|
return {
|
|
27
|
-
id:
|
|
32
|
+
id: keyword,
|
|
28
33
|
label: keyword,
|
|
29
34
|
};
|
|
30
35
|
}) ?? [],
|
|
31
|
-
}
|
|
36
|
+
};
|
|
37
|
+
// Create new space with the package added
|
|
38
|
+
const updatedSpace = {
|
|
39
|
+
...state.spaces[spaceIndex],
|
|
40
|
+
packages: [...state.spaces[spaceIndex].packages, newPackage],
|
|
41
|
+
};
|
|
42
|
+
// Replace the space in state
|
|
43
|
+
state.spaces = [
|
|
44
|
+
...state.spaces.slice(0, spaceIndex),
|
|
45
|
+
updatedSpace,
|
|
46
|
+
...state.spaces.slice(spaceIndex + 1),
|
|
47
|
+
];
|
|
32
48
|
},
|
|
33
49
|
setPackageDriveIdOperation(state, action, dispatch) {
|
|
34
50
|
const { packageId, driveId } = action.input;
|
|
@@ -56,17 +72,29 @@ export const reducer = {
|
|
|
56
72
|
const { ids, insertAfter, spaceId } = action.input;
|
|
57
73
|
for (const space of state.spaces) {
|
|
58
74
|
if (space.id === spaceId) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
75
|
+
// Remove the packages being reordered from their current positions
|
|
76
|
+
const reorderedPackages = space.packages.filter((pkg) => ids.includes(pkg.id));
|
|
77
|
+
const remainingPackages = space.packages.filter((pkg) => !ids.includes(pkg.id));
|
|
78
|
+
if (insertAfter) {
|
|
79
|
+
// Find the insertAfter package index in remaining packages
|
|
80
|
+
const insertAfterIndex = remainingPackages.findIndex((pkg) => pkg.id === insertAfter);
|
|
81
|
+
if (insertAfterIndex !== -1) {
|
|
82
|
+
// Insert the reordered packages after the insertAfter package
|
|
83
|
+
space.packages = [
|
|
84
|
+
...remainingPackages.slice(0, insertAfterIndex + 1),
|
|
85
|
+
...reorderedPackages,
|
|
86
|
+
...remainingPackages.slice(insertAfterIndex + 1),
|
|
87
|
+
];
|
|
64
88
|
}
|
|
65
|
-
|
|
66
|
-
|
|
89
|
+
else {
|
|
90
|
+
// If insertAfter package not found, just append to the end
|
|
91
|
+
space.packages = [...reorderedPackages, ...remainingPackages];
|
|
67
92
|
}
|
|
68
|
-
|
|
69
|
-
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
// No insertAfter specified, just append to the end
|
|
96
|
+
space.packages = [...reorderedPackages, ...remainingPackages];
|
|
97
|
+
}
|
|
70
98
|
}
|
|
71
99
|
}
|
|
72
100
|
},
|
|
@@ -5,6 +5,19 @@ export const reducer = {
|
|
|
5
5
|
},
|
|
6
6
|
setProfileNameOperation(state, action, dispatch) {
|
|
7
7
|
const { name } = action.input;
|
|
8
|
+
if (!state.profile) {
|
|
9
|
+
state.profile = {
|
|
10
|
+
logo: null,
|
|
11
|
+
name: "",
|
|
12
|
+
slug: "",
|
|
13
|
+
description: null,
|
|
14
|
+
socials: {
|
|
15
|
+
xProfile: null,
|
|
16
|
+
github: null,
|
|
17
|
+
website: null,
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
}
|
|
8
21
|
state.profile.name = name ?? state.profile.name;
|
|
9
22
|
},
|
|
10
23
|
setSlugOperation(state, action, dispatch) {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { toPascalCase } from "document-drive/utils/misc";
|
|
2
2
|
export const reducer = {
|
|
3
3
|
addSpaceOperation(state, action, dispatch) {
|
|
4
4
|
const { title, description } = action.input;
|
|
5
5
|
state.spaces.push({
|
|
6
|
-
id:
|
|
6
|
+
id: toPascalCase(title),
|
|
7
7
|
title: title ?? "",
|
|
8
8
|
description: description ?? "",
|
|
9
9
|
packages: [],
|
|
@@ -25,22 +25,28 @@ export const reducer = {
|
|
|
25
25
|
},
|
|
26
26
|
reorderSpacesOperation(state, action, dispatch) {
|
|
27
27
|
const { ids, insertAfter } = action.input;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (aIndex === -1) {
|
|
32
|
-
return 1;
|
|
33
|
-
}
|
|
34
|
-
if (bIndex === -1) {
|
|
35
|
-
return -1;
|
|
36
|
-
}
|
|
37
|
-
return aIndex - bIndex;
|
|
38
|
-
});
|
|
28
|
+
// Remove the spaces being reordered from their current positions
|
|
29
|
+
const reorderedSpaces = state.spaces.filter((space) => ids.includes(space.id));
|
|
30
|
+
const remainingSpaces = state.spaces.filter((space) => !ids.includes(space.id));
|
|
39
31
|
if (insertAfter) {
|
|
40
|
-
|
|
32
|
+
// Find the insertAfter space index in remaining spaces
|
|
33
|
+
const insertAfterIndex = remainingSpaces.findIndex((space) => space.id === insertAfter);
|
|
41
34
|
if (insertAfterIndex !== -1) {
|
|
42
|
-
|
|
35
|
+
// Insert the reordered spaces after the insertAfter space
|
|
36
|
+
state.spaces = [
|
|
37
|
+
...remainingSpaces.slice(0, insertAfterIndex + 1),
|
|
38
|
+
...reorderedSpaces,
|
|
39
|
+
...remainingSpaces.slice(insertAfterIndex + 1),
|
|
40
|
+
];
|
|
43
41
|
}
|
|
42
|
+
else {
|
|
43
|
+
// If insertAfter space not found, just append to the end
|
|
44
|
+
state.spaces = [...reorderedSpaces, ...remainingSpaces];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
// No insertAfter specified, just append to the end
|
|
49
|
+
state.spaces = [...reorderedSpaces, ...remainingSpaces];
|
|
44
50
|
}
|
|
45
51
|
},
|
|
46
52
|
};
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Button } from "@powerhousedao/design-system";
|
|
3
2
|
import { useDocumentById } from "@powerhousedao/reactor-browser";
|
|
4
3
|
import { useCallback, useState } from "react";
|
|
5
4
|
import { actions, } from "../../document-models/builder-account/index.js";
|
|
6
|
-
import { Form, StringField, UrlField } from "@powerhousedao/document-engineering";
|
|
5
|
+
import { Form, StringField, UrlField, Button } from "@powerhousedao/document-engineering";
|
|
7
6
|
export default function Editor(props) {
|
|
8
7
|
const { document: initialDocument } = props;
|
|
9
8
|
const [document, dispatch] = useDocumentById(initialDocument.header.id);
|
|
@@ -195,8 +194,8 @@ export default function Editor(props) {
|
|
|
195
194
|
const handleRemoveMember = useCallback((ethAddress) => {
|
|
196
195
|
dispatch(actions.removeMember({ ethAddress }));
|
|
197
196
|
}, [dispatch]);
|
|
198
|
-
return (_jsxs("div", { className: "html-defaults-container min-h-screen bg-gray-50", children: [_jsx("div", { className: "bg-white shadow-sm border-b", children: _jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: _jsx("div", { className: "py-6", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center space-x-4", children: [_jsx("div", { className: "flex-shrink-0", children: profile.logo ? (_jsx("img", { className: "w-12 h-12 rounded-lg object-cover", src: profile.logo, alt: "Logo" })) : (_jsx("div", { className: "w-12 h-12 bg-blue-600 rounded-lg flex items-center justify-center", children: _jsx("svg", { className: "w-6 h-6 text-white", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" }) }) })) }), _jsxs("div", { children: [_jsx("h1", { className: "text-2xl font-bold text-gray-900", children: profile.name || "Builder Account" }), _jsx("p", { className: "text-sm text-gray-500", children: profile.slug ? `@${profile.slug}` : "Manage your builder profile and packages" })] })] }), _jsx("div", { className: "flex items-center space-x-3", children: _jsx(Button, { color: "light", onClick: () => setIsEditingProfile(!isEditingProfile), children: isEditingProfile ? "Cancel" : "Edit Profile" }) })] }) }) }) }), _jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8", children: _jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-3 gap-8", children: [_jsxs("div", { className: "lg:col-span-2 space-y-8", children: [_jsxs("div", { className: "bg-white rounded-lg shadow-sm border", children: [_jsxs("div", { className: "px-6 py-4 border-b border-gray-200", children: [_jsx("h2", { className: "text-lg font-semibold text-gray-900", children: "Profile Information" }), _jsx("p", { className: "text-sm text-gray-500", children: "Manage your builder profile details" })] }), _jsx("div", { className: "p-6", children: isEditingProfile ? (_jsx(Form, { onSubmit: (e) => e.preventDefault(), children: _jsxs("div", { className: "space-y-6", children: [_jsx(StringField, { name: "profileName", label: "Profile Name", value: profile.name, onChange: (e) => handleSetProfileName(e.target.value), placeholder: "Enter your profile name", description: "Your public display name" }), _jsx(StringField, { name: "slug", label: "Slug", value: profile.slug, onChange: (e) => handleSetSlug(e.target.value), placeholder: "your-slug", description: "Unique identifier for your profile (used in URLs)" }), _jsx(StringField, { name: "description", label: "Description", value: profile.description || "", onChange: (e) => handleSetProfileDescription(e.target.value), placeholder: "Tell us about yourself and your work", description: "Brief description of your work and interests" }), _jsx(UrlField, { name: "logo", label: "Logo URL", value: profile.logo || "", onChange: (e) => handleSetLogo(e.target.value), placeholder: "https://example.com/logo.png", description: "URL to your profile logo image" }), _jsxs("div", { className: "space-y-4", children: [_jsx("h3", { className: "text-md font-medium text-gray-900", children: "Social Links" }), _jsx(UrlField, { name: "github", label: "GitHub", value: profile.socials.github || "", onChange: (e) => handleUpdateSocials({ ...profile.socials, github: e.target.value }), placeholder: "https://github.com/username" }), _jsx(UrlField, { name: "website", label: "Website", value: profile.socials.website || "", onChange: (e) => handleUpdateSocials({ ...profile.socials, website: e.target.value }), placeholder: "https://your-website.com" }), _jsx(UrlField, { name: "x", label: "X (Twitter)", value: profile.socials.xProfile || "", onChange: (e) => handleUpdateSocials({ ...profile.socials, x: e.target.value }), placeholder: "https://x.com/username" })] }), _jsxs("div", { className: "flex justify-end space-x-3", children: [_jsx(Button, { color: "light", onClick: () => setIsEditingProfile(false), children: "Cancel" }), _jsx(Button, { onClick: () => setIsEditingProfile(false), children: "Save Changes" })] })] }) })) : (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [_jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700", children: "Name" }), _jsx("p", { className: "mt-1 text-sm text-gray-900", children: profile.name || "Not set" })] }), _jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700", children: "Slug" }), _jsx("p", { className: "mt-1 text-sm text-gray-900", children: profile.slug ? `@${profile.slug}` : "Not set" })] })] }), profile.description && (_jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700", children: "Description" }), _jsx("p", { className: "mt-1 text-sm text-gray-900", children: profile.description })] })), _jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700", children: "Social Links" }), _jsxs("div", { className: "mt-2 flex space-x-4", children: [profile.socials.github && (_jsx("a", { href: profile.socials.github, target: "_blank", rel: "noopener noreferrer", className: "text-blue-600 hover:text-blue-800", children: "GitHub" })), profile.socials.website && (_jsx("a", { href: profile.socials.website, target: "_blank", rel: "noopener noreferrer", className: "text-blue-600 hover:text-blue-800", children: "Website" })), profile.socials.xProfile && (_jsx("a", { href: profile.socials.xProfile, target: "_blank", rel: "noopener noreferrer", className: "text-blue-600 hover:text-blue-800", children: "X (Twitter)" })), !profile.socials.github && !profile.socials.website && !profile.socials.xProfile && (_jsx("span", { className: "text-gray-500 text-sm", children: "No social links added" }))] })] })] })) })] }), _jsxs("div", { className: "bg-white rounded-lg shadow-sm border", children: [_jsx("div", { className: "px-6 py-4 border-b border-gray-200", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { children: [_jsx("h2", { className: "text-lg font-semibold text-gray-900", children: "Spaces" }), _jsx("p", { className: "text-sm text-gray-500", children: "Organize your packages into spaces" })] }), _jsx(Button, { onClick: () => setIsAddingSpace(true), children: "Add Space" })] }) }), _jsxs("div", { className: "p-6", children: [isAddingSpace ? (_jsx("div", { className: "p-4 bg-gray-50 rounded-lg", children: _jsx(Form, { onSubmit: (e) => e.preventDefault(), children: _jsxs("div", { className: "space-y-4", children: [_jsx(StringField, { name: "spaceTitle", label: "Space Title", value: newSpaceTitle, onChange: (e) => setNewSpaceTitle(e.target.value), placeholder: "Enter space title" }), _jsx(StringField, { name: "spaceDescription", label: "Description (optional)", value: newSpaceDescription, onChange: (e) => setNewSpaceDescription(e.target.value), placeholder: "Enter space description" }), _jsxs("div", { className: "flex justify-end space-x-3", children: [_jsx(Button, { color: "light", onClick: () => setIsAddingSpace(false), children: "Cancel" }), _jsx(Button, { onClick: handleAddSpace, disabled: !newSpaceTitle.trim(), children: "Add Space" })] })] }) }) })) : null, _jsx("div", { className: "space-y-4", children: spaces.length > 0 ? (spaces.map((space) => (_jsxs("div", { className: "border border-gray-200 rounded-lg p-4", children: [editingSpaceId === space.id ? (_jsx(Form, { onSubmit: (e) => e.preventDefault(), children: _jsxs("div", { className: "space-y-4", children: [_jsx(StringField, { name: "editingSpaceTitle", label: "Space Title", value: editingSpaceTitle, onChange: (e) => setEditingSpaceTitle(e.target.value), placeholder: "Enter space title" }), _jsx(StringField, { name: "editingSpaceDescription", label: "Description (optional)", value: editingSpaceDescription, onChange: (e) => setEditingSpaceDescription(e.target.value), placeholder: "Enter space description" }), _jsxs("div", { className: "flex justify-end space-x-3", children: [_jsx(Button, { color: "light", onClick: handleCancelSpaceEdit, children: "Cancel" }), _jsx(Button, { onClick: handleSaveSpaceEdit, disabled: !editingSpaceTitle.trim(), children: "Save Changes" })] })] }) })) : (_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { children: [_jsx("h3", { className: "text-md font-medium text-gray-900", children: space.title }), space.description && (_jsx("p", { className: "text-sm text-gray-500 mt-1", children: space.description })), _jsxs("p", { className: "text-xs text-gray-400 mt-1", children: [space.packages.length, " package", space.packages.length !== 1 ? 's' : ''] })] }), _jsxs("div", { className: "flex space-x-2", children: [_jsx(Button, { color: "light", size: "
|
|
197
|
+
return (_jsxs("div", { className: "html-defaults-container min-h-screen bg-gray-50", children: [_jsx("div", { className: "bg-white shadow-sm border-b", children: _jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: _jsx("div", { className: "py-6", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center space-x-4", children: [_jsx("div", { className: "flex-shrink-0", children: profile.logo ? (_jsx("img", { className: "w-12 h-12 rounded-lg object-cover", src: profile.logo, alt: "Logo" })) : (_jsx("div", { className: "w-12 h-12 bg-blue-600 rounded-lg flex items-center justify-center", children: _jsx("svg", { className: "w-6 h-6 text-white", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" }) }) })) }), _jsxs("div", { children: [_jsx("h1", { className: "text-2xl font-bold text-gray-900", children: profile.name || "Builder Account" }), _jsx("p", { className: "text-sm text-gray-500", children: profile.slug ? `@${profile.slug}` : "Manage your builder profile and packages" })] })] }), _jsx("div", { className: "flex items-center space-x-3", children: _jsx(Button, { color: "light", onClick: () => setIsEditingProfile(!isEditingProfile), children: isEditingProfile ? "Cancel" : "Edit Profile" }) })] }) }) }) }), _jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8", children: _jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-3 gap-8", children: [_jsxs("div", { className: "lg:col-span-2 space-y-8", children: [_jsxs("div", { className: "bg-white rounded-lg shadow-sm border", children: [_jsxs("div", { className: "px-6 py-4 border-b border-gray-200", children: [_jsx("h2", { className: "text-lg font-semibold text-gray-900", children: "Profile Information" }), _jsx("p", { className: "text-sm text-gray-500", children: "Manage your builder profile details" })] }), _jsx("div", { className: "p-6", children: isEditingProfile ? (_jsx(Form, { onSubmit: (e) => e.preventDefault(), children: _jsxs("div", { className: "space-y-6", children: [_jsx(StringField, { name: "profileName", label: "Profile Name", value: profile.name, onChange: (e) => handleSetProfileName(e.target.value), placeholder: "Enter your profile name", description: "Your public display name" }), _jsx(StringField, { name: "slug", label: "Slug", value: profile.slug, onChange: (e) => handleSetSlug(e.target.value), placeholder: "your-slug", description: "Unique identifier for your profile (used in URLs)" }), _jsx(StringField, { name: "description", label: "Description", value: profile.description || "", onChange: (e) => handleSetProfileDescription(e.target.value), placeholder: "Tell us about yourself and your work", description: "Brief description of your work and interests" }), _jsx(UrlField, { name: "logo", label: "Logo URL", value: profile.logo || "", onChange: (e) => handleSetLogo(e.target.value), placeholder: "https://example.com/logo.png", description: "URL to your profile logo image" }), _jsxs("div", { className: "space-y-4", children: [_jsx("h3", { className: "text-md font-medium text-gray-900", children: "Social Links" }), _jsx(UrlField, { name: "github", label: "GitHub", value: profile.socials.github || "", onChange: (e) => handleUpdateSocials({ ...profile.socials, github: e.target.value }), placeholder: "https://github.com/username" }), _jsx(UrlField, { name: "website", label: "Website", value: profile.socials.website || "", onChange: (e) => handleUpdateSocials({ ...profile.socials, website: e.target.value }), placeholder: "https://your-website.com" }), _jsx(UrlField, { name: "x", label: "X (Twitter)", value: profile.socials.xProfile || "", onChange: (e) => handleUpdateSocials({ ...profile.socials, x: e.target.value }), placeholder: "https://x.com/username" })] }), _jsxs("div", { className: "flex justify-end space-x-3", children: [_jsx(Button, { color: "light", onClick: () => setIsEditingProfile(false), children: "Cancel" }), _jsx(Button, { onClick: () => setIsEditingProfile(false), children: "Save Changes" })] })] }) })) : (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [_jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700", children: "Name" }), _jsx("p", { className: "mt-1 text-sm text-gray-900", children: profile.name || "Not set" })] }), _jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700", children: "Slug" }), _jsx("p", { className: "mt-1 text-sm text-gray-900", children: profile.slug ? `@${profile.slug}` : "Not set" })] })] }), profile.description && (_jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700", children: "Description" }), _jsx("p", { className: "mt-1 text-sm text-gray-900", children: profile.description })] })), _jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700", children: "Social Links" }), _jsxs("div", { className: "mt-2 flex space-x-4", children: [profile.socials.github && (_jsx("a", { href: profile.socials.github, target: "_blank", rel: "noopener noreferrer", className: "text-blue-600 hover:text-blue-800", children: "GitHub" })), profile.socials.website && (_jsx("a", { href: profile.socials.website, target: "_blank", rel: "noopener noreferrer", className: "text-blue-600 hover:text-blue-800", children: "Website" })), profile.socials.xProfile && (_jsx("a", { href: profile.socials.xProfile, target: "_blank", rel: "noopener noreferrer", className: "text-blue-600 hover:text-blue-800", children: "X (Twitter)" })), !profile.socials.github && !profile.socials.website && !profile.socials.xProfile && (_jsx("span", { className: "text-gray-500 text-sm", children: "No social links added" }))] })] })] })) })] }), _jsxs("div", { className: "bg-white rounded-lg shadow-sm border", children: [_jsx("div", { className: "px-6 py-4 border-b border-gray-200", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { children: [_jsx("h2", { className: "text-lg font-semibold text-gray-900", children: "Spaces" }), _jsx("p", { className: "text-sm text-gray-500", children: "Organize your packages into spaces" })] }), _jsx(Button, { onClick: () => setIsAddingSpace(true), children: "Add Space" })] }) }), _jsxs("div", { className: "p-6", children: [isAddingSpace ? (_jsx("div", { className: "p-4 bg-gray-50 rounded-lg", children: _jsx(Form, { onSubmit: (e) => e.preventDefault(), children: _jsxs("div", { className: "space-y-4", children: [_jsx(StringField, { name: "spaceTitle", label: "Space Title", value: newSpaceTitle, onChange: (e) => setNewSpaceTitle(e.target.value), placeholder: "Enter space title" }), _jsx(StringField, { name: "spaceDescription", label: "Description (optional)", value: newSpaceDescription, onChange: (e) => setNewSpaceDescription(e.target.value), placeholder: "Enter space description" }), _jsxs("div", { className: "flex justify-end space-x-3", children: [_jsx(Button, { color: "light", onClick: () => setIsAddingSpace(false), children: "Cancel" }), _jsx(Button, { onClick: handleAddSpace, disabled: !newSpaceTitle.trim(), children: "Add Space" })] })] }) }) })) : null, _jsx("div", { className: "space-y-4", children: spaces.length > 0 ? (spaces.map((space) => (_jsxs("div", { className: "border border-gray-200 rounded-lg p-4", children: [editingSpaceId === space.id ? (_jsx(Form, { onSubmit: (e) => e.preventDefault(), children: _jsxs("div", { className: "space-y-4", children: [_jsx(StringField, { name: "editingSpaceTitle", label: "Space Title", value: editingSpaceTitle, onChange: (e) => setEditingSpaceTitle(e.target.value), placeholder: "Enter space title" }), _jsx(StringField, { name: "editingSpaceDescription", label: "Description (optional)", value: editingSpaceDescription, onChange: (e) => setEditingSpaceDescription(e.target.value), placeholder: "Enter space description" }), _jsxs("div", { className: "flex justify-end space-x-3", children: [_jsx(Button, { color: "light", onClick: handleCancelSpaceEdit, children: "Cancel" }), _jsx(Button, { onClick: handleSaveSpaceEdit, disabled: !editingSpaceTitle.trim(), children: "Save Changes" })] })] }) })) : (_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { children: [_jsx("h3", { className: "text-md font-medium text-gray-900", children: space.title }), space.description && (_jsx("p", { className: "text-sm text-gray-500 mt-1", children: space.description })), _jsxs("p", { className: "text-xs text-gray-400 mt-1", children: [space.packages.length, " package", space.packages.length !== 1 ? 's' : ''] })] }), _jsxs("div", { className: "flex space-x-2", children: [_jsx(Button, { color: "light", size: "sm", onClick: () => handleStartEditingSpace(space.id), children: "Edit" }), _jsx(Button, { color: "light", size: "sm", onClick: () => {
|
|
199
198
|
setSelectedSpaceForPackage(space.id);
|
|
200
199
|
setIsAddingPackage(true);
|
|
201
|
-
}, children: "Add Package" }), _jsx(Button, { color: "red", size: "
|
|
200
|
+
}, children: "Add Package" }), _jsx(Button, { color: "red", size: "sm", onClick: () => handleDeleteSpace(space.id), children: "Delete" })] })] })), space.packages.length > 0 && (_jsx("div", { className: "mt-4 space-y-2", children: space.packages.map((pkg) => (_jsx("div", { className: "p-3 bg-gray-50 rounded border", children: editingPackageId === pkg.id ? (_jsx(Form, { onSubmit: (e) => e.preventDefault(), children: _jsxs("div", { className: "space-y-3", children: [_jsx(StringField, { name: "editingPackageName", label: "Package Name", value: editingPackageName, onChange: (e) => setEditingPackageName(e.target.value), placeholder: "Enter package name" }), _jsx(StringField, { name: "editingPackageDescription", label: "Description", value: editingPackageDescription, onChange: (e) => setEditingPackageDescription(e.target.value), placeholder: "Enter package description" }), _jsx(StringField, { name: "editingPackageCategory", label: "Category", value: editingPackageCategory, onChange: (e) => setEditingPackageCategory(e.target.value), placeholder: "Enter package category" }), _jsx(UrlField, { name: "editingPackageGithub", label: "GitHub URL", value: editingPackageGithub, onChange: (e) => setEditingPackageGithub(e.target.value), placeholder: "https://github.com/username/repo" }), _jsx(UrlField, { name: "editingPackageNpm", label: "NPM URL", value: editingPackageNpm, onChange: (e) => setEditingPackageNpm(e.target.value), placeholder: "https://www.npmjs.com/package/package-name" }), _jsxs("div", { className: "flex justify-end space-x-3", children: [_jsx(Button, { color: "light", onClick: handleCancelPackageEdit, children: "Cancel" }), _jsx(Button, { onClick: handleSavePackageEdit, disabled: !editingPackageName.trim(), children: "Save Changes" })] })] }) })) : (_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { children: [_jsx("span", { className: "font-medium text-gray-900", children: pkg.name }), pkg.description && (_jsx("p", { className: "text-sm text-gray-500", children: pkg.description })), pkg.category && (_jsxs("p", { className: "text-xs text-gray-400", children: ["Category: ", pkg.category] }))] }), _jsxs("div", { className: "flex space-x-2", children: [_jsx(Button, { color: "light", size: "sm", onClick: () => handleStartEditingPackage(pkg.id), children: "Edit" }), _jsx(Button, { color: "red", size: "sm", onClick: () => handleDeletePackage(pkg.id), children: "Remove" })] })] })) }, pkg.id))) }))] }, space.id)))) : (_jsx("div", { className: "text-center py-8 text-gray-500", children: _jsx("p", { children: "No spaces created yet. Create a space to organize your packages." }) })) })] })] }), isAddingPackage && (_jsxs("div", { className: "bg-white rounded-lg shadow-sm border", children: [_jsx("div", { className: "px-6 py-4 border-b border-gray-200", children: _jsx("h2", { className: "text-lg font-semibold text-gray-900", children: "Add Package" }) }), _jsx("div", { className: "p-6", children: _jsx(Form, { onSubmit: (e) => e.preventDefault(), children: _jsxs("div", { className: "space-y-4", children: [_jsx(StringField, { name: "packageName", label: "Package Name", value: newPackageName, onChange: (e) => setNewPackageName(e.target.value), placeholder: "Enter package name" }), _jsx(StringField, { name: "packageDescription", label: "Description", value: newPackageDescription, onChange: (e) => setNewPackageDescription(e.target.value), placeholder: "Enter package description" }), _jsx(StringField, { name: "packageCategory", label: "Category", value: newPackageCategory, onChange: (e) => setNewPackageCategory(e.target.value), placeholder: "Enter package category" }), _jsx(UrlField, { name: "packageGithub", label: "GitHub URL", value: newPackageGithub, onChange: (e) => setNewPackageGithub(e.target.value), placeholder: "https://github.com/username/repo" }), _jsx(UrlField, { name: "packageNpm", label: "NPM URL", value: newPackageNpm, onChange: (e) => setNewPackageNpm(e.target.value), placeholder: "https://www.npmjs.com/package/package-name" }), _jsxs("div", { className: "flex justify-end space-x-3", children: [_jsx(Button, { color: "light", onClick: () => setIsAddingPackage(false), children: "Cancel" }), _jsx(Button, { onClick: handleAddPackage, disabled: !newPackageName.trim() || !selectedSpaceForPackage, children: "Add Package" })] })] }) }) })] }))] }), _jsxs("div", { className: "space-y-6", children: [_jsxs("div", { className: "bg-white rounded-lg shadow-sm border", children: [_jsxs("div", { className: "px-6 py-4 border-b border-gray-200", children: [_jsx("h3", { className: "text-lg font-semibold text-gray-900", children: "Team Members" }), _jsx("p", { className: "text-sm text-gray-500", children: "Manage team access" })] }), _jsx("div", { className: "p-6", children: _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex space-x-2", children: [_jsx("input", { type: "text", value: newMemberAddress, onChange: (e) => setNewMemberAddress(e.target.value), placeholder: "0x...", className: "flex-1 px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500" }), _jsx(Button, { onClick: handleAddMember, disabled: !newMemberAddress.trim(), children: "Add" })] }), _jsx("div", { className: "space-y-2", children: members.length > 0 ? (members.map((address, index) => (_jsxs("div", { className: "flex items-center justify-between p-2 bg-gray-50 rounded border", children: [_jsx("span", { className: "text-sm font-mono text-gray-700 truncate", children: address }), _jsx(Button, { color: "red", size: "sm", onClick: () => handleRemoveMember(address), children: "Remove" })] }, index)))) : (_jsx("p", { className: "text-sm text-gray-500", children: "No team members added yet" })) })] }) })] }), _jsxs("div", { className: "bg-white rounded-lg shadow-sm border", children: [_jsx("div", { className: "px-6 py-4 border-b border-gray-200", children: _jsx("h3", { className: "text-lg font-semibold text-gray-900", children: "Quick Stats" }) }), _jsx("div", { className: "p-6", children: _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex justify-between items-center", children: [_jsx("span", { className: "text-sm text-gray-500", children: "Spaces" }), _jsx("span", { className: "text-sm font-medium text-gray-900", children: spaces.length })] }), _jsxs("div", { className: "flex justify-between items-center", children: [_jsx("span", { className: "text-sm text-gray-500", children: "Total Packages" }), _jsx("span", { className: "text-sm font-medium text-gray-900", children: spaces.reduce((total, space) => total + space.packages.length, 0) })] }), _jsxs("div", { className: "flex justify-between items-center", children: [_jsx("span", { className: "text-sm text-gray-500", children: "Team Members" }), _jsx("span", { className: "text-sm font-medium text-gray-900", children: members.length })] })] }) })] })] })] }) })] }));
|
|
202
201
|
}
|
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
* This file aggregates all processor factories
|
|
3
3
|
* Auto-generated by codegen - DO NOT EDIT MANUALLY
|
|
4
4
|
*/
|
|
5
|
-
// Import processor factories here as they are generated
|
|
5
|
+
// Import other processor factories here as they are generated
|
|
6
6
|
import { vetraReadModelProcessorFactory } from "./vetra-read-model/factory.js";
|
|
7
7
|
export const processorFactory = (module) => {
|
|
8
8
|
// Initialize all processor factories once with the module
|
|
9
9
|
const factories = [];
|
|
10
|
-
// Add processors here as they are generated
|
|
10
|
+
// Add other processors here as they are generated
|
|
11
11
|
factories.push(vetraReadModelProcessorFactory(module));
|
|
12
12
|
// Return the inner function that will be called for each drive
|
|
13
13
|
return async (driveHeader) => {
|
|
14
14
|
const processors = [];
|
|
15
|
-
// Call each cached factory with the
|
|
15
|
+
// Call each cached factory with the driveId
|
|
16
16
|
for (const factory of factories) {
|
|
17
17
|
const factoryProcessors = await factory(driveHeader);
|
|
18
18
|
processors.push(...factoryProcessors);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { RelationalDbProcessor } from "document-drive/processors/relational";
|
|
2
|
-
import { generateId } from "document-model";
|
|
3
2
|
import { up } from "./migrations.js";
|
|
3
|
+
import { toPascalCase } from "document-drive/utils/misc";
|
|
4
4
|
export class VetraReadModelProcessor extends RelationalDbProcessor {
|
|
5
5
|
static getNamespace(driveId) {
|
|
6
6
|
// Default namespace: `${this.name}_${driveId.replaceAll("-", "_")}`
|
|
@@ -18,71 +18,71 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
|
|
|
18
18
|
continue;
|
|
19
19
|
}
|
|
20
20
|
for (const operation of strand.operations) {
|
|
21
|
-
await this.handleOperation(strand.documentId, operation.action);
|
|
21
|
+
await this.handleOperation(strand.documentId, operation.action, operation.state);
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
|
-
async handleOperation(documentId, action) {
|
|
25
|
+
async handleOperation(documentId, action, state) {
|
|
26
26
|
switch (action.type) {
|
|
27
27
|
// Profile operations
|
|
28
28
|
case "SET_LOGO":
|
|
29
|
-
await this.handleSetLogo(documentId, action);
|
|
29
|
+
await this.handleSetLogo(documentId, action, state);
|
|
30
30
|
break;
|
|
31
31
|
case "SET_PROFILE_NAME":
|
|
32
|
-
await this.handleSetProfileName(documentId, action);
|
|
32
|
+
await this.handleSetProfileName(documentId, action, state);
|
|
33
33
|
break;
|
|
34
34
|
case "SET_SLUG":
|
|
35
|
-
await this.handleSetSlug(documentId, action);
|
|
35
|
+
await this.handleSetSlug(documentId, action, state);
|
|
36
36
|
break;
|
|
37
37
|
case "SET_PROFILE_DESCRIPTION":
|
|
38
|
-
await this.handleSetProfileDescription(documentId, action);
|
|
38
|
+
await this.handleSetProfileDescription(documentId, action, state);
|
|
39
39
|
break;
|
|
40
40
|
case "UPDATE_SOCIALS":
|
|
41
|
-
await this.handleUpdateSocials(documentId, action);
|
|
41
|
+
await this.handleUpdateSocials(documentId, action, state);
|
|
42
42
|
break;
|
|
43
43
|
// Members operations
|
|
44
44
|
case "ADD_MEMBER":
|
|
45
|
-
await this.handleAddMember(documentId, action);
|
|
45
|
+
await this.handleAddMember(documentId, action, state);
|
|
46
46
|
break;
|
|
47
47
|
case "REMOVE_MEMBER":
|
|
48
|
-
await this.handleRemoveMember(documentId, action);
|
|
48
|
+
await this.handleRemoveMember(documentId, action, state);
|
|
49
49
|
break;
|
|
50
50
|
// Spaces operations
|
|
51
51
|
case "ADD_SPACE":
|
|
52
|
-
await this.handleAddSpace(documentId, action);
|
|
52
|
+
await this.handleAddSpace(documentId, action, state);
|
|
53
53
|
break;
|
|
54
54
|
case "DELETE_SPACE":
|
|
55
|
-
await this.handleDeleteSpace(documentId, action);
|
|
55
|
+
await this.handleDeleteSpace(documentId, action, state);
|
|
56
56
|
break;
|
|
57
57
|
case "SET_SPACE_TITLE":
|
|
58
|
-
await this.handleSetSpaceTitle(documentId, action);
|
|
58
|
+
await this.handleSetSpaceTitle(documentId, action, state);
|
|
59
59
|
break;
|
|
60
60
|
case "SET_SPACE_DESCRIPTION":
|
|
61
|
-
await this.handleSetSpaceDescription(documentId, action);
|
|
61
|
+
await this.handleSetSpaceDescription(documentId, action, state);
|
|
62
62
|
break;
|
|
63
63
|
case "REORDER_SPACES":
|
|
64
|
-
await this.handleReorderSpaces(documentId, action);
|
|
64
|
+
await this.handleReorderSpaces(documentId, action, state);
|
|
65
65
|
break;
|
|
66
66
|
// Packages operations
|
|
67
67
|
case "ADD_PACKAGE":
|
|
68
|
-
await this.handleAddPackage(documentId, action);
|
|
68
|
+
await this.handleAddPackage(documentId, action, state);
|
|
69
69
|
break;
|
|
70
70
|
case "SET_PACKAGE_DRIVE_ID":
|
|
71
|
-
await this.handleSetPackageDriveId(documentId, action);
|
|
71
|
+
await this.handleSetPackageDriveId(documentId, action, state);
|
|
72
72
|
break;
|
|
73
73
|
case "UPDATE_PACKAGE":
|
|
74
|
-
await this.handleUpdatePackage(documentId, action);
|
|
74
|
+
await this.handleUpdatePackage(documentId, action, state);
|
|
75
75
|
break;
|
|
76
76
|
case "REORDER_PACKAGES":
|
|
77
|
-
await this.handleReorderPackages(documentId, action);
|
|
77
|
+
await this.handleReorderPackages(documentId, action, state);
|
|
78
78
|
break;
|
|
79
79
|
case "DELETE_PACKAGE":
|
|
80
|
-
await this.handleDeletePackage(documentId, action);
|
|
80
|
+
await this.handleDeletePackage(documentId, action, state);
|
|
81
81
|
break;
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
// Profile operations
|
|
85
|
-
async handleSetLogo(documentId, action) {
|
|
85
|
+
async handleSetLogo(documentId, action, state) {
|
|
86
86
|
await this.ensureBuilderAccount(documentId);
|
|
87
87
|
await this.relationalDb
|
|
88
88
|
.updateTable("builder_accounts")
|
|
@@ -93,7 +93,7 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
|
|
|
93
93
|
.where("id", "=", documentId)
|
|
94
94
|
.execute();
|
|
95
95
|
}
|
|
96
|
-
async handleSetProfileName(documentId, action) {
|
|
96
|
+
async handleSetProfileName(documentId, action, state) {
|
|
97
97
|
await this.ensureBuilderAccount(documentId);
|
|
98
98
|
await this.relationalDb
|
|
99
99
|
.updateTable("builder_accounts")
|
|
@@ -104,7 +104,7 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
|
|
|
104
104
|
.where("id", "=", documentId)
|
|
105
105
|
.execute();
|
|
106
106
|
}
|
|
107
|
-
async handleSetSlug(documentId, action) {
|
|
107
|
+
async handleSetSlug(documentId, action, state) {
|
|
108
108
|
await this.ensureBuilderAccount(documentId);
|
|
109
109
|
await this.relationalDb
|
|
110
110
|
.updateTable("builder_accounts")
|
|
@@ -115,7 +115,7 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
|
|
|
115
115
|
.where("id", "=", documentId)
|
|
116
116
|
.execute();
|
|
117
117
|
}
|
|
118
|
-
async handleSetProfileDescription(documentId, action) {
|
|
118
|
+
async handleSetProfileDescription(documentId, action, state) {
|
|
119
119
|
await this.ensureBuilderAccount(documentId);
|
|
120
120
|
await this.relationalDb
|
|
121
121
|
.updateTable("builder_accounts")
|
|
@@ -126,7 +126,7 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
|
|
|
126
126
|
.where("id", "=", documentId)
|
|
127
127
|
.execute();
|
|
128
128
|
}
|
|
129
|
-
async handleUpdateSocials(documentId, action) {
|
|
129
|
+
async handleUpdateSocials(documentId, action, state) {
|
|
130
130
|
await this.ensureBuilderAccount(documentId);
|
|
131
131
|
await this.relationalDb
|
|
132
132
|
.updateTable("builder_accounts")
|
|
@@ -140,7 +140,7 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
|
|
|
140
140
|
.execute();
|
|
141
141
|
}
|
|
142
142
|
// Members operations
|
|
143
|
-
async handleAddMember(documentId, action) {
|
|
143
|
+
async handleAddMember(documentId, action, state) {
|
|
144
144
|
await this.ensureBuilderAccount(documentId);
|
|
145
145
|
if (!action.input.ethAddress)
|
|
146
146
|
return;
|
|
@@ -155,7 +155,7 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
|
|
|
155
155
|
await this.relationalDb
|
|
156
156
|
.insertInto("builder_account_members")
|
|
157
157
|
.values({
|
|
158
|
-
id:
|
|
158
|
+
id: action.input.ethAddress,
|
|
159
159
|
builder_account_id: documentId,
|
|
160
160
|
eth_address: action.input.ethAddress,
|
|
161
161
|
created_at: new Date(),
|
|
@@ -163,7 +163,7 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
|
|
|
163
163
|
.execute();
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
|
-
async handleRemoveMember(documentId, action) {
|
|
166
|
+
async handleRemoveMember(documentId, action, state) {
|
|
167
167
|
if (!action.input.ethAddress)
|
|
168
168
|
return;
|
|
169
169
|
await this.relationalDb
|
|
@@ -173,9 +173,9 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
|
|
|
173
173
|
.execute();
|
|
174
174
|
}
|
|
175
175
|
// Spaces operations
|
|
176
|
-
async handleAddSpace(documentId, action) {
|
|
176
|
+
async handleAddSpace(documentId, action, state) {
|
|
177
177
|
await this.ensureBuilderAccount(documentId);
|
|
178
|
-
const spaceId =
|
|
178
|
+
const spaceId = toPascalCase(action.input.title);
|
|
179
179
|
await this.relationalDb
|
|
180
180
|
.insertInto("builder_spaces")
|
|
181
181
|
.values({
|
|
@@ -190,14 +190,14 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
|
|
|
190
190
|
.onConflict((oc) => oc.column("id").doNothing())
|
|
191
191
|
.execute();
|
|
192
192
|
}
|
|
193
|
-
async handleDeleteSpace(documentId, action) {
|
|
193
|
+
async handleDeleteSpace(documentId, action, state) {
|
|
194
194
|
await this.relationalDb
|
|
195
195
|
.deleteFrom("builder_spaces")
|
|
196
196
|
.where("id", "=", action.input.id)
|
|
197
197
|
.where("builder_account_id", "=", documentId)
|
|
198
198
|
.execute();
|
|
199
199
|
}
|
|
200
|
-
async handleSetSpaceTitle(documentId, action) {
|
|
200
|
+
async handleSetSpaceTitle(documentId, action, state) {
|
|
201
201
|
await this.relationalDb
|
|
202
202
|
.updateTable("builder_spaces")
|
|
203
203
|
.set({
|
|
@@ -208,7 +208,7 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
|
|
|
208
208
|
.where("builder_account_id", "=", documentId)
|
|
209
209
|
.execute();
|
|
210
210
|
}
|
|
211
|
-
async handleSetSpaceDescription(documentId, action) {
|
|
211
|
+
async handleSetSpaceDescription(documentId, action, state) {
|
|
212
212
|
await this.relationalDb
|
|
213
213
|
.updateTable("builder_spaces")
|
|
214
214
|
.set({
|
|
@@ -219,7 +219,7 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
|
|
|
219
219
|
.where("builder_account_id", "=", documentId)
|
|
220
220
|
.execute();
|
|
221
221
|
}
|
|
222
|
-
async handleReorderSpaces(documentId, action) {
|
|
222
|
+
async handleReorderSpaces(documentId, action, state) {
|
|
223
223
|
const { ids, insertAfter } = action.input;
|
|
224
224
|
for (let i = 0; i < ids.length; i++) {
|
|
225
225
|
const spaceId = ids[i];
|
|
@@ -236,12 +236,12 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
|
|
|
236
236
|
}
|
|
237
237
|
}
|
|
238
238
|
// Packages operations
|
|
239
|
-
async handleAddPackage(documentId, action) {
|
|
240
|
-
const packageId =
|
|
239
|
+
async handleAddPackage(documentId, action, state) {
|
|
240
|
+
const packageId = action.input.spaceId + "-" + toPascalCase(action.input.name);
|
|
241
241
|
await this.relationalDb
|
|
242
242
|
.insertInto("builder_packages")
|
|
243
243
|
.values({
|
|
244
|
-
id: packageId
|
|
244
|
+
id: `${packageId}`,
|
|
245
245
|
space_id: action.input.spaceId,
|
|
246
246
|
name: action.input.name,
|
|
247
247
|
description: action.input.description || null,
|
|
@@ -264,7 +264,7 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
|
|
|
264
264
|
await this.relationalDb
|
|
265
265
|
.insertInto("builder_package_keywords")
|
|
266
266
|
.values({
|
|
267
|
-
id:
|
|
267
|
+
id: `${packageId}-${keyword}`,
|
|
268
268
|
package_id: packageId,
|
|
269
269
|
label: keyword,
|
|
270
270
|
created_at: new Date(),
|
|
@@ -273,7 +273,7 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
|
|
|
273
273
|
}
|
|
274
274
|
}
|
|
275
275
|
}
|
|
276
|
-
async handleSetPackageDriveId(documentId, action) {
|
|
276
|
+
async handleSetPackageDriveId(documentId, action, state) {
|
|
277
277
|
await this.relationalDb
|
|
278
278
|
.updateTable("builder_packages")
|
|
279
279
|
.set({
|
|
@@ -283,7 +283,7 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
|
|
|
283
283
|
.where("id", "=", action.input.packageId)
|
|
284
284
|
.execute();
|
|
285
285
|
}
|
|
286
|
-
async handleUpdatePackage(documentId, action) {
|
|
286
|
+
async handleUpdatePackage(documentId, action, state) {
|
|
287
287
|
const updates = { updated_at: new Date() };
|
|
288
288
|
if (action.input.title !== undefined) {
|
|
289
289
|
updates.name = action.input.title;
|
|
@@ -297,7 +297,7 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
|
|
|
297
297
|
.where("id", "=", action.input.id)
|
|
298
298
|
.execute();
|
|
299
299
|
}
|
|
300
|
-
async handleReorderPackages(documentId, action) {
|
|
300
|
+
async handleReorderPackages(documentId, action, state) {
|
|
301
301
|
const { ids, insertAfter, spaceId } = action.input;
|
|
302
302
|
for (let i = 0; i < ids.length; i++) {
|
|
303
303
|
const packageId = ids[i];
|
|
@@ -313,7 +313,7 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
|
|
|
313
313
|
.execute();
|
|
314
314
|
}
|
|
315
315
|
}
|
|
316
|
-
async handleDeletePackage(documentId, action) {
|
|
316
|
+
async handleDeletePackage(documentId, action, state) {
|
|
317
317
|
await this.relationalDb
|
|
318
318
|
.deleteFrom("builder_packages")
|
|
319
319
|
.where("id", "=", action.input.id)
|
|
@@ -3,57 +3,9 @@ export const getResolvers = (subgraph) => {
|
|
|
3
3
|
const reactor = subgraph.reactor;
|
|
4
4
|
const db = subgraph.relationalDb;
|
|
5
5
|
return {
|
|
6
|
-
|
|
7
|
-
fetchAllBuilderAccounts: async (parent, args, context) => {
|
|
8
|
-
const driveId = context.driveId || "default";
|
|
9
|
-
const accounts = await VetraReadModelProcessor.query(driveId, db)
|
|
10
|
-
.selectFrom("builder_accounts")
|
|
11
|
-
.selectAll()
|
|
12
|
-
.execute();
|
|
13
|
-
return accounts.map((account) => ({
|
|
14
|
-
id: account.id,
|
|
15
|
-
profileName: account.profile_name,
|
|
16
|
-
profileSlug: account.profile_slug,
|
|
17
|
-
profileLogo: account.profile_logo,
|
|
18
|
-
profileDescription: account.profile_description,
|
|
19
|
-
profileSocialsX: account.profile_socials_x,
|
|
20
|
-
profileSocialsGithub: account.profile_socials_github,
|
|
21
|
-
profileSocialsWebsite: account.profile_socials_website,
|
|
22
|
-
createdAt: account.created_at.toISOString(),
|
|
23
|
-
updatedAt: account.updated_at.toISOString(),
|
|
24
|
-
spaces: [], // Will be resolved by field resolver
|
|
25
|
-
members: [], // Will be resolved by field resolver
|
|
26
|
-
}));
|
|
27
|
-
},
|
|
28
|
-
fetchBuilderAccount: async (parent, args, context) => {
|
|
29
|
-
const driveId = context.driveId || "default";
|
|
30
|
-
const account = await VetraReadModelProcessor.query(driveId, db)
|
|
31
|
-
.selectFrom("builder_accounts")
|
|
32
|
-
.selectAll()
|
|
33
|
-
.where("id", "=", args.id)
|
|
34
|
-
.executeTakeFirst();
|
|
35
|
-
if (!account) {
|
|
36
|
-
return null;
|
|
37
|
-
}
|
|
38
|
-
return {
|
|
39
|
-
id: account.id,
|
|
40
|
-
profileName: account.profile_name,
|
|
41
|
-
profileSlug: account.profile_slug,
|
|
42
|
-
profileLogo: account.profile_logo,
|
|
43
|
-
profileDescription: account.profile_description,
|
|
44
|
-
profileSocialsX: account.profile_socials_x,
|
|
45
|
-
profileSocialsGithub: account.profile_socials_github,
|
|
46
|
-
profileSocialsWebsite: account.profile_socials_website,
|
|
47
|
-
createdAt: account.created_at.toISOString(),
|
|
48
|
-
updatedAt: account.updated_at.toISOString(),
|
|
49
|
-
spaces: [], // Will be resolved by field resolver
|
|
50
|
-
members: [], // Will be resolved by field resolver
|
|
51
|
-
};
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
BuilderAccount: {
|
|
6
|
+
BuilderAccountType: {
|
|
55
7
|
spaces: async (parent, args, context) => {
|
|
56
|
-
const driveId = context.driveId || "
|
|
8
|
+
const driveId = context.driveId || "powerhouse";
|
|
57
9
|
const spaces = await VetraReadModelProcessor.query(driveId, db)
|
|
58
10
|
.selectFrom("builder_spaces")
|
|
59
11
|
.selectAll()
|
|
@@ -68,11 +20,12 @@ export const getResolvers = (subgraph) => {
|
|
|
68
20
|
sortOrder: space.sort_order,
|
|
69
21
|
createdAt: space.created_at.toISOString(),
|
|
70
22
|
updatedAt: space.updated_at.toISOString(),
|
|
23
|
+
driveId: driveId, // Pass driveId to field resolvers
|
|
71
24
|
packages: [], // Will be resolved by field resolver
|
|
72
25
|
}));
|
|
73
26
|
},
|
|
74
27
|
members: async (parent, args, context) => {
|
|
75
|
-
const driveId = context.driveId || "
|
|
28
|
+
const driveId = context.driveId || "powerhouse";
|
|
76
29
|
const members = await VetraReadModelProcessor.query(driveId, db)
|
|
77
30
|
.selectFrom("builder_account_members")
|
|
78
31
|
.selectAll()
|
|
@@ -88,7 +41,7 @@ export const getResolvers = (subgraph) => {
|
|
|
88
41
|
},
|
|
89
42
|
BuilderSpace: {
|
|
90
43
|
packages: async (parent, args, context) => {
|
|
91
|
-
const driveId = context.driveId || "
|
|
44
|
+
const driveId = parent.driveId || context.driveId || "powerhouse";
|
|
92
45
|
const packages = await VetraReadModelProcessor.query(driveId, db)
|
|
93
46
|
.selectFrom("builder_packages")
|
|
94
47
|
.selectAll()
|
|
@@ -116,7 +69,7 @@ export const getResolvers = (subgraph) => {
|
|
|
116
69
|
},
|
|
117
70
|
BuilderPackage: {
|
|
118
71
|
keywords: async (parent, args, context) => {
|
|
119
|
-
const driveId = context.driveId || "
|
|
72
|
+
const driveId = context.driveId || "powerhouse";
|
|
120
73
|
const keywords = await VetraReadModelProcessor.query(driveId, db)
|
|
121
74
|
.selectFrom("builder_package_keywords")
|
|
122
75
|
.selectAll()
|
|
@@ -130,5 +83,61 @@ export const getResolvers = (subgraph) => {
|
|
|
130
83
|
}));
|
|
131
84
|
},
|
|
132
85
|
},
|
|
86
|
+
Query: {
|
|
87
|
+
fetchAllBuilderAccounts: async (parent, args) => {
|
|
88
|
+
const driveId = args.driveId || "powerhouse";
|
|
89
|
+
const search = args.search;
|
|
90
|
+
let accounts = VetraReadModelProcessor.query(driveId, db)
|
|
91
|
+
.selectFrom("builder_accounts")
|
|
92
|
+
.selectAll();
|
|
93
|
+
if (search) {
|
|
94
|
+
accounts = accounts.where((eb) => {
|
|
95
|
+
return eb("profile_name", "ilike", `%${search}%`)
|
|
96
|
+
.or("profile_slug", "ilike", `%${search}%`)
|
|
97
|
+
.or("profile_description", "ilike", `%${search}%`);
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
const results = await accounts.execute();
|
|
101
|
+
return results.map((account) => ({
|
|
102
|
+
id: account.id,
|
|
103
|
+
profileName: account.profile_name,
|
|
104
|
+
profileSlug: account.profile_slug,
|
|
105
|
+
profileLogo: account.profile_logo,
|
|
106
|
+
profileDescription: account.profile_description,
|
|
107
|
+
profileSocialsX: account.profile_socials_x,
|
|
108
|
+
profileSocialsGithub: account.profile_socials_github,
|
|
109
|
+
profileSocialsWebsite: account.profile_socials_website,
|
|
110
|
+
createdAt: account.created_at.toISOString(),
|
|
111
|
+
updatedAt: account.updated_at.toISOString(),
|
|
112
|
+
driveId: driveId, // Pass driveId to field resolvers
|
|
113
|
+
spaces: [], // Will be resolved by field resolver
|
|
114
|
+
members: [], // Will be resolved by field resolver
|
|
115
|
+
}));
|
|
116
|
+
},
|
|
117
|
+
fetchBuilderAccount: async (parent, args) => {
|
|
118
|
+
const driveId = args.driveId || "powerhouse";
|
|
119
|
+
const account = await VetraReadModelProcessor.query(driveId, db)
|
|
120
|
+
.selectFrom("builder_accounts")
|
|
121
|
+
.selectAll()
|
|
122
|
+
.where("id", "=", args.id)
|
|
123
|
+
.executeTakeFirst();
|
|
124
|
+
if (!account) {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
id: account.id,
|
|
129
|
+
profileName: account.profile_name,
|
|
130
|
+
profileSlug: account.profile_slug,
|
|
131
|
+
profileLogo: account.profile_logo,
|
|
132
|
+
profileDescription: account.profile_description,
|
|
133
|
+
profileSocialsX: account.profile_socials_x,
|
|
134
|
+
profileSocialsGithub: account.profile_socials_github,
|
|
135
|
+
profileSocialsWebsite: account.profile_socials_website,
|
|
136
|
+
createdAt: account.created_at.toISOString(),
|
|
137
|
+
updatedAt: account.updated_at.toISOString(),
|
|
138
|
+
driveId: driveId, // Pass driveId to field resolvers
|
|
139
|
+
};
|
|
140
|
+
},
|
|
141
|
+
},
|
|
133
142
|
};
|
|
134
143
|
};
|
|
@@ -61,9 +61,18 @@ export const schema = gql `
|
|
|
61
61
|
createdAt: String!
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
type BuilderAccountFilter {
|
|
65
|
+
profileName: String
|
|
66
|
+
profileSlug: String
|
|
67
|
+
profileLogo: String
|
|
68
|
+
profileDescription: String
|
|
69
|
+
}
|
|
70
|
+
|
|
64
71
|
type Query {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
72
|
+
fetchAllBuilderAccounts(
|
|
73
|
+
driveId: String
|
|
74
|
+
search: String
|
|
75
|
+
): [BuilderAccountType!]!
|
|
76
|
+
fetchBuilderAccount(driveId: String, id: String!): BuilderAccountType
|
|
68
77
|
}
|
|
69
78
|
`;
|