@powerhousedao/network-admin 0.0.20 → 0.0.22

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":"DriveExplorer.d.ts","sourceRoot":"","sources":["../../../../editors/network-admin/components/DriveExplorer.tsx"],"names":[],"mappings":"AAuCA;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,GAAG,2CA8jBvC"}
1
+ {"version":3,"file":"DriveExplorer.d.ts","sourceRoot":"","sources":["../../../../editors/network-admin/components/DriveExplorer.tsx"],"names":[],"mappings":"AAuCA;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,GAAG,2CAmoBvC"}
@@ -104,40 +104,88 @@ export function DriveExplorer(props) {
104
104
  const sowDoc = allDocuments?.find((doc) => doc.header.id === sow);
105
105
  const rfpDoc = allDocuments?.find((doc) => doc.header.id === rfp);
106
106
  const pmtDoc = allDocuments?.find((doc) => doc.header.id === paymentTerms);
107
+ // get alternative proposals
108
+ let alternativeProposals = null;
109
+ if (doc.state?.global?.alternativeProposals) {
110
+ alternativeProposals = doc.state?.global
111
+ ?.alternativeProposals;
112
+ }
107
113
  // Only include documents that actually exist
108
- const wstrChildDocs = [sowDoc, rfpDoc, pmtDoc].filter((doc) => doc !== undefined && doc !== null);
109
- return {
114
+ const wstrChildDocs = [rfpDoc].filter((doc) => doc !== undefined && doc !== null);
115
+ const returnableChildren = {
110
116
  id: `editor-${doc.header.id}`,
111
117
  title: `${doc.state?.global?.code ? doc.state?.global?.code + " - " : ""}${doc.state?.global?.title || doc.header.name}`,
112
- children: wstrChildDocs.map((childDoc) => ({
113
- id: `editor-${childDoc.header.id}`,
114
- title: `${childDoc.state?.global?.code ? childDoc.state?.global?.code + " - " : ""}${childDoc.state?.global?.title || childDoc.header.name}`,
115
- })),
118
+ children: wstrChildDocs.map((childDoc) => {
119
+ let dynamicTitle = childDoc?.header.documentType === "powerhouse/rfp"
120
+ ? `Request For Proposal`
121
+ : `${childDoc.state?.global?.code ? childDoc.state?.global?.code + " - " : ""}${childDoc.state?.global?.title || childDoc.header.name}`;
122
+ return {
123
+ id: `editor-${childDoc.header.id}`,
124
+ title: dynamicTitle,
125
+ };
126
+ }),
116
127
  };
128
+ wstrChildDocs.push(sowDoc);
129
+ wstrChildDocs.push(pmtDoc);
130
+ // if sowDoc or pmtDoc is included in the wstrChildDocs, then add a child with the title "Initial Proposal"
131
+ if (wstrChildDocs.includes(sowDoc) ||
132
+ wstrChildDocs.includes(pmtDoc)) {
133
+ returnableChildren.children.push({
134
+ id: "initial-proposal",
135
+ title: "Initial Proposal",
136
+ children: wstrChildDocs
137
+ .filter((childDoc) => childDoc &&
138
+ childDoc.header &&
139
+ (childDoc.header.documentType ===
140
+ "powerhouse/scopeofwork" ||
141
+ childDoc.header.documentType === "payment-terms"))
142
+ .map((childDoc) => {
143
+ let dynamicTitle = childDoc.header.documentType ===
144
+ "powerhouse/scopeofwork"
145
+ ? "Scope of Work"
146
+ : childDoc.header.documentType === "payment-terms"
147
+ ? "Payment Terms"
148
+ : null;
149
+ return {
150
+ id: `editor-${childDoc.header.id}`,
151
+ title: dynamicTitle,
152
+ };
153
+ }),
154
+ });
155
+ }
156
+ if (alternativeProposals.length > 0) {
157
+ returnableChildren.children.push({
158
+ id: "alternative-proposals",
159
+ title: `Alternative Proposals (${alternativeProposals.length})`,
160
+ children: alternativeProposals.map((proposal) => {
161
+ // Find documents for this specific proposal
162
+ const proposalSowDoc = allDocuments?.find((doc) => doc.header.id === proposal.sow);
163
+ const proposalPaymentTermsDoc = allDocuments?.find((doc) => doc.header.id === proposal.paymentTerms);
164
+ // Filter to only include documents that exist
165
+ const proposalChildDocs = [proposalSowDoc, proposalPaymentTermsDoc].filter((doc) => doc !== undefined && doc !== null);
166
+ return {
167
+ id: `alternative-proposal-${proposal.id}`,
168
+ title: `${proposal.author.name}`,
169
+ children: proposalChildDocs.map((childDoc) => {
170
+ let dynamicTitle = childDoc.header.documentType === "powerhouse/scopeofwork"
171
+ ? "Scope of Work"
172
+ : childDoc.header.documentType === "payment-terms"
173
+ ? "Payment Terms"
174
+ : null;
175
+ return {
176
+ id: `editor-${childDoc.header.id}`,
177
+ title: dynamicTitle,
178
+ };
179
+ }),
180
+ };
181
+ }),
182
+ });
183
+ }
184
+ return returnableChildren;
117
185
  }),
