@powerhousedao/network-admin 0.0.53 → 0.0.55

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.
@@ -1 +1 @@
1
- {"version":3,"file":"network-profile-management.d.ts","sourceRoot":"","sources":["../../../../../document-models/network-profile/src/reducers/network-profile-management.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gDAAgD,EAAE,MAAM,8DAA8D,CAAC;AAErI,eAAO,MAAM,gDAAgD,EAAE,gDAmC5D,CAAC"}
1
+ {"version":3,"file":"network-profile-management.d.ts","sourceRoot":"","sources":["../../../../../document-models/network-profile/src/reducers/network-profile-management.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gDAAgD,EAAE,MAAM,8DAA8D,CAAC;AAErI,eAAO,MAAM,gDAAgD,EAAE,gDA6C5D,CAAC"}
@@ -1,9 +1,19 @@
1
1
  export const networkProfileNetworkProfileManagementOperations = {
2
2
  setIconOperation(state, action) {
3
- state.icon = action.input.icon || "";
3
+ if (action.input.icon !== undefined) {
4
+ state.icon = action.input.icon || "";
5
+ }
6
+ if (action.input.darkThemeIcon !== undefined) {
7
+ state.darkThemeIcon = action.input.darkThemeIcon || "";
8
+ }
4
9
  },
5
10
  setLogoOperation(state, action) {
6
- state.logo = action.input.logo || "";
11
+ if (action.input.logo !== undefined) {
12
+ state.logo = action.input.logo || "";
13
+ }
14
+ if (action.input.darkThemeLogo !== undefined) {
15
+ state.darkThemeLogo = action.input.darkThemeLogo || "";
16
+ }
7
17
  },
8
18
  setLogoBigOperation(state, action) {
9
19
  state.logoBig = action.input.logoBig || "";
@@ -1 +1 @@
1
- {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../editors/network-profile/editor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAoBlD,MAAM,MAAM,MAAM,GAAG,WAAW,CAAC;AA+RjC,MAAM,CAAC,OAAO,UAAU,MAAM,mDAoR7B"}
1
+ {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../editors/network-profile/editor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAoBlD,MAAM,MAAM,MAAM,GAAG,WAAW,CAAC;AAgSjC,MAAM,CAAC,OAAO,UAAU,MAAM,mDA+Q7B"}
@@ -42,12 +42,20 @@ function ImageModal({ isOpen, onClose, imageUrl, imageAlt, }) {
42
42
  return (_jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center backdrop-blur-sm", onClick: onClose, children: _jsxs("div", { className: "relative bg-gray-900 rounded-lg shadow-2xl border-2 border-gray-700", style: getModalSize(), children: [_jsx("button", { onClick: onClose, className: "absolute -top-3 -right-3 z-10 w-8 h-8 bg-gray-800 hover:bg-gray-900 rounded-full flex items-center justify-center text-white transition-all duration-200 shadow-lg", children: _jsx(Icon, { name: "ArrowLeft", size: 16 }) }), _jsx("div", { className: "w-full h-full flex items-center justify-center p-8", children: _jsx("img", { src: imageUrl, alt: imageAlt, className: `max-w-full max-h-full object-contain rounded-lg ${imageLoaded ? "opacity-100" : "opacity-0"} transition-opacity duration-200`, onClick: (e) => e.stopPropagation(), onLoad: handleImageLoad }) })] }) }));
43
43
  }
44
44
  // Image URL input component with preview
45
- function ImageUrlInput({ label, value, onChange, placeholder, fileSize = "200KB", }) {
45
+ function ImageUrlInput({ label, value, onChange, placeholder, }) {
46
46
  const [imageError, setImageError] = useState(false);
47
47
  const [isModalOpen, setIsModalOpen] = useState(false);
48
- // Reset image error when value changes
48
+ // Initialize with the current value prop to ensure it's set correctly on mount
49
+ const [inputValue, setInputValue] = useState(() => value || "");
50
+ // Sync input value with prop value when it changes externally
51
+ // This is important when toggling between light/dark modes or when state updates
52
+ useEffect(() => {
53
+ setInputValue(value || "");
54
+ }, [value]);
55
+ // Reset image error when value changes (important for dark mode toggle and new URLs)
49
56
  useEffect(() => {
50
57
  setImageError(false);
58
+ // Force image reload by clearing any cached error state
51
59
  }, [value]);
52
60
  const handleImageClick = () => {
53
61
  if (value &&
@@ -63,10 +71,12 @@ function ImageUrlInput({ label, value, onChange, placeholder, fileSize = "200KB"
63
71
  : ""}`, onClick: handleImageClick, children: value &&
64
72
  !imageError &&
65
73
  (value.startsWith("http://") ||
66
- value.startsWith("https://")) ? (_jsx("img", { src: value, alt: `${label} preview`, className: "w-full h-full object-cover", onError: () => setImageError(true), onLoad: () => setImageError(false) })) : (_jsx(Icon, { name: "Image", size: 24, className: "text-gray-400" })) }), _jsxs("div", { className: "flex-1", children: [_jsx("div", { className: "text-sm font-medium text-gray-900", children: value || placeholder || `${label.replace(":", "")}.jpg` }), _jsxs("div", { className: "text-xs text-gray-500", children: ["File Type: jpg | File Size: ", value ? fileSize : "0KB", imageError && value && (_jsx("div", { className: "text-red-500 mt-1", children: "\u26A0 Failed to load image" })), value &&
74
+ value.startsWith("https://")) ? (_jsx("img", { src: value, alt: `${label} preview`, className: "w-full h-full object-cover", onError: () => setImageError(true), onLoad: () => setImageError(false) }, value)) : (_jsx(Icon, { name: "Image", size: 24, className: "text-gray-400" })) }), _jsxs("div", { className: "flex-1", children: [_jsx("div", { className: "text-sm font-medium text-gray-900", children: value || placeholder || `${label.replace(":", "")}.jpg` }), _jsxs("div", { className: "text-xs text-gray-500", children: [imageError && value && (_jsx("div", { className: "text-red-500 mt-1", children: "\u26A0 Failed to load image" })), value &&
67
75
  !imageError &&
68
76
  (value.startsWith("http://") ||
69
- value.startsWith("https://")) && (_jsx("div", { className: "text-blue-600 mt-1", children: "\uD83D\uDCA1 Click image to view full size" }))] })] })] }), _jsx("div", { className: "flex-shrink-0", children: _jsx("div", { className: "w-6 h-6 rounded-full bg-gray-200 flex items-center justify-center", children: _jsx(Icon, { name: "Image", size: 16, className: "text-gray-600" }) }) })] }), _jsx("div", { className: "mt-3", children: _jsx(TextInput, { className: "w-full", defaultValue: value || "", onBlur: (e) => {
77
+ value.startsWith("https://")) && (_jsx("div", { className: "text-blue-600 mt-1", children: "\uD83D\uDCA1 Click image to view full size" }))] })] })] }), _jsx("div", { className: "flex-shrink-0", children: _jsx("div", { className: "w-6 h-6 rounded-full bg-gray-200 flex items-center justify-center", children: _jsx(Icon, { name: "Image", size: 16, className: "text-gray-600" }) }) })] }), _jsx("div", { className: "mt-3", children: _jsx("input", { type: "text", className: "w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500", value: inputValue, onChange: (e) => {
78
+ setInputValue(e.target.value);
79
+ }, onBlur: (e) => {
70
80
  if (e.target.value !== value) {
71
81
  onChange(e.target.value);
72
82
  }
@@ -75,7 +85,7 @@ function ImageUrlInput({ label, value, onChange, placeholder, fileSize = "200KB"
75
85
  // Toggle-enabled image input component for light/dark theme switching
76
86
  function ToggleableImageInput({ label, lightValue, darkValue, onLightChange, onDarkChange, lightPlaceholder, darkPlaceholder, fileSize = "200KB", }) {
77
87
  const [isDarkMode, setIsDarkMode] = useState(false);
78
- return (_jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex items-center justify-between mb-2", children: [_jsx("label", { className: "block text-sm font-medium text-gray-700", children: label }), _jsxs("div", { className: "flex items-center space-x-2", children: [_jsx("span", { className: `text-xs font-medium ${!isDarkMode ? "text-gray-900" : "text-gray-500"}`, children: "Light" }), _jsx("button", { type: "button", onClick: () => setIsDarkMode(!isDarkMode), className: `relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 ${isDarkMode ? "bg-gray-700" : "bg-gray-300"}`, children: _jsx("span", { className: `inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${isDarkMode ? "translate-x-6" : "translate-x-1"}` }) }), _jsx("span", { className: `text-xs font-medium ${isDarkMode ? "text-gray-900" : "text-gray-500"}`, children: "Dark" })] })] }), !isDarkMode ? (_jsx(ImageUrlInput, { label: "", value: lightValue, onChange: onLightChange, placeholder: lightPlaceholder, fileSize: fileSize })) : (_jsx(ImageUrlInput, { label: "", value: darkValue, onChange: onDarkChange, placeholder: darkPlaceholder, fileSize: fileSize }))] }));
88
+ return (_jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex items-center justify-between mb-2", children: [_jsx("label", { className: "block text-sm font-medium text-gray-700", children: label }), _jsxs("div", { className: "flex items-center space-x-2", children: [_jsx("span", { className: `text-xs font-medium ${!isDarkMode ? "text-gray-900" : "text-gray-500"}`, children: "Light" }), _jsx("button", { type: "button", onClick: () => setIsDarkMode(!isDarkMode), className: `relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 ${isDarkMode ? "bg-gray-700" : "bg-gray-300"}`, children: _jsx("span", { className: `inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${isDarkMode ? "translate-x-6" : "translate-x-1"}` }) }), _jsx("span", { className: `text-xs font-medium ${isDarkMode ? "text-gray-900" : "text-gray-500"}`, children: "Dark" })] })] }), _jsx(ImageUrlInput, { label: "", value: isDarkMode ? darkValue : lightValue, onChange: isDarkMode ? onDarkChange : onLightChange, placeholder: isDarkMode ? darkPlaceholder : lightPlaceholder }, isDarkMode ? "dark" : "light")] }));
79
89
  }
80
90
  export default function Editor() {
81
91
  // Getting dispatch from selected document
@@ -101,24 +111,20 @@ export default function Editor() {
101
111
  case "icon":
102
112
  action = actions.setIcon({
103
113
  icon: value,
104
- darkThemeIcon: state?.darkThemeIcon || "",
105
114
  });
106
115
  break;
107
116
  case "darkThemeIcon":
108
117
  action = actions.setIcon({
109
- icon: state?.icon || "",
110
118
  darkThemeIcon: value,
111
119
  });
112
120
  break;
113
121
  case "logo":
114
122
  action = actions.setLogo({
115
123
  logo: value,
116
- darkThemeLogo: state?.darkThemeLogo || "",
117
124
  });
118
125
  break;
119
126
  case "darkThemeLogo":
120
127
  action = actions.setLogo({
121
- logo: state?.logo || "",
122
128
  darkThemeLogo: value,
123
129
  });
124
130
  break;
@@ -164,7 +170,7 @@ export default function Editor() {
164
170
  if (e.target.value !== state?.name) {
165
171
  handleFieldChange("name", e.target.value);
166
172
  }
167
- }, placeholder: "Enter network name" })] }), _jsx(ToggleableImageInput, { label: "Icon:", lightValue: state?.icon || "", darkValue: state?.darkThemeIcon || "", onLightChange: (value) => handleFieldChange("icon", value), onDarkChange: (value) => handleFieldChange("darkThemeIcon", value), lightPlaceholder: "PowerhouseIcon.jpg", darkPlaceholder: "PowerhouseIconDark.jpg", fileSize: "200KB" }), _jsx(ToggleableImageInput, { label: "Logo:", lightValue: state?.logo || "", darkValue: state?.darkThemeLogo || "", onLightChange: (value) => handleFieldChange("logo", value), onDarkChange: (value) => handleFieldChange("darkThemeLogo", value), lightPlaceholder: "PowerhouseLogo.jpg", darkPlaceholder: "PowerhouseLogoDark.jpg", fileSize: "2MB" }), _jsx(ImageUrlInput, { label: "Large Logo:", value: state?.logoBig || "", onChange: (value) => handleFieldChange("logoBig", value), placeholder: "LargeLogo.jpg", fileSize: "10MB" }), _jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "Website:" }), _jsx(TextInput, { className: "w-full", defaultValue: state?.website || "", onBlur: (e) => {
173
+ }, placeholder: "Enter network name" })] }), _jsx(ToggleableImageInput, { label: "Icon:", lightValue: state?.icon || "", darkValue: state?.darkThemeIcon || "", onLightChange: (value) => handleFieldChange("icon", value), onDarkChange: (value) => handleFieldChange("darkThemeIcon", value), lightPlaceholder: "icon.jpg", darkPlaceholder: "icon-dark.jpg", fileSize: "200KB" }), _jsx(ToggleableImageInput, { label: "Logo:", lightValue: state?.logo || "", darkValue: state?.darkThemeLogo || "", onLightChange: (value) => handleFieldChange("logo", value), onDarkChange: (value) => handleFieldChange("darkThemeLogo", value), lightPlaceholder: "logo.jpg", darkPlaceholder: "logo-dark.jpg", fileSize: "2MB" }), _jsx(ImageUrlInput, { label: "Large Logo:", value: state?.logoBig || "", onChange: (value) => handleFieldChange("logoBig", value), placeholder: "LargeLogo.jpg" }), _jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "Website:" }), _jsx(TextInput, { className: "w-full", defaultValue: state?.website || "", onBlur: (e) => {
168
174
  const value = e.target.value || null;
169
175
  if (value !== state?.website) {
170
176
  handleFieldChange("website", value);
package/dist/style.css CHANGED
@@ -1423,6 +1423,11 @@
1423
1423
  }
1424
1424
  }
1425
1425
  }
1426
+ .focus\:border-blue-500 {
1427
+ &:focus {
1428
+ border-color: var(--color-blue-500);
1429
+ }
1430
+ }
1426
1431
  .focus\:ring-2 {
1427
1432
  &:focus {
1428
1433
  --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
@@ -2296,6 +2301,7 @@
2296
2301
  "Courier New", monospace;
2297
2302
  --color-red-50: oklch(97.1% 0.013 17.38);
2298
2303
  --color-red-100: hsl(3 82% 96%);
2304
+ --color-red-300: hsl(6 82% 87%);
2299
2305
  --color-red-500: hsl(5 80% 78%);
2300
2306
  --color-red-600: hsl(4 81% 74%);
2301
2307
  --color-orange-500: hsl(33 99% 70%);
@@ -2371,6 +2377,7 @@
2371
2377
  --tracking-wider: 0.05em;
2372
2378
  --leading-relaxed: 1.625;
2373
2379
  --radius-sm: 0.25rem;
2380
+ --radius-md: 0.375rem;
2374
2381
  --radius-lg: 0.5rem;
2375
2382
  --radius-xl: 0.75rem;
2376
2383
  --radius-2xl: 1rem;
@@ -2584,6 +2591,9 @@
2584
2591
  .mt-1 {
2585
2592
  margin-top: calc(var(--spacing) * 1);
2586
2593
  }
2594
+ .mt-2 {
2595
+ margin-top: calc(var(--spacing) * 2);
2596
+ }
2587
2597
  .mt-3 {
2588
2598
  margin-top: calc(var(--spacing) * 3);
2589
2599
  }
@@ -2620,6 +2630,9 @@
2620
2630
  .inline-flex {
2621
2631
  display: inline-flex;
2622
2632
  }
2633
+ .table {
2634
+ display: table;
2635
+ }
2623
2636
  .h-2 {
2624
2637
  height: calc(var(--spacing) * 2);
2625
2638
  }
@@ -2689,6 +2702,9 @@
2689
2702
  .flex-shrink-0 {
2690
2703
  flex-shrink: 0;
2691
2704
  }
2705
+ .border-collapse {
2706
+ border-collapse: collapse;
2707
+ }
2692
2708
  .-translate-y-1\/2 {
2693
2709
  --tw-translate-y: calc(calc(1/2 * 100%) * -1);
2694
2710
  translate: var(--tw-translate-x) var(--tw-translate-y);
@@ -2705,6 +2721,9 @@
2705
2721
  .grid-cols-1 {
2706
2722
  grid-template-columns: repeat(1, minmax(0, 1fr));
2707
2723
  }
2724
+ .flex-col {
2725
+ flex-direction: column;
2726
+ }
2708
2727
  .flex-wrap {
2709
2728
  flex-wrap: wrap;
2710
2729
  }
@@ -2783,6 +2802,9 @@
2783
2802
  .rounded-lg {
2784
2803
  border-radius: var(--radius-lg);
2785
2804
  }
2805
+ .rounded-md {
2806
+ border-radius: var(--radius-md);
2807
+ }
2786
2808
  .rounded-sm {
2787
2809
  border-radius: var(--radius-sm);
2788
2810
  }
@@ -2824,6 +2846,9 @@
2824
2846
  .border-indigo-100 {
2825
2847
  border-color: var(--color-indigo-100);
2826
2848
  }
2849
+ .border-red-300 {
2850
+ border-color: var(--color-red-300);
2851
+ }
2827
2852
  .border-slate-100 {
2828
2853
  border-color: var(--color-slate-100);
2829
2854
  }
@@ -2899,6 +2924,9 @@
2899
2924
  .bg-purple-500 {
2900
2925
  background-color: var(--color-purple-500);
2901
2926
  }
2927
+ .bg-red-50 {
2928
+ background-color: var(--color-red-50);
2929
+ }
2902
2930
  .bg-red-500 {
2903
2931
  background-color: var(--color-red-500);
2904
2932
  }
@@ -3090,6 +3118,10 @@
3090
3118
  font-size: var(--text-xs);
3091
3119
  line-height: var(--tw-leading, var(--text-xs--line-height));
3092
3120
  }
3121
+ .leading-4 {
3122
+ --tw-leading: calc(var(--spacing) * 4);
3123
+ line-height: calc(var(--spacing) * 4);
3124
+ }
3093
3125
  .leading-relaxed {
3094
3126
  --tw-leading: var(--leading-relaxed);
3095
3127
  line-height: var(--leading-relaxed);
@@ -3157,6 +3189,9 @@
3157
3189
  .text-red-500 {
3158
3190
  color: var(--color-red-500);
3159
3191
  }
3192
+ .text-red-600 {
3193
+ color: var(--color-red-600);
3194
+ }
3160
3195
  .text-sky-700 {
3161
3196
  color: var(--color-sky-700);
3162
3197
  }
@@ -3217,6 +3252,10 @@
3217
3252
  --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
3218
3253
  box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
3219
3254
  }
3255
+ .blur {
3256
+ --tw-blur: blur(8px);
3257
+ filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
3258
+ }
3220
3259
  .backdrop-blur-sm {
3221
3260
  --tw-backdrop-blur: blur(var(--blur-sm));
3222
3261
  -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
@@ -3469,6 +3508,19 @@
3469
3508
  --tw-ring-offset-width: 0px;
3470
3509
  --tw-ring-offset-color: #fff;
3471
3510
  --tw-ring-offset-shadow: 0 0 #0000;
3511
+ --tw-blur: initial;
3512
+ --tw-brightness: initial;
3513
+ --tw-contrast: initial;
3514
+ --tw-grayscale: initial;
3515
+ --tw-hue-rotate: initial;
3516
+ --tw-invert: initial;
3517
+ --tw-opacity: initial;
3518
+ --tw-saturate: initial;
3519
+ --tw-sepia: initial;
3520
+ --tw-drop-shadow: initial;
3521
+ --tw-drop-shadow-color: initial;
3522
+ --tw-drop-shadow-alpha: 100%;
3523
+ --tw-drop-shadow-size: initial;
3472
3524
  --tw-backdrop-blur: initial;
3473
3525
  --tw-backdrop-brightness: initial;
3474
3526
  --tw-backdrop-contrast: initial;
@@ -0,0 +1,11 @@
1
+ import { BaseSubgraph } from "@powerhousedao/reactor-api";
2
+ import type { DocumentNode } from "graphql";
3
+ export declare class BuildersAddonSubgraph extends BaseSubgraph {
4
+ name: string;
5
+ typeDefs: DocumentNode;
6
+ resolvers: Record<string, unknown>;
7
+ additionalContextFields: {};
8
+ onSetup(): Promise<void>;
9
+ onDisconnect(): Promise<void>;
10
+ }
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../subgraphs/builders-addon/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAI5C,qBAAa,qBAAsB,SAAQ,YAAY;IACrD,IAAI,SAAoB;IACxB,QAAQ,EAAE,YAAY,CAAU;IAChC,SAAS,0BAAsB;IAC/B,uBAAuB,KAAM;IACvB,OAAO;IACP,YAAY;CACnB"}
@@ -0,0 +1,11 @@
1
+ import { BaseSubgraph } from "@powerhousedao/reactor-api";
2
+ import { schema } from "./schema.js";
3
+ import { getResolvers } from "./resolvers.js";
4
+ export class BuildersAddonSubgraph extends BaseSubgraph {
5
+ name = "builders-addon";
6
+ typeDefs = schema;
7
+ resolvers = getResolvers(this);
8
+ additionalContextFields = {};
9
+ async onSetup() { }
10
+ async onDisconnect() { }
11
+ }
@@ -0,0 +1,3 @@
1
+ import { type ISubgraph } from "@powerhousedao/reactor-api";
2
+ export declare const getResolvers: (subgraph: ISubgraph) => Record<string, unknown>;
3
+ //# sourceMappingURL=resolvers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolvers.d.ts","sourceRoot":"","sources":["../../../subgraphs/builders-addon/resolvers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAc5D,eAAO,MAAM,YAAY,GAAI,UAAU,SAAS,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CA4UxE,CAAC"}
@@ -0,0 +1,280 @@
1
+ import {} from "@powerhousedao/reactor-api";
2
+ export const getResolvers = (subgraph) => {
3
+ const reactor = subgraph.reactor;
4
+ const extractPhid = (value) => {
5
+ if (typeof value === "string") {
6
+ return value.trim() || null;
7
+ }
8
+ if (value &&
9
+ typeof value === "object" &&
10
+ "id" in value &&
11
+ typeof value.id === "string") {
12
+ const id = value.id;
13
+ return id.trim() || null;
14
+ }
15
+ return null;
16
+ };
17
+ const getCandidateDrives = async () => {
18
+ try {
19
+ const drives = await reactor.getDrives?.();
20
+ if (Array.isArray(drives) && drives.length > 0)
21
+ return drives;
22
+ }
23
+ catch { }
24
+ return [];
25
+ };
26
+ const applyFilters = (builder, filter) => {
27
+ if (!filter)
28
+ return true;
29
+ if (filter.id && builder.id !== filter.id)
30
+ return false;
31
+ if (filter.code &&
32
+ String(builder.code || "").toLowerCase() !==
33
+ String(filter.code || "").toLowerCase())
34
+ return false;
35
+ if (filter.name &&
36
+ String(builder.name || "").toLowerCase() !==
37
+ String(filter.name || "").toLowerCase())
38
+ return false;
39
+ if (filter.slug &&
40
+ String(builder.slug || "").toLowerCase() !==
41
+ String(filter.slug || "").toLowerCase())
42
+ return false;
43
+ if (filter.type &&
44
+ String(builder.type || "").toLowerCase() !==
45
+ String(filter.type || "").toLowerCase())
46
+ return false;
47
+ if (filter.status &&
48
+ String(builder.status || "").toLowerCase() !==
49
+ String(filter.status || "").toLowerCase())
50
+ return false;
51
+ if (filter.skills && filter.skills.length > 0) {
52
+ const builderSkills = (builder.skils || []).map((s) => String(s).toLowerCase());
53
+ const hasAllSkills = filter.skills.every((skill) => builderSkills.includes(String(skill).toLowerCase()));
54
+ if (!hasAllSkills)
55
+ return false;
56
+ }
57
+ if (filter.scopes && filter.scopes.length > 0) {
58
+ const builderScopes = (builder.scopes || []).map((s) => String(s).toLowerCase());
59
+ const hasAllScopes = filter.scopes.every((scope) => builderScopes.includes(String(scope).toLowerCase()));
60
+ if (!hasAllScopes)
61
+ return false;
62
+ }
63
+ return true;
64
+ };
65
+ return {
66
+ Query: {
67
+ builders: async (parent, args) => {
68
+ const filter = args.filter;
69
+ const drives = await getCandidateDrives();
70
+ // Step 1: Collect all builder profile documents
71
+ const builderDocs = [];
72
+ const sowDocs = [];
73
+ for (const driveId of drives) {
74
+ try {
75
+ const docIds = await reactor.getDocuments(driveId);
76
+ const docs = await Promise.all(docIds.map(async (docId) => {
77
+ try {
78
+ return await reactor.getDocument(docId);
79
+ }
80
+ catch {
81
+ return null;
82
+ }
83
+ }));
84
+ for (const doc of docs) {
85
+ if (!doc)
86
+ continue;
87
+ if (doc.header.documentType === "powerhouse/builder-profile") {
88
+ builderDocs.push(doc);
89
+ }
90
+ else if (doc.header.documentType === "powerhouse/scopeofwork") {
91
+ sowDocs.push(doc);
92
+ }
93
+ }
94
+ }
95
+ catch (error) {
96
+ console.warn(`Failed to process drive ${driveId}:`, error);
97
+ }
98
+ }
99
+ // Step 2: Build a map of deliverable OID -> deliverable object for each SOW
100
+ const sowDeliverablesMap = new Map();
101
+ for (const sowDoc of sowDocs) {
102
+ const sowState = sowDoc.state.global;
103
+ if (!sowState || typeof sowState !== "object")
104
+ continue;
105
+ const deliverablesMap = new Map();
106
+ const deliverables = Array.isArray(sowState.deliverables)
107
+ ? sowState.deliverables
108
+ : [];
109
+ for (const deliverable of deliverables) {
110
+ if (!deliverable || typeof deliverable !== "object")
111
+ continue;
112
+ const deliverableId = deliverable.id;
113
+ if (deliverableId && typeof deliverableId === "string") {
114
+ deliverablesMap.set(deliverableId, deliverable);
115
+ }
116
+ }
117
+ sowDeliverablesMap.set(sowDoc.header.id, deliverablesMap);
118
+ }
119
+ // Step 3: Extract projects from SOW documents and group by projectOwner
120
+ const projectsByOwner = new Map();
121
+ for (const sowDoc of sowDocs) {
122
+ const sowState = sowDoc.state.global;
123
+ if (!sowState || typeof sowState !== "object")
124
+ continue;
125
+ if (!Array.isArray(sowState.projects))
126
+ continue;
127
+ const deliverablesMap = sowDeliverablesMap.get(sowDoc.header.id) || new Map();
128
+ for (const project of sowState.projects) {
129
+ if (!project || typeof project !== "object")
130
+ continue;
131
+ const ownerPhid = extractPhid(project.projectOwner);
132
+ if (!ownerPhid)
133
+ continue;
134
+ // Resolve scope deliverables from OIDs to actual deliverable objects
135
+ let resolvedScope = null;
136
+ if (project.scope && typeof project.scope === "object") {
137
+ try {
138
+ const scopeDeliverableOids = Array.isArray(project.scope.deliverables)
139
+ ? project.scope.deliverables
140
+ : [];
141
+ const resolvedDeliverables = scopeDeliverableOids
142
+ .map((oid) => {
143
+ if (!oid || typeof oid !== "string")
144
+ return null;
145
+ const deliverable = deliverablesMap.get(oid);
146
+ if (!deliverable || typeof deliverable !== "object")
147
+ return null;
148
+ // Transform to SOW_Deliverable format with error handling
149
+ try {
150
+ return {
151
+ id: deliverable.id || "",
152
+ icon: deliverable.icon ?? null,
153
+ title: String(deliverable.title || ""),
154
+ code: String(deliverable.code || ""),
155
+ description: String(deliverable.description || ""),
156
+ status: deliverable.status || "DRAFT",
157
+ workProgress: deliverable.workProgress ?? null,
158
+ keyResults: Array.isArray(deliverable.keyResults)
159
+ ? deliverable.keyResults.map((kr) => ({
160
+ id: kr?.id || "",
161
+ title: String(kr?.title || ""),
162
+ link: String(kr?.link || ""),
163
+ }))
164
+ : [],
165
+ budgetAnchor: deliverable.budgetAnchor ?? null,
166
+ };
167
+ }
168
+ catch (error) {
169
+ console.warn(`Failed to transform deliverable ${oid}:`, error);
170
+ return null;
171
+ }
172
+ })
173
+ .filter((d) => d !== null);
174
+ // Build resolved scope with error handling
175
+ resolvedScope = {
176
+ deliverables: resolvedDeliverables,
177
+ status: project.scope.status ||
178
+ project.scope.deliverableSetStatus ||
179
+ "DRAFT",
180
+ progress: project.scope.progress ?? null,
181
+ deliverablesCompleted: project.scope.deliverablesCompleted ?? {
182
+ total: 0,
183
+ completed: 0,
184
+ },
185
+ };
186
+ }
187
+ catch (error) {
188
+ console.warn(`Failed to resolve scope for project ${project.id}:`, error);
189
+ // Fallback to empty scope
190
+ resolvedScope = {
191
+ deliverables: [],
192
+ status: "DRAFT",
193
+ progress: null,
194
+ deliverablesCompleted: { total: 0, completed: 0 },
195
+ };
196
+ }
197
+ }
198
+ // Transform project to BuilderProject format with error handling
199
+ try {
200
+ const builderProject = {
201
+ id: project.id || "",
202
+ code: String(project.code || ""),
203
+ title: String(project.title || ""),
204
+ slug: String(project.slug || ""),
205
+ abstract: project.abstract ?? null,
206
+ imageUrl: project.imageUrl ?? null,
207
+ scope: resolvedScope,
208
+ budgetType: project.budgetType ?? null,
209
+ currency: project.currency ?? null,
210
+ budget: project.budget ?? null,
211
+ expenditure: project.expenditure ?? null,
212
+ };
213
+ if (!projectsByOwner.has(ownerPhid)) {
214
+ projectsByOwner.set(ownerPhid, []);
215
+ }
216
+ projectsByOwner.get(ownerPhid).push(builderProject);
217
+ }
218
+ catch (error) {
219
+ console.warn(`Failed to transform project ${project.id}:`, error);
220
+ // Skip this project if transformation fails
221
+ continue;
222
+ }
223
+ }
224
+ }
225
+ // Step 4: Transform builder documents to BuilderProfileState format
226
+ const builders = builderDocs
227
+ .map((doc) => {
228
+ const state = doc.state.global;
229
+ // Ensure all non-nullable fields are properly handled
230
+ const name = String(state?.name ?? doc.header?.name ?? "");
231
+ const icon = String(state?.icon ?? "");
232
+ const description = String(state?.description ?? state?.slug ?? "");
233
+ const type = state?.type ?? "INDIVIDUAL";
234
+ const skils = Array.isArray(state?.skils) ? state.skils : [];
235
+ const scopes = Array.isArray(state?.scopes) ? state.scopes : [];
236
+ const links = Array.isArray(state?.links) ? state.links : [];
237
+ const contributors = Array.isArray(state?.contributors)
238
+ ? state.contributors
239
+ : [];
240
+ const builder = {
241
+ id: doc.header.id,
242
+ code: state?.code ?? null,
243
+ slug: state?.slug ?? null,
244
+ name,
245
+ icon,
246
+ description,
247
+ lastModified: state?.lastModified ?? null,
248
+ type,
249
+ contributors,
250
+ status: state?.status ?? null,
251
+ skils,
252
+ scopes,
253
+ links,
254
+ projects: projectsByOwner.get(doc.header.id) || [],
255
+ };
256
+ return builder;
257
+ })
258
+ .filter((builder) => applyFilters(builder, filter));
259
+ return builders;
260
+ },
261
+ },
262
+ SOW_Progress: {
263
+ __resolveType(obj) {
264
+ if (obj && typeof obj === "object") {
265
+ if (Object.prototype.hasOwnProperty.call(obj, "total") &&
266
+ Object.prototype.hasOwnProperty.call(obj, "completed")) {
267
+ return "SOW_StoryPoint";
268
+ }
269
+ if (Object.prototype.hasOwnProperty.call(obj, "value")) {
270
+ return "SOW_Percentage";
271
+ }
272
+ if (Object.prototype.hasOwnProperty.call(obj, "done")) {
273
+ return "SOW_Binary";
274
+ }
275
+ }
276
+ return null;
277
+ },
278
+ },
279
+ };
280
+ };
@@ -0,0 +1,3 @@
1
+ import type { DocumentNode } from "graphql";
2
+ export declare const schema: DocumentNode;
3
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../subgraphs/builders-addon/schema.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,eAAO,MAAM,MAAM,EAAE,YA+MpB,CAAC"}
@@ -0,0 +1,209 @@
1
+ import { gql } from "graphql-tag";
2
+ export const schema = gql `
3
+ """
4
+ Subgraph definition
5
+ """
6
+ type Query {
7
+ builders(filter: buildersFilter): [BuilderProfileState!]!
8
+ }
9
+
10
+ ## Filters
11
+
12
+ input buildersFilter {
13
+ id: PHID
14
+ code: String
15
+ name: String
16
+ slug: String
17
+ type: teamType
18
+ status: BuilderStatus
19
+ skills: [BuilderSkill!]
20
+ scopes: [BuilderScope!]
21
+ }
22
+
23
+
24
+
25
+
26
+ ## Builder Profile Schema
27
+ type BuilderProfileState {
28
+ id: PHID
29
+ code: String
30
+ slug: String
31
+ name: String
32
+ icon: URL
33
+ description: String
34
+ lastModified: DateTime
35
+ type: teamType!
36
+ contributors: [PHID!]!
37
+ status: BuilderStatus
38
+ skils: [BuilderSkill!]!
39
+ scopes: [BuilderScope!]!
40
+ links: [BuilderLink!]!
41
+ projects: [BuilderProject!]!
42
+ }
43
+
44
+ enum teamType {
45
+ INDIVIDUAL
46
+ TEAM
47
+ }
48
+
49
+ enum BuilderStatus {
50
+ ACTIVE
51
+ INACTIVE
52
+ ON_HOLD
53
+ COMPLETED
54
+ ARCHIVED
55
+ }
56
+
57
+ enum BuilderSkill {
58
+ FRONTEND_DEVELOPMENT
59
+ BACKEND_DEVELOPMENT
60
+ FULL_STACK_DEVELOPMENT
61
+ DEVOPS_ENGINEERING
62
+ SMART_CONTRACT_DEVELOPMENT
63
+ UI_UX_DESIGN
64
+ TECHNICAL_WRITING
65
+ QA_TESTING
66
+ DATA_ENGINEERING
67
+ SECURITY_ENGINEERING
68
+ }
69
+
70
+ enum BuilderScope {
71
+ ACC
72
+ STA
73
+ SUP
74
+ STABILITY_SCOPE
75
+ SUPPORT_SCOPE
76
+ PROTOCOL_SCOPE
77
+ GOVERNANCE_SCOPE
78
+ }
79
+
80
+ type BuilderLink {
81
+ id: OID!
82
+ url: URL!
83
+ label: String
84
+ }
85
+
86
+ type Builder {
87
+ id: PHID
88
+ code: String
89
+ slug: String
90
+ name: String!
91
+ icon: String!
92
+ description: String!
93
+ lastModified: DateTime
94
+ type: teamType!
95
+ contributors: [Builder!]!
96
+ status: BuilderStatus
97
+ skils: [BuilderSkill!]!
98
+ scopes: [BuilderScope!]!
99
+ links: [BuilderLink!]!
100
+ }
101
+
102
+ type BuilderProject {
103
+ id: OID!
104
+ code: String!
105
+ title: String!
106
+ slug: String!
107
+ abstract: String
108
+ imageUrl: URL
109
+ scope: Builder_SOW_DeliverablesSet
110
+ budgetType: SOW_BudgetType
111
+ currency: SOW_PMCurrency
112
+ budget: Float
113
+ expenditure: SOW_BudgetExpenditure
114
+ }
115
+
116
+ type Builder_SOW_DeliverablesSet {
117
+ deliverables: [BuilderSOW_Deliverable!]!
118
+ status: SOW_DeliverableSetStatus!
119
+ progress: SOW_Progress!
120
+ deliverablesCompleted: SOW_DeliverablesCompleted!
121
+ }
122
+
123
+ type BuilderSOW_Deliverable {
124
+ id: OID!
125
+ icon: String
126
+ title: String!
127
+ code: String!
128
+ description: String!
129
+ status: SOW_DeliverableStatus!
130
+ workProgress: SOW_Progress
131
+ keyResults: [SOW_KeyResult!]!
132
+ budgetAnchor: SOW_BudgetAnchorProject
133
+ }
134
+
135
+ enum SOW_DeliverableStatus {
136
+ WONT_DO
137
+ DRAFT
138
+ TODO
139
+ BLOCKED
140
+ IN_PROGRESS
141
+ DELIVERED
142
+ CANCELED
143
+ }
144
+
145
+ type SOW_KeyResult {
146
+ id: OID!
147
+ title: String!
148
+ link: String!
149
+ }
150
+
151
+ type SOW_BudgetAnchorProject {
152
+ project: OID
153
+ unit: SOW_Unit
154
+ unitCost: Float!
155
+ quantity: Float!
156
+ margin: Float!
157
+ }
158
+
159
+ enum SOW_Unit {
160
+ StoryPoints
161
+ Hours
162
+ }
163
+
164
+ enum SOW_BudgetType {
165
+ CONTINGENCY
166
+ OPEX
167
+ CAPEX
168
+ OVERHEAD
169
+ }
170
+
171
+ enum SOW_PMCurrency {
172
+ DAI
173
+ USDS
174
+ EUR
175
+ USD
176
+ }
177
+
178
+ enum SOW_DeliverableSetStatus {
179
+ DRAFT
180
+ TODO
181
+ IN_PROGRESS
182
+ FINISHED
183
+ CANCELED
184
+ }
185
+
186
+ type SOW_DeliverablesCompleted {
187
+ total: Int!
188
+ completed: Int!
189
+ }
190
+
191
+ type SOW_BudgetExpenditure {
192
+ percentage: Float!
193
+ actuals: Float!
194
+ cap: Float!
195
+ }
196
+
197
+ union SOW_Progress = SOW_StoryPoint | SOW_Percentage | SOW_Binary
198
+
199
+ type SOW_Percentage {
200
+ value: Float!
201
+ }
202
+ type SOW_Binary {
203
+ done: Boolean
204
+ }
205
+ type SOW_StoryPoint {
206
+ total: Int!
207
+ completed: Int!
208
+ }
209
+ `;
@@ -5,4 +5,5 @@ export * as WorkstreamSubgraph from "./workstream/index.js";
5
5
  export * as WorkstreamsSubgraph from "./workstreams/index.js";
6
6
  export * as NetworksSubgraph from "./networks/index.js";
7
7
  export * as BuildersSubgraph from "./builders/index.js";
8
+ export * as BuildersAddonSubgraph from "./builders-addon/index.js";
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../subgraphs/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,sBAAsB,MAAM,4BAA4B,CAAC;AACrE,OAAO,KAAK,oBAAoB,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,2BAA2B,MAAM,kCAAkC,CAAC;AAChF,OAAO,KAAK,kBAAkB,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,mBAAmB,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,gBAAgB,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,gBAAgB,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../subgraphs/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,sBAAsB,MAAM,4BAA4B,CAAC;AACrE,OAAO,KAAK,oBAAoB,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,2BAA2B,MAAM,kCAAkC,CAAC;AAChF,OAAO,KAAK,kBAAkB,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,mBAAmB,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,gBAAgB,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,gBAAgB,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,qBAAqB,MAAM,2BAA2B,CAAC"}
@@ -5,3 +5,4 @@ export * as WorkstreamSubgraph from "./workstream/index.js";
5
5
  export * as WorkstreamsSubgraph from "./workstreams/index.js";
6
6
  export * as NetworksSubgraph from "./networks/index.js";
7
7
  export * as BuildersSubgraph from "./builders/index.js";
8
+ export * as BuildersAddonSubgraph from "./builders-addon/index.js";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@powerhousedao/network-admin",
3
3
  "description": "Network Admin package for Powerhouse",
4
- "version": "0.0.53",
4
+ "version": "0.0.55",
5
5
  "license": "AGPL-3.0-only",
6
6
  "type": "module",
7
7
  "files": [
@@ -62,7 +62,7 @@
62
62
  "service-unstartup": "bash ./node_modules/@powerhousedao/ph-cli/dist/scripts/service-unstartup.sh"
63
63
  },
64
64
  "dependencies": {
65
- "@powerhousedao/builder-profile": "0.0.5",
65
+ "@powerhousedao/builder-profile": "0.0.6",
66
66
  "@powerhousedao/builder-tools": "^5.0.12",
67
67
  "@powerhousedao/common": "^5.0.12",
68
68
  "@powerhousedao/design-system": "^5.0.12",