@powerhousedao/builder-profile 0.0.3 → 0.0.4
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-profile/actions.d.ts +9 -0
- package/dist/document-models/builder-profile/actions.d.ts.map +1 -1
- package/dist/document-models/builder-profile/actions.js +2 -2
- package/dist/document-models/builder-profile/gen/actions.d.ts +3 -3
- package/dist/document-models/builder-profile/gen/actions.d.ts.map +1 -1
- package/dist/document-models/builder-profile/gen/actions.js +1 -1
- package/dist/document-models/builder-profile/gen/builders/actions.d.ts +44 -0
- package/dist/document-models/builder-profile/gen/builders/actions.d.ts.map +1 -0
- package/dist/document-models/builder-profile/gen/builders/creators.d.ts +13 -0
- package/dist/document-models/builder-profile/gen/builders/creators.d.ts.map +1 -0
- package/dist/document-models/builder-profile/gen/builders/creators.js +12 -0
- package/dist/document-models/builder-profile/gen/builders/error.d.ts.map +1 -0
- package/dist/document-models/builder-profile/gen/builders/operations.d.ts +16 -0
- package/dist/document-models/builder-profile/gen/builders/operations.d.ts.map +1 -0
- package/dist/document-models/builder-profile/gen/creators.d.ts +2 -2
- package/dist/document-models/builder-profile/gen/creators.d.ts.map +1 -1
- package/dist/document-models/builder-profile/gen/creators.js +2 -2
- package/dist/document-models/builder-profile/gen/document-model.d.ts.map +1 -1
- package/dist/document-models/builder-profile/gen/document-model.js +121 -22
- package/dist/document-models/builder-profile/gen/document-schema.d.ts +168 -16
- package/dist/document-models/builder-profile/gen/document-schema.d.ts.map +1 -1
- package/dist/document-models/builder-profile/gen/index.d.ts +1 -1
- package/dist/document-models/builder-profile/gen/index.d.ts.map +1 -1
- package/dist/document-models/builder-profile/gen/index.js +1 -1
- package/dist/document-models/builder-profile/gen/ph-factories.d.ts.map +1 -1
- package/dist/document-models/builder-profile/gen/ph-factories.js +8 -0
- package/dist/document-models/builder-profile/gen/reducer.d.ts.map +1 -1
- package/dist/document-models/builder-profile/gen/reducer.js +39 -3
- package/dist/document-models/builder-profile/gen/schema/types.d.ts +55 -0
- package/dist/document-models/builder-profile/gen/schema/types.d.ts.map +1 -1
- package/dist/document-models/builder-profile/gen/schema/zod.d.ts +19 -1
- package/dist/document-models/builder-profile/gen/schema/zod.d.ts.map +1 -1
- package/dist/document-models/builder-profile/gen/schema/zod.js +126 -0
- package/dist/document-models/builder-profile/gen/utils.d.ts.map +1 -1
- package/dist/document-models/builder-profile/gen/utils.js +9 -1
- package/dist/document-models/builder-profile/src/reducers/builders.d.ts +3 -0
- package/dist/document-models/builder-profile/src/reducers/builders.d.ts.map +1 -0
- package/dist/document-models/builder-profile/src/reducers/builders.js +108 -0
- package/dist/document-models/builder-profile/src/tests/{builder.test.d.ts → builders.test.d.ts} +1 -1
- package/dist/document-models/builder-profile/src/tests/builders.test.d.ts.map +1 -0
- package/dist/document-models/builder-profile/src/tests/{builder.test.js → builders.test.js} +1 -1
- package/dist/document-models/document-models.d.ts.map +1 -1
- package/dist/document-models/document-models.js +3 -1
- package/dist/document-models/index.d.ts +0 -4
- package/dist/document-models/index.d.ts.map +1 -1
- package/dist/document-models/index.js +0 -4
- package/dist/editors/builder-profile/components/ContributorsSection.d.ts +8 -0
- package/dist/editors/builder-profile/components/ContributorsSection.d.ts.map +1 -0
- package/dist/editors/builder-profile/components/ContributorsSection.js +177 -0
- package/dist/editors/builder-profile/components/ImageUrlInput.d.ts +9 -0
- package/dist/editors/builder-profile/components/ImageUrlInput.d.ts.map +1 -0
- package/dist/editors/builder-profile/components/ImageUrlInput.js +57 -0
- package/dist/editors/builder-profile/components/LinksSection.d.ts +18 -0
- package/dist/editors/builder-profile/components/LinksSection.d.ts.map +1 -0
- package/dist/editors/builder-profile/components/LinksSection.js +74 -0
- package/dist/editors/builder-profile/components/ProfilePreview.d.ts +7 -0
- package/dist/editors/builder-profile/components/ProfilePreview.d.ts.map +1 -0
- package/dist/editors/builder-profile/components/ProfilePreview.js +55 -0
- package/dist/editors/builder-profile/components/ScopesSection.d.ts +9 -0
- package/dist/editors/builder-profile/components/ScopesSection.d.ts.map +1 -0
- package/dist/editors/builder-profile/components/ScopesSection.js +58 -0
- package/dist/editors/builder-profile/components/SkillsSection.d.ts +9 -0
- package/dist/editors/builder-profile/components/SkillsSection.d.ts.map +1 -0
- package/dist/editors/builder-profile/components/SkillsSection.js +66 -0
- package/dist/editors/builder-profile/editor.d.ts.map +1 -1
- package/dist/editors/builder-profile/editor.js +213 -101
- package/dist/editors/builder-profile/module.js +1 -1
- package/dist/editors/index.d.ts +0 -4
- package/dist/editors/index.d.ts.map +1 -1
- package/dist/editors/index.js +0 -4
- package/dist/index.js +2 -2
- package/dist/powerhouse.manifest.json +9 -4
- package/dist/style.css +745 -29
- package/dist/subgraphs/builder-profile/resolvers.d.ts.map +1 -1
- package/dist/subgraphs/builder-profile/resolvers.js +108 -0
- package/dist/subgraphs/builder-profile/schema.d.ts.map +1 -1
- package/dist/subgraphs/builder-profile/schema.js +118 -1
- package/package.json +24 -20
- package/dist/document-models/builder-profile/gen/builder/actions.d.ts +0 -8
- package/dist/document-models/builder-profile/gen/builder/actions.d.ts.map +0 -1
- package/dist/document-models/builder-profile/gen/builder/creators.d.ts +0 -4
- package/dist/document-models/builder-profile/gen/builder/creators.d.ts.map +0 -1
- package/dist/document-models/builder-profile/gen/builder/creators.js +0 -3
- package/dist/document-models/builder-profile/gen/builder/error.d.ts.map +0 -1
- package/dist/document-models/builder-profile/gen/builder/operations.d.ts +0 -7
- package/dist/document-models/builder-profile/gen/builder/operations.d.ts.map +0 -1
- package/dist/document-models/builder-profile/src/reducers/builder.d.ts +0 -3
- package/dist/document-models/builder-profile/src/reducers/builder.d.ts.map +0 -1
- package/dist/document-models/builder-profile/src/reducers/builder.js +0 -9
- package/dist/document-models/builder-profile/src/tests/builder.test.d.ts.map +0 -1
- /package/dist/document-models/builder-profile/gen/{builder → builders}/actions.js +0 -0
- /package/dist/document-models/builder-profile/gen/{builder → builders}/error.d.ts +0 -0
- /package/dist/document-models/builder-profile/gen/{builder → builders}/error.js +0 -0
- /package/dist/document-models/builder-profile/gen/{builder → builders}/operations.js +0 -0
|
@@ -3,22 +3,148 @@ export const isDefinedNonNullAny = (v) => v !== undefined && v !== null;
|
|
|
3
3
|
export const definedNonNullAnySchema = z
|
|
4
4
|
.any()
|
|
5
5
|
.refine((v) => isDefinedNonNullAny(v));
|
|
6
|
+
export const BuilderScopeSchema = z.enum([
|
|
7
|
+
"ACC",
|
|
8
|
+
"GOVERNANCE_SCOPE",
|
|
9
|
+
"PROTOCOL_SCOPE",
|
|
10
|
+
"STA",
|
|
11
|
+
"STABILITY_SCOPE",
|
|
12
|
+
"SUP",
|
|
13
|
+
"SUPPORT_SCOPE",
|
|
14
|
+
]);
|
|
15
|
+
export const BuilderScopeInputSchema = z.enum([
|
|
16
|
+
"ACC",
|
|
17
|
+
"GOVERNANCE_SCOPE",
|
|
18
|
+
"PROTOCOL_SCOPE",
|
|
19
|
+
"STA",
|
|
20
|
+
"STABILITY_SCOPE",
|
|
21
|
+
"SUP",
|
|
22
|
+
"SUPPORT_SCOPE",
|
|
23
|
+
]);
|
|
24
|
+
export const BuilderSkillSchema = z.enum([
|
|
25
|
+
"BACKEND_DEVELOPMENT",
|
|
26
|
+
"DATA_ENGINEERING",
|
|
27
|
+
"DEVOPS_ENGINEERING",
|
|
28
|
+
"FRONTEND_DEVELOPMENT",
|
|
29
|
+
"FULL_STACK_DEVELOPMENT",
|
|
30
|
+
"QA_TESTING",
|
|
31
|
+
"SECURITY_ENGINEERING",
|
|
32
|
+
"SMART_CONTRACT_DEVELOPMENT",
|
|
33
|
+
"TECHNICAL_WRITING",
|
|
34
|
+
"UI_UX_DESIGN",
|
|
35
|
+
]);
|
|
36
|
+
export const BuilderSkillInputSchema = z.enum([
|
|
37
|
+
"BACKEND_DEVELOPMENT",
|
|
38
|
+
"DATA_ENGINEERING",
|
|
39
|
+
"DEVOPS_ENGINEERING",
|
|
40
|
+
"FRONTEND_DEVELOPMENT",
|
|
41
|
+
"FULL_STACK_DEVELOPMENT",
|
|
42
|
+
"QA_TESTING",
|
|
43
|
+
"SECURITY_ENGINEERING",
|
|
44
|
+
"SMART_CONTRACT_DEVELOPMENT",
|
|
45
|
+
"TECHNICAL_WRITING",
|
|
46
|
+
"UI_UX_DESIGN",
|
|
47
|
+
]);
|
|
48
|
+
export const BuilderStatusSchema = z.enum([
|
|
49
|
+
"ACTIVE",
|
|
50
|
+
"ARCHIVED",
|
|
51
|
+
"COMPLETED",
|
|
52
|
+
"INACTIVE",
|
|
53
|
+
"ON_HOLD",
|
|
54
|
+
]);
|
|
55
|
+
export const BuilderStatusInputSchema = z.enum([
|
|
56
|
+
"ACTIVE",
|
|
57
|
+
"ARCHIVED",
|
|
58
|
+
"COMPLETED",
|
|
59
|
+
"INACTIVE",
|
|
60
|
+
"ON_HOLD",
|
|
61
|
+
]);
|
|
62
|
+
export const TeamTypeSchema = z.enum(["INDIVIDUAL", "TEAM"]);
|
|
63
|
+
export const TeamTypeInputSchema = z.enum(["INDIVIDUAL", "TEAM"]);
|
|
64
|
+
export function AddContributorInputSchema() {
|
|
65
|
+
return z.object({
|
|
66
|
+
contributorPHID: z.string(),
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
export function AddLinkInputSchema() {
|
|
70
|
+
return z.object({
|
|
71
|
+
id: z.string(),
|
|
72
|
+
label: z.string().nullish(),
|
|
73
|
+
url: z.string().url(),
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
export function AddScopeInputSchema() {
|
|
77
|
+
return z.object({
|
|
78
|
+
scope: z.lazy(() => BuilderScopeInputSchema.nullish()),
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
export function AddSkillInputSchema() {
|
|
82
|
+
return z.object({
|
|
83
|
+
skill: z.lazy(() => BuilderSkillInputSchema.nullish()),
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
export function BuilderLinkSchema() {
|
|
87
|
+
return z.object({
|
|
88
|
+
__typename: z.literal("BuilderLink").optional(),
|
|
89
|
+
id: z.string(),
|
|
90
|
+
label: z.string().nullable(),
|
|
91
|
+
url: z.string().url(),
|
|
92
|
+
});
|
|
93
|
+
}
|
|
6
94
|
export function BuilderProfileStateSchema() {
|
|
7
95
|
return z.object({
|
|
8
96
|
__typename: z.literal("BuilderProfileState").optional(),
|
|
97
|
+
code: z.string().nullable(),
|
|
98
|
+
contributors: z.array(z.string()),
|
|
9
99
|
description: z.string().nullable(),
|
|
10
100
|
icon: z.string().url().nullable(),
|
|
11
101
|
id: z.string().nullable(),
|
|
102
|
+
lastModified: z.string().datetime().nullable(),
|
|
103
|
+
links: z.array(BuilderLinkSchema()),
|
|
12
104
|
name: z.string().nullable(),
|
|
105
|
+
scopes: z.array(BuilderScopeSchema),
|
|
106
|
+
skilss: z.array(BuilderSkillSchema),
|
|
13
107
|
slug: z.string().nullable(),
|
|
108
|
+
status: BuilderStatusSchema.nullable(),
|
|
109
|
+
type: TeamTypeSchema,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
export function EditLinkInputSchema() {
|
|
113
|
+
return z.object({
|
|
114
|
+
id: z.string(),
|
|
115
|
+
label: z.string().nullish(),
|
|
116
|
+
url: z.string().url(),
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
export function RemoveContributorInputSchema() {
|
|
120
|
+
return z.object({
|
|
121
|
+
contributorPHID: z.string(),
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
export function RemoveLinkInputSchema() {
|
|
125
|
+
return z.object({
|
|
126
|
+
id: z.string(),
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
export function RemoveScopeInputSchema() {
|
|
130
|
+
return z.object({
|
|
131
|
+
scope: z.lazy(() => BuilderScopeInputSchema.nullish()),
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
export function RemoveSkillInputSchema() {
|
|
135
|
+
return z.object({
|
|
136
|
+
skill: z.lazy(() => BuilderSkillInputSchema.nullish()),
|
|
14
137
|
});
|
|
15
138
|
}
|
|
16
139
|
export function UpdateProfileInputSchema() {
|
|
17
140
|
return z.object({
|
|
141
|
+
code: z.string().nullish(),
|
|
18
142
|
description: z.string().nullish(),
|
|
19
143
|
icon: z.string().url().nullish(),
|
|
20
144
|
id: z.string().nullish(),
|
|
21
145
|
name: z.string().nullish(),
|
|
22
146
|
slug: z.string().nullish(),
|
|
147
|
+
status: z.lazy(() => BuilderStatusInputSchema.nullish()),
|
|
148
|
+
type: z.lazy(() => TeamTypeInputSchema.nullish()),
|
|
23
149
|
});
|
|
24
150
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../document-models/builder-profile/gen/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAQzD,OAAO,KAAK,EACV,yBAAyB,EACzB,wBAAwB,EACzB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAUxD,eAAO,MAAM,kBAAkB,EAAE,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../document-models/builder-profile/gen/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAQzD,OAAO,KAAK,EACV,yBAAyB,EACzB,wBAAwB,EACzB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAUxD,eAAO,MAAM,kBAAkB,EAAE,yBAchC,CAAC;AACF,eAAO,MAAM,iBAAiB,EAAE,wBAA6B,CAAC;AAE9D,eAAO,MAAM,KAAK,EAAE,kBAAkB,CAAC,qBAAqB,CAqC3D,CAAC;AAEF,eAAO,MAAM,cAAc,gEAAuB,CAAC;AACnD,eAAO,MAAM,WAAW,6DAAoB,CAAC;AAC7C,eAAO,MAAM,gBAAgB,2CAAyB,CAAC;AACvD,eAAO,MAAM,aAAa,+DAAsB,CAAC;AACjD,eAAO,MAAM,aAAa,+DAAsB,CAAC;AACjD,eAAO,MAAM,mBAAmB,qEAA4B,CAAC;AAC7D,eAAO,MAAM,gBAAgB,kEAAyB,CAAC;AACvD,eAAO,MAAM,sBAAsB,wEAA+B,CAAC"}
|
|
@@ -4,14 +4,22 @@ import { builderProfileDocumentType } from "./document-type.js";
|
|
|
4
4
|
import { isBuilderProfileDocument, assertIsBuilderProfileDocument, isBuilderProfileState, assertIsBuilderProfileState, } from "./document-schema.js";
|
|
5
5
|
export const initialGlobalState = {
|
|
6
6
|
id: null,
|
|
7
|
+
code: null,
|
|
7
8
|
slug: null,
|
|
8
9
|
name: null,
|
|
9
10
|
icon: null,
|
|
10
11
|
description: null,
|
|
12
|
+
lastModified: null,
|
|
13
|
+
type: "INDIVIDUAL",
|
|
14
|
+
contributors: [],
|
|
15
|
+
status: null,
|
|
16
|
+
skilss: [],
|
|
17
|
+
scopes: [],
|
|
18
|
+
links: [],
|
|
11
19
|
};
|
|
12
20
|
export const initialLocalState = {};
|
|
13
21
|
export const utils = {
|
|
14
|
-
fileExtension: "
|
|
22
|
+
fileExtension: "",
|
|
15
23
|
createState(state) {
|
|
16
24
|
return {
|
|
17
25
|
...defaultBaseState(),
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builders.d.ts","sourceRoot":"","sources":["../../../../../document-models/builder-profile/src/reducers/builders.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,gEAAgE,CAAC;AAEvH,eAAO,MAAM,gCAAgC,EAAE,gCAyG5C,CAAC"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
export const builderProfileBuildersOperations = {
|
|
2
|
+
updateProfileOperation(state, action) {
|
|
3
|
+
if (action.input.id)
|
|
4
|
+
state.id = action.input.id;
|
|
5
|
+
if (action.input.code)
|
|
6
|
+
state.code = action.input.code;
|
|
7
|
+
if (action.input.slug)
|
|
8
|
+
state.slug = action.input.slug;
|
|
9
|
+
if (action.input.name)
|
|
10
|
+
state.name = action.input.name;
|
|
11
|
+
if (action.input.icon)
|
|
12
|
+
state.icon = action.input.icon;
|
|
13
|
+
if (action.input.description)
|
|
14
|
+
state.description = action.input.description;
|
|
15
|
+
if (action.input.status)
|
|
16
|
+
state.status = action.input.status;
|
|
17
|
+
if (action.input.type)
|
|
18
|
+
state.type = action.input.type;
|
|
19
|
+
// Convert UTC timestamp (ms) to ISO string for storage
|
|
20
|
+
state.lastModified = new Date(action.timestampUtcMs).toISOString();
|
|
21
|
+
},
|
|
22
|
+
addSkillOperation(state, action) {
|
|
23
|
+
if (action.input.skill) {
|
|
24
|
+
if (!state.skilss.includes(action.input.skill)) {
|
|
25
|
+
state.skilss.push(action.input.skill);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
// Convert UTC timestamp (ms) to ISO string for storage
|
|
29
|
+
state.lastModified = new Date(action.timestampUtcMs).toISOString();
|
|
30
|
+
},
|
|
31
|
+
removeSkillOperation(state, action) {
|
|
32
|
+
if (action.input.skill) {
|
|
33
|
+
const index = state.skilss.indexOf(action.input.skill);
|
|
34
|
+
if (index !== -1) {
|
|
35
|
+
state.skilss.splice(index, 1);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// Convert UTC timestamp (ms) to ISO string for storage
|
|
39
|
+
state.lastModified = new Date(action.timestampUtcMs).toISOString();
|
|
40
|
+
},
|
|
41
|
+
addScopeOperation(state, action) {
|
|
42
|
+
if (action.input.scope) {
|
|
43
|
+
if (!state.scopes.includes(action.input.scope)) {
|
|
44
|
+
state.scopes.push(action.input.scope);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Convert UTC timestamp (ms) to ISO string for storage
|
|
48
|
+
state.lastModified = new Date(action.timestampUtcMs).toISOString();
|
|
49
|
+
},
|
|
50
|
+
removeScopeOperation(state, action) {
|
|
51
|
+
if (action.input.scope) {
|
|
52
|
+
const index = state.scopes.indexOf(action.input.scope);
|
|
53
|
+
if (index !== -1) {
|
|
54
|
+
state.scopes.splice(index, 1);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Convert UTC timestamp (ms) to ISO string for storage
|
|
58
|
+
state.lastModified = new Date(action.timestampUtcMs).toISOString();
|
|
59
|
+
},
|
|
60
|
+
addLinkOperation(state, action) {
|
|
61
|
+
const newLink = {
|
|
62
|
+
id: action.input.id,
|
|
63
|
+
url: action.input.url,
|
|
64
|
+
label: action.input.label || null,
|
|
65
|
+
};
|
|
66
|
+
state.links.push(newLink);
|
|
67
|
+
// Convert UTC timestamp (ms) to ISO string for storage
|
|
68
|
+
state.lastModified = new Date(action.timestampUtcMs).toISOString();
|
|
69
|
+
},
|
|
70
|
+
editLinkOperation(state, action) {
|
|
71
|
+
const linkIndex = state.links.findIndex((link) => link.id === action.input.id);
|
|
72
|
+
if (linkIndex !== -1) {
|
|
73
|
+
if (action.input.url)
|
|
74
|
+
state.links[linkIndex].url = action.input.url;
|
|
75
|
+
if (action.input.label)
|
|
76
|
+
state.links[linkIndex].label = action.input.label;
|
|
77
|
+
}
|
|
78
|
+
// Convert UTC timestamp (ms) to ISO string for storage
|
|
79
|
+
state.lastModified = new Date(action.timestampUtcMs).toISOString();
|
|
80
|
+
},
|
|
81
|
+
removeLinkOperation(state, action) {
|
|
82
|
+
const linkIndex = state.links.findIndex((link) => link.id === action.input.id);
|
|
83
|
+
if (linkIndex !== -1) {
|
|
84
|
+
state.links.splice(linkIndex, 1);
|
|
85
|
+
}
|
|
86
|
+
// Convert UTC timestamp (ms) to ISO string for storage
|
|
87
|
+
state.lastModified = new Date(action.timestampUtcMs).toISOString();
|
|
88
|
+
},
|
|
89
|
+
addContributorOperation(state, action) {
|
|
90
|
+
if (action.input.contributorPHID) {
|
|
91
|
+
if (!state.contributors.includes(action.input.contributorPHID)) {
|
|
92
|
+
state.contributors.push(action.input.contributorPHID);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// Convert UTC timestamp (ms) to ISO string for storage
|
|
96
|
+
state.lastModified = new Date(action.timestampUtcMs).toISOString();
|
|
97
|
+
},
|
|
98
|
+
removeContributorOperation(state, action) {
|
|
99
|
+
if (action.input.contributorPHID) {
|
|
100
|
+
const index = state.contributors.indexOf(action.input.contributorPHID);
|
|
101
|
+
if (index !== -1) {
|
|
102
|
+
state.contributors.splice(index, 1);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Convert UTC timestamp (ms) to ISO string for storage
|
|
106
|
+
state.lastModified = new Date(action.timestampUtcMs).toISOString();
|
|
107
|
+
},
|
|
108
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builders.test.d.ts","sourceRoot":"","sources":["../../../../../document-models/builder-profile/src/tests/builders.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { describe, it, expect } from "vitest";
|
|
6
6
|
import { generateMock } from "@powerhousedao/codegen";
|
|
7
7
|
import { reducer, utils, isBuilderProfileDocument, updateProfile, UpdateProfileInputSchema, } from "@powerhousedao/builder-profile/document-models/builder-profile";
|
|
8
|
-
describe("
|
|
8
|
+
describe("Builders Operations", () => {
|
|
9
9
|
it("should handle updateProfile operation", () => {
|
|
10
10
|
const document = utils.createDocument();
|
|
11
11
|
const input = generateMock(UpdateProfileInputSchema());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document-models.d.ts","sourceRoot":"","sources":["../../document-models/document-models.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAG1D,eAAO,MAAM,cAAc,EAAE,mBAAmB,CAAC,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"document-models.d.ts","sourceRoot":"","sources":["../../document-models/document-models.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAG1D,eAAO,MAAM,cAAc,EAAE,mBAAmB,CAAC,GAAG,CAAC,EAEpD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../document-models/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../document-models/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface ContributorsSectionProps {
|
|
2
|
+
contributors: string[];
|
|
3
|
+
onAddContributor: (contributorPHID: string) => void;
|
|
4
|
+
onRemoveContributor: (contributorPHID: string) => void;
|
|
5
|
+
}
|
|
6
|
+
export declare function ContributorsSection({ contributors, onAddContributor, onRemoveContributor, }: ContributorsSectionProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=ContributorsSection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContributorsSection.d.ts","sourceRoot":"","sources":["../../../../editors/builder-profile/components/ContributorsSection.tsx"],"names":[],"mappings":"AAyBA,UAAU,wBAAwB;IAChC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,gBAAgB,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,mBAAmB,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,IAAI,CAAC;CACxD;AAED,wBAAgB,mBAAmB,CAAC,EAClC,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,GACpB,EAAE,wBAAwB,2CA+O1B"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo, useCallback } from "react";
|
|
3
|
+
import { useDrives, useGetDocuments } from "@powerhousedao/reactor-browser";
|
|
4
|
+
import { ObjectSetTable, PHIDInput, } from "@powerhousedao/document-engineering";
|
|
5
|
+
export function ContributorsSection({ contributors, onAddContributor, onRemoveContributor, }) {
|
|
6
|
+
const drives = useDrives();
|
|
7
|
+
// Map all builder profile FileNodes from all drives with their driveId
|
|
8
|
+
const builderProfileNodesWithDriveId = useMemo(() => {
|
|
9
|
+
if (!drives)
|
|
10
|
+
return [];
|
|
11
|
+
return drives.flatMap((drive) => {
|
|
12
|
+
const builderProfileNodes = drive.state.global.nodes.filter((node) => node.kind === "file" &&
|
|
13
|
+
"documentType" in node &&
|
|
14
|
+
node.documentType === "powerhouse/builder-profile");
|
|
15
|
+
return builderProfileNodes.map((node) => ({
|
|
16
|
+
node,
|
|
17
|
+
driveId: drive.header.id,
|
|
18
|
+
}));
|
|
19
|
+
});
|
|
20
|
+
}, [drives]);
|
|
21
|
+
// Get all unique builder PHIDs from the nodes
|
|
22
|
+
const builderPhids = useMemo(() => {
|
|
23
|
+
return builderProfileNodesWithDriveId.map(({ node }) => node.id);
|
|
24
|
+
}, [builderProfileNodesWithDriveId]);
|
|
25
|
+
// Fetch all builder profile documents from all drives
|
|
26
|
+
const builderProfileDocuments = useGetDocuments(builderPhids);
|
|
27
|
+
// Create a map of PHID to document for quick lookup
|
|
28
|
+
const builderProfileMap = useMemo(() => {
|
|
29
|
+
const map = new Map();
|
|
30
|
+
if (!builderProfileDocuments)
|
|
31
|
+
return map;
|
|
32
|
+
builderProfileDocuments.forEach((doc) => {
|
|
33
|
+
if (doc.header.documentType === "powerhouse/builder-profile") {
|
|
34
|
+
map.set(doc.header.id, doc);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
return map;
|
|
38
|
+
}, [builderProfileDocuments]);
|
|
39
|
+
// Helper function to get builder profile documents from all drives
|
|
40
|
+
const getBuilderProfiles = useCallback(() => {
|
|
41
|
+
return builderProfileNodesWithDriveId.map(({ node }) => {
|
|
42
|
+
const doc = builderProfileMap.get(node.id);
|
|
43
|
+
const name = doc?.state?.global?.name || node.name || node.id;
|
|
44
|
+
return {
|
|
45
|
+
id: node.id,
|
|
46
|
+
label: name,
|
|
47
|
+
value: node.id,
|
|
48
|
+
title: name,
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
}, [builderProfileNodesWithDriveId, builderProfileMap]);
|
|
52
|
+
// Helper function to get builder profile data by PHID from all drives
|
|
53
|
+
const getBuilderProfileByPhid = useCallback((phid) => {
|
|
54
|
+
const doc = builderProfileMap.get(phid);
|
|
55
|
+
if (!doc)
|
|
56
|
+
return null;
|
|
57
|
+
return {
|
|
58
|
+
name: doc.state.global?.name || doc.header.id,
|
|
59
|
+
slug: doc.state.global?.slug || doc.header.id,
|
|
60
|
+
icon: doc.state.global?.icon || null,
|
|
61
|
+
};
|
|
62
|
+
}, [builderProfileMap]);
|
|
63
|
+
const contributorData = useMemo(() => {
|
|
64
|
+
return contributors.map((phid) => {
|
|
65
|
+
const profile = getBuilderProfileByPhid(phid);
|
|
66
|
+
return {
|
|
67
|
+
phid: phid,
|
|
68
|
+
name: profile?.name || "",
|
|
69
|
+
slug: profile?.slug || "",
|
|
70
|
+
icon: profile?.icon || null,
|
|
71
|
+
};
|
|
72
|
+
});
|
|
73
|
+
}, [contributors, getBuilderProfileByPhid]);
|
|
74
|
+
const columns = useMemo(() => [
|
|
75
|
+
{
|
|
76
|
+
field: "phid",
|
|
77
|
+
title: "PHID",
|
|
78
|
+
editable: true,
|
|
79
|
+
align: "center",
|
|
80
|
+
width: 200,
|
|
81
|
+
onSave: (newValue, context) => {
|
|
82
|
+
const currentId = context.row.phid || "";
|
|
83
|
+
if (newValue !== currentId && newValue && currentId) {
|
|
84
|
+
// First remove the old contributor
|
|
85
|
+
onRemoveContributor(currentId);
|
|
86
|
+
// Then add the new contributor with the new PHID
|
|
87
|
+
onAddContributor(newValue);
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
return false;
|
|
91
|
+
},
|
|
92
|
+
renderCellEditor: (value, onChange, context) => (_jsx(PHIDInput, { value: value || "", onChange: (newValue) => {
|
|
93
|
+
onChange(newValue);
|
|
94
|
+
}, onBlur: (e) => {
|
|
95
|
+
const newValue = e.target.value;
|
|
96
|
+
const currentValue = value || "";
|
|
97
|
+
// If a PHID is entered and it's different from current value
|
|
98
|
+
if (newValue && newValue !== currentValue) {
|
|
99
|
+
const existingContributor = contributors.find((contributor) => contributor === newValue);
|
|
100
|
+
if (!existingContributor) {
|
|
101
|
+
// If we're editing an existing row (has an ID), remove the old one first
|
|
102
|
+
if (context.row.phid && context.row.phid !== newValue) {
|
|
103
|
+
onRemoveContributor(context.row.phid);
|
|
104
|
+
}
|
|
105
|
+
// Add the new contributor
|
|
106
|
+
onAddContributor(newValue);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}, placeholder: "Enter PHID", className: "w-full", variant: "withValueAndTitle", initialOptions: getBuilderProfiles(), fetchOptionsCallback: (userInput) => {
|
|
110
|
+
const builderProfiles = getBuilderProfiles();
|
|
111
|
+
// Filter profiles based on user input
|
|
112
|
+
if (!userInput.trim()) {
|
|
113
|
+
return Promise.resolve(builderProfiles);
|
|
114
|
+
}
|
|
115
|
+
const filteredProfiles = builderProfiles.filter((profile) => profile.label
|
|
116
|
+
.toLowerCase()
|
|
117
|
+
.includes(userInput.toLowerCase()) ||
|
|
118
|
+
profile.id.toLowerCase().includes(userInput.toLowerCase()));
|
|
119
|
+
return Promise.resolve(filteredProfiles);
|
|
120
|
+
} })),
|
|
121
|
+
renderCell: (value) => {
|
|
122
|
+
if (value === "" || !value) {
|
|
123
|
+
return (_jsx("div", { className: "font-light italic text-gray-500 text-center", children: "+ Double-click to add new contributor (enter or click outside to save)" }));
|
|
124
|
+
}
|
|
125
|
+
return _jsx("div", { className: "text-center font-mono text-sm", children: value });
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
field: "name",
|
|
130
|
+
title: "Name",
|
|
131
|
+
editable: false,
|
|
132
|
+
align: "center",
|
|
133
|
+
width: 200,
|
|
134
|
+
renderCell: (value) => {
|
|
135
|
+
return _jsx("div", { className: "text-center", children: value });
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
field: "slug",
|
|
140
|
+
title: "Slug",
|
|
141
|
+
editable: false,
|
|
142
|
+
align: "center",
|
|
143
|
+
width: 200,
|
|
144
|
+
renderCell: (value) => {
|
|
145
|
+
return _jsx("div", { className: "text-center", children: value });
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
field: "icon",
|
|
150
|
+
title: "Icon",
|
|
151
|
+
editable: false,
|
|
152
|
+
align: "center",
|
|
153
|
+
width: 150,
|
|
154
|
+
renderCell: (_value, context) => {
|
|
155
|
+
if (!context.row.icon) {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
return (_jsx("div", { className: "text-center", children: _jsx("img", { src: context.row.icon, alt: "Contributor icon", className: "w-10 h-10 rounded-sm mx-auto object-cover", onError: (e) => {
|
|
159
|
+
e.currentTarget.style.display = "none";
|
|
160
|
+
} }) }));
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
], [contributors, getBuilderProfiles, onAddContributor, onRemoveContributor]);
|
|
164
|
+
return (_jsxs("div", { className: "bg-white rounded-lg p-6 shadow-sm", children: [_jsx("h3", { className: "text-lg font-medium text-gray-900 mb-4", children: "Contributors" }), _jsx("p", { className: "text-sm text-gray-600 mb-4", children: "Add team members to your builder profile. Search for existing builder profiles by name or PHID." }), _jsx(ObjectSetTable, { columns: columns, data: contributorData, allowRowSelection: true, onDelete: (data) => {
|
|
165
|
+
if (data.length > 0) {
|
|
166
|
+
data.forEach((d) => {
|
|
167
|
+
onRemoveContributor(d.phid);
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}, onAdd: (data) => {
|
|
171
|
+
// Only add if we have a PHID
|
|
172
|
+
const phid = data.id;
|
|
173
|
+
if (phid) {
|
|
174
|
+
onAddContributor(phid);
|
|
175
|
+
}
|
|
176
|
+
} })] }));
|
|
177
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
interface ImageUrlInputProps {
|
|
2
|
+
label: string;
|
|
3
|
+
value: string;
|
|
4
|
+
onChange: (value: string) => void;
|
|
5
|
+
placeholder?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function ImageUrlInput({ label, value, onChange, placeholder, }: ImageUrlInputProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=ImageUrlInput.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ImageUrlInput.d.ts","sourceRoot":"","sources":["../../../../editors/builder-profile/components/ImageUrlInput.tsx"],"names":[],"mappings":"AA0EA,UAAU,kBAAkB;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,KAAK,EACL,QAAQ,EACR,WAAW,GACZ,EAAE,kBAAkB,2CA4FpB"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useEffect } from "react";
|
|
3
|
+
import { TextInput, Icon } from "@powerhousedao/document-engineering";
|
|
4
|
+
function ImageModal({ isOpen, onClose, imageUrl, imageAlt }) {
|
|
5
|
+
const [imageLoaded, setImageLoaded] = useState(false);
|
|
6
|
+
const [imageDimensions, setImageDimensions] = useState({
|
|
7
|
+
width: 0,
|
|
8
|
+
height: 0,
|
|
9
|
+
});
|
|
10
|
+
if (!isOpen)
|
|
11
|
+
return null;
|
|
12
|
+
const handleImageLoad = (e) => {
|
|
13
|
+
const img = e.target;
|
|
14
|
+
setImageDimensions({ width: img.naturalWidth, height: img.naturalHeight });
|
|
15
|
+
setImageLoaded(true);
|
|
16
|
+
};
|
|
17
|
+
const getModalSize = () => {
|
|
18
|
+
if (!imageLoaded)
|
|
19
|
+
return { width: "auto", height: "auto" };
|
|
20
|
+
const maxWidth = Math.min(imageDimensions.width + 100, window.innerWidth * 0.8);
|
|
21
|
+
const maxHeight = Math.min(imageDimensions.height + 100, window.innerHeight * 0.8);
|
|
22
|
+
return {
|
|
23
|
+
width: `${maxWidth}px`,
|
|
24
|
+
height: `${maxHeight}px`,
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
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: "Xmark", 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 }) })] }) }));
|
|
28
|
+
}
|
|
29
|
+
export function ImageUrlInput({ label, value, onChange, placeholder, }) {
|
|
30
|
+
const [imageError, setImageError] = useState(false);
|
|
31
|
+
const [isModalOpen, setIsModalOpen] = useState(false);
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
setImageError(false);
|
|
34
|
+
}, [value]);
|
|
35
|
+
const handleImageClick = () => {
|
|
36
|
+
if (value &&
|
|
37
|
+
!imageError &&
|
|
38
|
+
(value.startsWith("http://") || value.startsWith("https://"))) {
|
|
39
|
+
setIsModalOpen(true);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "space-y-2", children: [_jsx("label", { className: "block text-sm font-medium text-gray-700", children: label }), _jsxs("div", { className: "border border-gray-300 rounded-lg p-4", children: [_jsx("div", { className: "flex items-center justify-between", children: _jsxs("div", { className: "flex items-center space-x-3", children: [_jsx("div", { className: `flex-shrink-0 w-12 h-12 bg-gray-100 rounded border flex items-center justify-center overflow-hidden ${value &&
|
|
43
|
+
!imageError &&
|
|
44
|
+
(value.startsWith("http://") || value.startsWith("https://"))
|
|
45
|
+
? "cursor-pointer hover:opacity-80 transition-opacity duration-200"
|
|
46
|
+
: ""}`, onClick: handleImageClick, children: value &&
|
|
47
|
+
!imageError &&
|
|
48
|
+
(value.startsWith("http://") ||
|
|
49
|
+
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" })) }), _jsx("div", { className: "flex-1 min-w-0", children: _jsxs("div", { className: "text-xs text-gray-500", children: [imageError && value && (_jsx("div", { className: "text-red-500", children: "Failed to load image" })), value &&
|
|
50
|
+
!imageError &&
|
|
51
|
+
(value.startsWith("http://") ||
|
|
52
|
+
value.startsWith("https://")) && (_jsx("div", { className: "text-blue-600", children: "Click image to view full size" }))] }) })] }) }), _jsx("div", { className: "mt-3", children: _jsx(TextInput, { className: "w-full", defaultValue: value || "", onBlur: (e) => {
|
|
53
|
+
if (e.target.value !== value) {
|
|
54
|
+
onChange(e.target.value);
|
|
55
|
+
}
|
|
56
|
+
}, placeholder: placeholder || "Enter image URL" }) })] })] }), _jsx(ImageModal, { isOpen: isModalOpen, onClose: () => setIsModalOpen(false), imageUrl: value, imageAlt: `${label} full size` })] }));
|
|
57
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { BuilderLink } from "../../../document-models/builder-profile/gen/types.js";
|
|
2
|
+
interface LinksSectionProps {
|
|
3
|
+
links: BuilderLink[];
|
|
4
|
+
onAddLink: (link: {
|
|
5
|
+
id: string;
|
|
6
|
+
url: string;
|
|
7
|
+
label?: string;
|
|
8
|
+
}) => void;
|
|
9
|
+
onEditLink: (link: {
|
|
10
|
+
id: string;
|
|
11
|
+
url: string;
|
|
12
|
+
label?: string;
|
|
13
|
+
}) => void;
|
|
14
|
+
onRemoveLink: (id: string) => void;
|
|
15
|
+
}
|
|
16
|
+
export declare function LinksSection({ links, onAddLink, onEditLink, onRemoveLink, }: LinksSectionProps): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=LinksSection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LinksSection.d.ts","sourceRoot":"","sources":["../../../../editors/builder-profile/components/LinksSection.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uDAAuD,CAAC;AAEzF,UAAU,iBAAiB;IACzB,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,SAAS,EAAE,CAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACvE,UAAU,EAAE,CAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACxE,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC;AAYD,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,SAAS,EACT,UAAU,EACV,YAAY,GACb,EAAE,iBAAiB,2CAgOnB"}
|