118
186
  ],
119
187
  };
120
188
  }),
121
- // // Add workstream documents
122
- // ...workstreamDocs.map((doc) => ({
123
- // id: `editor-${doc.header.id}`,
124
- // title: `${(doc.state as any)?.global?.code || ""} - ${(doc.state as any)?.global?.title || doc.header.name}`,
125
- // })),
126
- // // Add scope of work documents
127
- // ...scopeOfWorkDocs.map((doc) => ({
128
- // id: `editor-${doc.header.id}`,
129
- // title: `${(doc.state as any)?.global?.title || doc.header.name}`,
130
- // })),
131
- // // Add RFP documents
132
- // ...rfpDocs.map((doc) => ({
133
- // id: `editor-${doc.header.id}`,
134
- // title: `${(doc.state as any)?.global?.code || ""} - ${(doc.state as any)?.global?.title || doc.header.name}`,
135
- // })),
136
- // // Add payment terms documents
137
- // ...paymentTermsDocs.map((doc) => ({
138
- // id: `editor-${doc.header.id}`,
139
- // title: `${(doc.state as any)?.global?.code || ""} - ${(doc.state as any)?.global?.title || doc.header.name}`,
140
- // })),
141
189
  ],
142
190
  };
143
191
  const networkInfoNode = {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../editors/network-admin/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAGxE,eAAO,MAAM,MAAM,EAAE,iBAiBpB,CAAC;AAEF,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../editors/network-admin/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAGxE,eAAO,MAAM,MAAM,EAAE,iBAoBpB,CAAC;AAEF,eAAe,MAAM,CAAC"}
@@ -11,6 +11,9 @@ export const module = {
11
11
  // List all document types that can be dropped
12
12
  "powerhouse/network-profile",
13
13
  "powerhouse/workstream",
14
+ "powerhouse/scopeofwork",
15
+ "payment-terms",
16
+ "powerhouse/rfp",
14
17
  ],
15
18
  dragAndDrop: {
16
19
  enabled: true, // Enable drag-and-drop functionality
@@ -1 +1 @@
1
- {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../editors/workstream/editor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAU,WAAW,EAAc,MAAM,gBAAgB,CAAC;AAgCtE,MAAM,MAAM,MAAM,GAAG,WAAW,CAAC;AAejC,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,KAAK,EAAE,GAAG,2CA23BxC"}
1
+ {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../editors/workstream/editor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAU,WAAW,EAAc,MAAM,gBAAgB,CAAC;AAiCtE,MAAM,MAAM,MAAM,GAAG,WAAW,CAAC;AAsBjC,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,KAAK,EAAE,GAAG,2CAuiCxC"}
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Button, toast, ToastContainer } from "@powerhousedao/design-system";
3
- import { TextInput, Select, PHIDInput, Icon, ObjectSetTable, } from "@powerhousedao/document-engineering";
3
+ import { TextInput, Select, OIDInput, Icon, ObjectSetTable, buildEnumCellEditor, } from "@powerhousedao/document-engineering";
4
4
  import { actions, } from "../../document-models/workstream/index.js";
5
5
  import { actions as rfpActions, } from "../../document-models/request-for-proposals/index.js";
6
6
  import { ScopeOfWork } from "@powerhousedao/project-management/document-models";
@@ -19,6 +19,12 @@ const statusOptions = [
19
19
  { value: "IN_PROGRESS", label: "In Progress" },
20
20
  { value: "FINISHED", label: "Finished" },
21
21
  ];
22
+ const statusStyles = {
23
+ DRAFT: "bg-[#fcdfbd] text-[#ffa033] rounded px-2 py-1 font-semibold",
24
+ SUBMITTED: "bg-[#bfdffd] text-[#339cff] rounded px-2 py-1 font-semibold",
25
+ ACCEPTED: "bg-[#c8ecd1] text-[#4fc86f] rounded px-2 py-1 font-semibold",
26
+ REJECTED: "bg-[#ffaea8] text-[#de3333] rounded px-2 py-1 font-semibold",
27
+ };
22
28
  export default function Editor(props) {
23
29
  const [doc, dispatch] = useDocumentById(props.documentId);
24
30
  // Try to get dispatch from context or props
@@ -62,21 +68,17 @@ export default function Editor(props) {
62
68
  // Local state to track newly created RFP document ID
63
69
  const [newlyCreatedRfpId, setNewlyCreatedRfpId] = useState(null);
64
70
  // Local state to track manual input values
65
- const [manualSowInput, setManualSowInput] = useState("");
66
- const [manualPaymentTermsInput, setManualPaymentTermsInput] = useState("");
67
71
  const [manualAuthorInput, setManualAuthorInput] = useState("");
68
72
  // Effect to clear local state when global state is updated
69
73
  useEffect(() => {
70
74
  if (state.initialProposal?.sow && newlyCreatedSowId) {
71
75
  setNewlyCreatedSowId(null);
72
- setManualSowInput("");
73
76
  }
74
77
  }, [state.initialProposal?.sow, newlyCreatedSowId]);
75
78
  // Effect to clear local state when global state is updated
76
79
  useEffect(() => {
77
80
  if (state.initialProposal?.paymentTerms && newlyCreatedPaymentTermsId) {
78
81
  setNewlyCreatedPaymentTermsId(null);
79
- setManualPaymentTermsInput("");
80
82
  }
81
83
  }, [state.initialProposal?.paymentTerms, newlyCreatedPaymentTermsId]);
82
84
  // Effect to clear local state when global state is updated
@@ -93,6 +95,22 @@ export default function Editor(props) {
93
95
  doc.header.id === state.rfp?.id);
94
96
  });
95
97
  }
98
+ // Find SOW document node
99
+ let sowDocumentNode = undefined;
100
+ if (state.initialProposal?.sow) {
101
+ sowDocumentNode = allDocuments?.find((doc) => {
102
+ return (doc.header.documentType === "powerhouse/scopeofwork" &&
103
+ doc.header.id === state.initialProposal?.sow);
104
+ });
105
+ }
106
+ // Find Payment Terms document node
107
+ let paymentTermsDocumentNode = undefined;
108
+ if (state.initialProposal?.paymentTerms) {
109
+ paymentTermsDocumentNode = allDocuments?.find((doc) => {
110
+ return (doc.header.documentType === "payment-terms" &&
111
+ doc.header.id === state.initialProposal?.paymentTerms);
112
+ });
113
+ }
96
114
  // Get RFP document data using useDocumentById hook - always call with stable ID
97
115
  const rfpDocumentId = rfpDocumentNode?.header.id || "";
98
116
  const rfpDocumentData = useDocumentById(rfpDocumentId);
@@ -128,17 +146,44 @@ export default function Editor(props) {
128
146
  rfpDocumentNode.header.id === "") {
129
147
  setRfpDocument((prev) => (prev === undefined ? prev : undefined));
130
148
  }
131
- }, [rfpDocumentNode, rfpDocumentDataState]);
149
+ }, [rfpDocumentNode, rfpDocumentDataState, newlyCreatedRfpId]);
132
150
  const searchRfpDocuments = (userInput) => {
133
- const results = allDocuments?.filter((node) => (node.header.documentType === "powerhouse/rfp" &&
134
- node.header.name.toLowerCase().includes(userInput.toLowerCase())) ||
135
- node.header.id.toLowerCase().includes(userInput.toLowerCase()));
151
+ const results = allDocuments?.filter((node) => node.header.documentType === "powerhouse/rfp" &&
152
+ (!userInput ||
153
+ node.header.name.toLowerCase().includes(userInput.toLowerCase()) ||
154
+ node.header.id.toLowerCase().includes(userInput.toLowerCase())));
136
155
  return results?.map((doc) => ({
137
156
  value: doc.header.id,
138
157
  title: doc.header.name,
139
158
  path: "",
140
159
  }));
141
160
  };
161
+ const searchSowDocuments = (userInput) => {
162
+ const results = allDocuments?.filter((node) => node.header.documentType === "powerhouse/scopeofwork" &&
163
+ (!userInput ||
164
+ node.header.name.toLowerCase().includes(userInput.toLowerCase()) ||
165
+ node.header.id.toLowerCase().includes(userInput.toLowerCase()) ||
166
+ (node.state?.global?.title
167
+ ?.toLowerCase()
168
+ .includes(userInput.toLowerCase()) ??
169
+ false)));
170
+ return results?.map((doc) => ({
171
+ value: doc.header.id,
172
+ title: doc.state?.global?.title || doc.header.name,
173
+ path: "",
174
+ }));
175
+ };
176
+ const searchPaymentTermsDocuments = (userInput) => {
177
+ const results = allDocuments?.filter((node) => node.header.documentType === "payment-terms" &&
178
+ (!userInput ||
179
+ node.header.name.toLowerCase().includes(userInput.toLowerCase()) ||
180
+ node.header.id.toLowerCase().includes(userInput.toLowerCase())));
181
+ return results?.map((doc) => ({
182
+ value: doc.header.id,
183
+ title: doc.state?.global?.title || doc.header.name,
184
+ path: "",
185
+ }));
186
+ };
142
187
  // Handle workstream field changes
143
188
  const handleWorkstreamChange = (field, value) => {
144
189
  if (!dispatch) {
@@ -216,19 +261,20 @@ export default function Editor(props) {
216
261
  editable: true,
217
262
  onSave: (newValue, context) => {
218
263
  if (newValue !== context.row.title) {
219
- // dispatch(
220
- // actions.editDeliverable({
221
- // id: context.row.id,
222
- // title: newValue as string,
223
- // })
224
- // );
264
+ dispatch(actions.editAlternativeProposal({
265
+ id: context.row.id,
266
+ proposalAuthor: {
267
+ id: context.row.authorId,
268
+ name: newValue,
269
+ },
270
+ }));
225
271
  return true;
226
272
  }
227
273
  return false;
228
274
  },
229
275
  renderCell: (value, context) => {
230
- if (value === "") {
231
- return (_jsx("div", { className: "font-light italic text-left text-gray-500", children: "+ Double-click to add new author" }));
276
+ if (value === undefined) {
277
+ return (_jsx("div", { className: "font-light italic text-left text-gray-500 text-xs", children: "+ Double-click to add new author" }));
232
278
  }
233
279
  return _jsx("div", { className: "text-left", children: value });
234
280
  },
@@ -236,6 +282,7 @@ export default function Editor(props) {
236
282
  {
237
283
  field: "sow",
238
284
  title: "SOW",
285
+ type: "oid",
239
286
  editable: true,
240
287
  align: "center",
241
288
  onSave: (newValue, context) => {
@@ -252,6 +299,7 @@ export default function Editor(props) {
252
299
  {
253
300
  field: "paymentTerms",
254
301
  title: "Payment Terms",
302
+ type: "oid",
255
303
  editable: true,
256
304
  align: "center",
257
305
  onSave: (newValue, context) => {
@@ -268,25 +316,33 @@ export default function Editor(props) {
268
316
  {
269
317
  field: "status",
270
318
  title: "Status",
271
- editable: false,
319
+ editable: true,
272
320
  align: "center",
273
- width: 100,
274
- renderCell: (value, context) => {
321
+ type: "enum",
322
+ valueGetter: (row) => row.status,
323
+ onSave: (newValue, context) => {
324
+ if (newValue !== context.row.status) {
325
+ dispatch(actions.editAlternativeProposal({
326
+ id: context.row.id,
327
+ status: newValue,
328
+ }));
329
+ return true;
330
+ }
331
+ return false;
332
+ },
333
+ renderCellEditor: buildEnumCellEditor({
334
+ className: "w-[130px]",
335
+ options: [
336
+ { value: "DRAFT", label: "Draft" },
337
+ { value: "SUBMITTED", label: "Submitted" },
338
+ { value: "ACCEPTED", label: "Accepted" },
339
+ { value: "REJECTED", label: "Rejected" },
340
+ ],
341
+ }),
342
+ renderCell: (value) => {
275
343
  if (!value)
276
344
  return null;
277
- return (_jsx(Select, { options: [
278
- { value: "DRAFT", label: "Draft" },
279
- { value: "SUBMITTED", label: "Submitted" },
280
- { value: "ACCEPTED", label: "Accepted" },
281
- { value: "REJECTED", label: "Rejected" },
282
- ], value: value || "DRAFT", onChange: (value) => {
283
- if (value !== value) {
284
- dispatch(actions.editAlternativeProposal({
285
- id: context.row.id,
286
- status: value,
287
- }));
288
- }
289
- } }));
345
+ return (_jsx("div", { className: `text-center ${statusStyles[value]}`, children: value }));
290
346
  },
291
347
  },
292
348
  ], []);
@@ -310,17 +366,17 @@ export default function Editor(props) {
310
366
  if (e.target.value !== state.client?.icon) {
311
367
  handleClientChange("icon", e.target.value);
312
368
  }
313
- }, placeholder: "Enter client icon URL" })] })] })] })] }), rfpDocument ? (_jsxs("div", { className: "bg-white rounded-lg p-6 mt-6 mb-6 shadow-sm", children: [_jsx("h1", { className: "text-2xl text-gray-900 mb-4", children: "Request for Proposal" }), _jsxs("div", { className: "w-full flex flex-row items-center gap-8", children: [_jsx("div", { className: "w-[350px]", children: _jsx(PHIDInput, { name: "Request for Proposal", label: "RFP Document", placeholder: "Search for RFP Document", variant: "withValueTitleAndDescription", value: newlyCreatedRfpId || state.rfp?.id || "", onBlur: (e) => {
369
+ }, placeholder: "Enter client icon URL" })] })] })] })] }), _jsxs("div", { className: "bg-white rounded-lg p-6 mt-6 mb-6 shadow-sm", children: [_jsx("h1", { className: "text-2xl text-gray-900 mb-4", children: "Request for Proposal" }), _jsxs("div", { className: "w-full flex flex-row items-center gap-8", children: [_jsx("div", { className: "w-[350px]", children: _jsx(OIDInput, { name: "Request for Proposal", label: "RFP Document", placeholder: "Search for RFP Document", variant: "withValueTitleAndDescription", value: newlyCreatedRfpId || state.rfp?.id || "", onBlur: (e) => {
314
370
  if (e.target.value !== state.rfp?.id) {
315
371
  dispatch(actions.setRequestForProposal({
316
372
  rfpId: e.target.value,
317
- title: rfpDocument.document.title,
373
+ title: rfpDocument?.document.title || "",
318
374
  }));
319
375
  }
320
376
  },
321
377
  // search options as the user types
322
378
  fetchOptionsCallback: async (userInput) => {
323
- const results = searchRfpDocuments(userInput) || [];
379
+ const results = searchRfpDocuments(userInput || "") || [];
324
380
  if (results?.length === 0) {
325
381
  return Promise.reject(new Error("No RFP documents found"));
326
382
  }
@@ -354,19 +410,19 @@ export default function Editor(props) {
354
410
  };
355
411
  }, initialOptions: [
356
412
  {
357
- value: rfpDocument.header.id,
358
- title: rfpDocument.document.title,
413
+ value: rfpDocument?.header.id || "",
414
+ title: rfpDocument?.document.title || "",
359
415
  path: {
360
- text: rfpDocument.document.title,
361
- url: rfpDocument.header.id,
416
+ text: rfpDocument?.document.title || "",
417
+ url: rfpDocument?.header.id || "",
362
418
  },
363
419
  description: "",
364
420
  icon: "File",
365
421
  },
366
- ] }) }), _jsx("div", { className: "flex items-center", children: _jsxs("span", { className: "inline-flex items-center gap-2", children: [_jsx(Icon, { className: "hover:cursor-pointer hover:bg-gray-500", name: "Moved", size: 18, onClick: () => {
422
+ ] }) }), rfpDocument ? (_jsx("div", { className: "flex items-center", children: _jsxs("span", { className: "inline-flex items-center gap-2", children: [_jsx(Icon, { className: "hover:cursor-pointer hover:bg-gray-500", name: "Moved", size: 18, onClick: () => {
367
423
  setActiveDocumentId(rfpDocument?.header.id);
368
424
  setActiveSidebarNodeId(`editor-${rfpDocument?.header.id}`);
369
- } }), _jsx("span", { children: "RFP Editor" })] }) })] })] })) : (_jsxs("div", { className: "bg-white rounded-lg p-6 mt-6 mb-6 shadow-sm", children: [_jsx("h1", { className: "text-2xl text-gray-900 mb-4", children: "Request for Proposal" }), _jsx("div", { className: "mt-4", children: _jsx(Button, { color: "light", size: "small", className: "cursor-pointer hover:bg-gray-600 hover:text-white", title: "Save Workstream", "aria-description": "Save Workstream", onClick: async () => {
425
+ } }), _jsx("span", { children: "RFP Editor" })] }) })) : ("")] }), !rfpDocument ? (_jsx("div", { className: "mt-4", children: _jsx(Button, { color: "light", size: "small", className: "cursor-pointer hover:bg-gray-600 hover:text-white", title: "Save Workstream", "aria-description": "Save Workstream", onClick: async () => {
370
426
  const createdNode = await createRfpDocument();
371
427
  if (createdNode) {
372
428
  // Set local state to immediately show the new RFP ID
@@ -376,7 +432,7 @@ export default function Editor(props) {
376
432
  title: createdNode.name,
377
433
  }));
378
434
  }
379
- }, children: "Create RFP Document" }) })] })), rfpDocument ? (_jsx("div", { children: state.initialProposal ? (_jsxs("div", { className: "bg-white rounded-lg p-6 mb-6 shadow-sm", children: [_jsx("h1", { className: "text-2xl text-gray-900 mb-4", children: "Initial Proposal" }), _jsxs("div", { className: "flex flex-row gap-4 mb-6", children: [_jsx("div", { className: "flex-1", children: _jsx(TextInput, { label: "Author", value: manualAuthorInput ||
435
+ }, children: "Create RFP Document" }) })) : ("")] }), rfpDocument ? (_jsx("div", { children: state.initialProposal ? (_jsxs("div", { className: "bg-white rounded-lg p-6 mb-6 shadow-sm", children: [_jsx("h1", { className: "text-2xl text-gray-900 mb-4", children: "Initial Proposal" }), _jsxs("div", { className: "flex flex-row gap-4 mb-6", children: [_jsx("div", { className: "flex-1", children: _jsx(TextInput, { label: "Author", value: manualAuthorInput ||
380
436
  state.initialProposal?.author?.name ||
381
437
  "", onChange: (e) => {
382
438
  setManualAuthorInput(e.target.value);
@@ -390,20 +446,74 @@ export default function Editor(props) {
390
446
  },
391
447
  }));
392
448
  }
393
- } }) }), _jsxs("div", { className: "flex-1", children: [_jsx(TextInput, { label: "Sow", value: newlyCreatedSowId ||
394
- manualSowInput ||
395
- state.initialProposal?.sow ||
396
- "", onChange: (e) => {
397
- setManualSowInput(e.target.value);
398
- setNewlyCreatedSowId(null); // Clear newly created ID when user starts typing
399
- }, onBlur: (e) => {
449
+ } }) }), _jsx("div", { className: "flex-1", children: _jsx(Select, { label: "Status", options: [
450
+ { value: "DRAFT", label: "Draft" },
451
+ { value: "SUBMITTED", label: "Submitted" },
452
+ { value: "ACCEPTED", label: "Accepted" },
453
+ { value: "REJECTED", label: "Rejected" },
454
+ ], value: state.initialProposal.status || "DRAFT", onChange: (value) => {
455
+ if (value !== state.initialProposal.status) {
456
+ dispatch(actions.editInitialProposal({
457
+ id: state.initialProposal.id,
458
+ status: value,
459
+ }));
460
+ }
461
+ } }) })] }), _jsxs("div", { className: "flex flex-row gap-4 mb-6", children: [_jsxs("div", { className: "flex-1", children: [_jsx(OIDInput, { name: "Scope of Work", label: "Scope Of Work", placeholder: "Search for SOW Document", variant: "withValueTitleAndDescription", value: newlyCreatedSowId || state.initialProposal?.sow || "", onBlur: (e) => {
400
462
  if (e.target.value !== state.initialProposal?.sow) {
401
463
  dispatch(actions.editInitialProposal({
402
464
  id: state.initialProposal?.id || "",
403
465
  sowId: e.target.value,
404
466
  }));
405
467
  }
406
- } }), _jsx("button", { className: "text-sm bg-gray-100 rounded-md p-1 hover:bg-gray-200", onClick: async () => {
468
+ },
469
+ // search options as the user types
470
+ fetchOptionsCallback: async (userInput) => {
471
+ const results = searchSowDocuments(userInput || "") || [];
472
+ if (results?.length === 0) {
473
+ return Promise.reject(new Error("No SOW documents found"));
474
+ }
475
+ return results?.map((doc) => ({
476
+ value: doc.value, // unique document ID
477
+ title: doc.title, // document title or name
478
+ path: {
479
+ text: doc.path,
480
+ url: doc.value,
481
+ }, // document path or location
482
+ description: "", // document description or summary
483
+ icon: "File", // document icon
484
+ }));
485
+ },
486
+ // get details of a specific option by its ID/value
487
+ fetchSelectedOptionCallback: async (documentId) => {
488
+ const doc = searchSowDocuments(documentId)?.[0];
489
+ if (!doc) {
490
+ return Promise.reject(new Error("SOW document not found"));
491
+ }
492
+ return {
493
+ value: doc.value,
494
+ title: doc.title,
495
+ path: {
496
+ text: doc.path,
497
+ url: doc.title,
498
+ },
499
+ description: "",
500
+ icon: "File",
501
+ };
502
+ }, initialOptions: sowDocumentNode
503
+ ? [
504
+ {
505
+ value: sowDocumentNode.header.id,
506
+ title: sowDocumentNode.state?.global
507
+ ?.title || sowDocumentNode.header.name,
508
+ path: {
509
+ text: sowDocumentNode.header.name,
510
+ url: sowDocumentNode.header.id,
511
+ },
512
+ description: "",
513
+ icon: "File",
514
+ },
515
+ ]
516
+ : undefined }), _jsx("button", { className: "text-sm bg-gray-100 rounded-md mt-1 p-1 hover:bg-gray-200", onClick: async () => {
407
517
  console.log("Creating sow");
408
518
  const createdNode = await createSowDocument();
409
519
  if (createdNode) {
@@ -414,20 +524,65 @@ export default function Editor(props) {
414
524
  sowId: createdNode.id,
415
525
  }));
416
526
  }
417
- }, children: "Create sow" })] }), _jsxs("div", { className: "flex-1", children: [_jsx(TextInput, { label: "Payment Terms", value: newlyCreatedPaymentTermsId ||
418
- manualPaymentTermsInput ||
527
+ }, children: "Create sow" })] }), _jsxs("div", { className: "flex-1", children: [_jsx(OIDInput, { name: "Payment Terms", label: "Payment Terms", placeholder: "Search for Payment Terms Document", variant: "withValueTitleAndDescription", value: newlyCreatedPaymentTermsId ||
419
528
  state.initialProposal?.paymentTerms ||
420
- "", onChange: (e) => {
421
- setManualPaymentTermsInput(e.target.value);
422
- setNewlyCreatedPaymentTermsId(null); // Clear newly created ID when user starts typing
423
- }, onBlur: (e) => {
529
+ "", onBlur: (e) => {
424
530
  if (e.target.value !== state.initialProposal?.paymentTerms) {
425
531
  dispatch(actions.editInitialProposal({
426
532
  id: state.initialProposal?.id || "",
427
533
  paymentTermsId: e.target.value,
428
534
  }));
429
535
  }
430
- } }), _jsx("button", { className: "text-sm bg-gray-100 rounded-md p-1 hover:bg-gray-200", onClick: async () => {
536
+ },
537
+ // search options as the user types
538
+ fetchOptionsCallback: async (userInput) => {
539
+ const results = searchPaymentTermsDocuments(userInput || "") || [];
540
+ if (results?.length === 0) {
541
+ return Promise.reject(new Error("No Payment Terms documents found"));
542
+ }
543
+ return results?.map((doc) => ({
544
+ value: doc.value, // unique document ID
545
+ title: doc.title, // document title or name
546
+ path: {
547
+ text: doc.path,
548
+ url: doc.value,
549
+ }, // document path or location
550
+ description: "", // document description or summary
551
+ icon: "File", // document icon
552
+ }));
553
+ },
554
+ // get details of a specific option by its ID/value
555
+ fetchSelectedOptionCallback: async (documentId) => {
556
+ const doc = searchPaymentTermsDocuments(documentId)?.[0];
557
+ if (!doc) {
558
+ return Promise.reject(new Error("Payment Terms document not found"));
559
+ }
560
+ return {
561
+ value: doc.value,
562
+ title: doc.title,
563
+ path: {
564
+ text: doc.path,
565
+ url: doc.title,
566
+ },
567
+ description: "",
568
+ icon: "File",
569
+ };
570
+ }, initialOptions: paymentTermsDocumentNode
571
+ ? [
572
+ {
573
+ value: paymentTermsDocumentNode.header.id,
574
+ title: paymentTermsDocumentNode.state
575
+ ?.global?.title ||
576
+ paymentTermsDocumentNode.header.name,
577
+ path: {
578
+ text: paymentTermsDocumentNode.header.name,
579
+ url: paymentTermsDocumentNode.header.id,
580
+ },
581
+ description: "",
582
+ icon: "File",
583
+ },
584
+ ]
585
+ : undefined }), _jsx("button", { className: "text-sm bg-gray-100 rounded-md mt-1 p-1 hover:bg-gray-200", onClick: async () => {
431
586
  console.log("Creating payment terms");
432
587
  const createdNode = await createPaymentTermsDocument();
433
588
  if (createdNode) {
@@ -438,19 +593,7 @@ export default function Editor(props) {
438
593
  paymentTermsId: createdNode.id,
439
594
  }));
440
595
  }
441
- }, children: "Create Payment Terms" })] }), _jsx("div", { className: "flex-1", children: _jsx(Select, { label: "Status", options: [
442
- { value: "DRAFT", label: "Draft" },
443
- { value: "SUBMITTED", label: "Submitted" },
444
- { value: "ACCEPTED", label: "Accepted" },
445
- { value: "REJECTED", label: "Rejected" },
446
- ], value: state.initialProposal.status || "DRAFT", onChange: (value) => {
447
- if (value !== state.initialProposal.status) {
448
- dispatch(actions.editInitialProposal({
449
- id: state.initialProposal.id,
450
- status: value,
451
- }));
452
- }
453
- } }) })] }), _jsxs("div", { children: [_jsx("h2", { className: "text-lg font-medium text-gray-900 mb-4", children: "Alternative Proposals" }), _jsx(ObjectSetTable, { columns: alternativeProposalsColumns, data: alternativeProposalsData, allowRowSelection: true, onDelete: (data) => {
596
+ }, children: "Create Payment Terms" })] })] }), _jsxs("div", { children: [_jsx("h2", { className: "text-lg font-medium text-gray-900 mb-4", children: "Alternative Proposals" }), _jsx(ObjectSetTable, { columns: alternativeProposalsColumns, data: alternativeProposalsData, allowRowSelection: true, onDelete: (data) => {
454
597
  if (data.length > 0) {
455
598
  data.forEach((d) => {
456
599
  dispatch(actions.removeAlternativeProposal({