@powerhousedao/network-admin 0.0.24 → 0.0.25

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":"AA6CA;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE;IAAE,QAAQ,CAAC,EAAE,GAAG,CAAA;CAAE,2CAskBtD"}
1
+ {"version":3,"file":"DriveExplorer.d.ts","sourceRoot":"","sources":["../../../../editors/network-admin/components/DriveExplorer.tsx"],"names":[],"mappings":"AA6CA;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE;IAAE,QAAQ,CAAC,EAAE,GAAG,CAAA;CAAE,2CAikBtD"}
@@ -339,12 +339,7 @@ export function DriveExplorer(props) {
339
339
  catch (error) {
340
340
  console.error("Failed to create document:", error);
341
341
  }
342
- }, [
343
- addDocument,
344
- selectedDrive?.header.id,
345
- selectedFolder?.id,
346
- modalDocumentType,
347
- ]);
342
+ }, [selectedDrive?.header.id, modalDocumentType]);
348
343
  // === RENDER ===
349
344
  return (_jsx(SidebarProvider, { nodes: sidebarNodes, children: isScopeOfWorkFullView && props.children ? (_jsx("div", { className: "h-full w-full", children: props.children })) : (
350
345
  /* === NORMAL VIEW WITH SIDEBAR === */
@@ -1 +1 @@
1
- {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../editors/workstream/editor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,WAAW,EAGZ,MAAM,gBAAgB,CAAC;AAmCxB,MAAM,MAAM,MAAM,GAAG,WAAW,CAAC;AAsBjC,MAAM,CAAC,OAAO,UAAU,MAAM,4CA+hC7B"}
1
+ {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../editors/workstream/editor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,WAAW,EAGZ,MAAM,gBAAgB,CAAC;AAmCxB,MAAM,MAAM,MAAM,GAAG,WAAW,CAAC;AAsBjC,MAAM,CAAC,OAAO,UAAU,MAAM,4CA8jC7B"}
@@ -6,7 +6,7 @@ import { actions as rfpActions, } from "../../document-models/request-for-propos
6
6
  import { ScopeOfWork } from "@powerhousedao/project-management/document-models";
7
7
  import { generateId } from "document-model";
8
8
  import { useDocumentById, useSelectedDrive, addDocument, useSelectedDriveDocuments, dispatchActions, } from "@powerhousedao/reactor-browser";
9
- import { useEffect, useMemo, useState } from "react";
9
+ import { useEffect, useMemo, useState, useCallback } from "react";
10
10
  import { useSelectedWorkstreamDocument } from "../hooks/useWorkstreamDocument.js";
11
11
  // Status options for the dropdown
12
12
  const statusOptions = [
@@ -34,38 +34,76 @@ export default function Editor() {
34
34
  setState(doc.state.global);
35
35
  }, [doc.state.global]);
36
36
  const [selectedDrive] = useSelectedDrive();
37
- const createRfpDocument = async () => {
38
- const createdNode = await addDocument(selectedDrive?.header.id || "", `RFP-${state.title || ""}`, "powerhouse/rfp", undefined, undefined, undefined, "request-for-proposals-editor");
39
- console.log("Created RFP document", createdNode);
40
- if (createdNode) {
41
- await dispatchActions(rfpActions.editRfp({
42
- title: `RFP-${state.title || ""}`,
43
- }), createdNode.id);
44
- }
45
- return createdNode;
46
- };
47
- const createSowDocument = async () => {
48
- const createdNode = await addDocument(selectedDrive?.header.id || "", `SOW-${state.title || ""}`, "powerhouse/scopeofwork", undefined, undefined, undefined, "scope-of-work-editor");
49
- console.log("Created SOW document", createdNode);
50
- if (createdNode) {
51
- await dispatchActions(ScopeOfWork.actions.editScopeOfWork({
52
- title: `SOW-${state.title || ""}`,
53
- }), createdNode.id);
54
- }
55
- return createdNode;
56
- };
57
- const createPaymentTermsDocument = async () => {
58
- const createdNode = await addDocument(selectedDrive?.header.id || "", `Payment Terms-${state.title || ""}`, "payment-terms", undefined, undefined, undefined, "payment-terms-editor");
59
- console.log("Created Payment Terms document", createdNode);
60
- // Note: Payment Terms might not have actions to initialize, so we just create it
61
- return createdNode;
62
- };
63
- // Local state to track newly created SOW document ID
37
+ // Local state to track newly created document IDs
64
38
  const [newlyCreatedSowId, setNewlyCreatedSowId] = useState(null);
65
- // Local state to track newly created Payment Terms document ID
66
39
  const [newlyCreatedPaymentTermsId, setNewlyCreatedPaymentTermsId] = useState(null);
67
- // Local state to track newly created RFP document ID
68
40
  const [newlyCreatedRfpId, setNewlyCreatedRfpId] = useState(null);
41
+ // Loading states to prevent double-clicks
42
+ const [isCreatingRfp, setIsCreatingRfp] = useState(false);
43
+ const [isCreatingSow, setIsCreatingSow] = useState(false);
44
+ const [isCreatingPaymentTerms, setIsCreatingPaymentTerms] = useState(false);
45
+ const createRfpDocument = useCallback(async () => {
46
+ if (isCreatingRfp)
47
+ return null; // Prevent double-calls
48
+ setIsCreatingRfp(true);
49
+ try {
50
+ const createdNode = await addDocument(selectedDrive?.header.id || "", `RFP-${state.title || ""}`, "powerhouse/rfp", undefined, undefined, undefined, "request-for-proposals-editor");
51
+ console.log("Created RFP document", createdNode);
52
+ if (createdNode) {
53
+ await dispatchActions(rfpActions.editRfp({
54
+ title: `RFP-${state.title || ""}`,
55
+ }), createdNode.id);
56
+ }
57
+ return createdNode;
58
+ }
59
+ catch (error) {
60
+ console.error("Failed to create RFP document:", error);
61
+ return null;
62
+ }
63
+ finally {
64
+ setIsCreatingRfp(false);
65
+ }
66
+ }, [isCreatingRfp, selectedDrive?.header.id, state.title]);
67
+ const createSowDocument = useCallback(async () => {
68
+ if (isCreatingSow)
69
+ return null; // Prevent double-calls
70
+ setIsCreatingSow(true);
71
+ try {
72
+ const createdNode = await addDocument(selectedDrive?.header.id || "", `SOW-${state.title || ""}`, "powerhouse/scopeofwork", undefined, undefined, undefined, "scope-of-work-editor");
73
+ console.log("Created SOW document", createdNode);
74
+ if (createdNode) {
75
+ await dispatchActions(ScopeOfWork.actions.editScopeOfWork({
76
+ title: `SOW-${state.title || ""}`,
77
+ }), createdNode.id);
78
+ }
79
+ return createdNode;
80
+ }
81
+ catch (error) {
82
+ console.error("Failed to create SOW document:", error);
83
+ return null;
84
+ }
85
+ finally {
86
+ setIsCreatingSow(false);
87
+ }
88
+ }, [isCreatingSow, selectedDrive?.header.id, state.title]);
89
+ const createPaymentTermsDocument = useCallback(async () => {
90
+ if (isCreatingPaymentTerms)
91
+ return null; // Prevent double-calls
92
+ setIsCreatingPaymentTerms(true);
93
+ try {
94
+ const createdNode = await addDocument(selectedDrive?.header.id || "", `Payment Terms-${state.title || ""}`, "payment-terms", undefined, undefined, undefined, "payment-terms-editor");
95
+ console.log("Created Payment Terms document", createdNode);
96
+ // Note: Payment Terms might not have actions to initialize, so we just create it
97
+ return createdNode;
98
+ }
99
+ catch (error) {
100
+ console.error("Failed to create Payment Terms document:", error);
101
+ return null;
102
+ }
103
+ finally {
104
+ setIsCreatingPaymentTerms(false);
105
+ }
106
+ }, [isCreatingPaymentTerms, selectedDrive?.header.id, state.title]);
69
107
  // Local state to track manual input values
70
108
  const [manualAuthorInput, setManualAuthorInput] = useState("");
71
109
  // Effect to clear local state when global state is updated
@@ -418,7 +456,7 @@ export default function Editor() {
418
456
  description: "",
419
457
  icon: "File",
420
458
  },
421
- ] }) }) }), !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 () => {
459
+ ] }) }) }), !rfpDocument ? (_jsx("div", { className: "mt-4", children: _jsx(Button, { color: "light", size: "small", className: "cursor-pointer hover:bg-gray-600 hover:text-white disabled:opacity-50 disabled:cursor-not-allowed", title: "Save Workstream", "aria-description": "Save Workstream", disabled: isCreatingRfp, onClick: async () => {
422
460
  const createdNode = await createRfpDocument();
423
461
  if (createdNode) {
424
462
  // Set local state to immediately show the new RFP ID
@@ -428,7 +466,7 @@ export default function Editor() {
428
466
  title: createdNode.name,
429
467
  }));
430
468
  }
431
- }, 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 ||
469
+ }, children: isCreatingRfp ? "Creating..." : "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 ||
432
470
  state.initialProposal?.author?.name ||
433
471
  "", onChange: (e) => {
434
472
  setManualAuthorInput(e.target.value);
@@ -509,7 +547,7 @@ export default function Editor() {
509
547
  icon: "File",
510
548
  },
511
549
  ]
512
- : undefined }), _jsx("button", { className: "text-sm bg-gray-100 rounded-md mt-1 p-1 hover:bg-gray-200", onClick: async () => {
550
+ : undefined }), _jsx("button", { className: "text-sm bg-gray-100 rounded-md mt-1 p-1 hover:bg-gray-200 disabled:opacity-50 disabled:cursor-not-allowed", disabled: isCreatingSow, onClick: async () => {
513
551
  console.log("Creating sow");
514
552
  const createdNode = await createSowDocument();
515
553
  if (createdNode) {
@@ -520,7 +558,7 @@ export default function Editor() {
520
558
  sowId: createdNode.id,
521
559
  }));
522
560
  }
523
- }, 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 ||
561
+ }, children: isCreatingSow ? "Creating..." : "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 ||
524
562
  state.initialProposal?.paymentTerms ||
525
563
  "", onBlur: (e) => {
526
564
  if (e.target.value !== state.initialProposal?.paymentTerms) {
@@ -576,7 +614,7 @@ export default function Editor() {
576
614
  icon: "File",
577
615
  },
578
616
  ]
579
- : undefined }), _jsx("button", { className: "text-sm bg-gray-100 rounded-md mt-1 p-1 hover:bg-gray-200", onClick: async () => {
617
+ : undefined }), _jsx("button", { className: "text-sm bg-gray-100 rounded-md mt-1 p-1 hover:bg-gray-200 disabled:opacity-50 disabled:cursor-not-allowed", disabled: isCreatingPaymentTerms, onClick: async () => {
580
618
  console.log("Creating payment terms");
581
619
  const createdNode = await createPaymentTermsDocument();
582
620
  if (createdNode) {
@@ -587,7 +625,7 @@ export default function Editor() {
587
625
  paymentTermsId: createdNode.id,
588
626
  }));
589
627
  }
590
- }, 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) => {
628
+ }, children: isCreatingPaymentTerms ? "Creating..." : "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) => {
591
629
  if (data.length > 0) {
592
630
  data.forEach((d) => {
593
631
  dispatch(actions.removeAlternativeProposal({
package/dist/style.css CHANGED
@@ -1042,6 +1042,16 @@
1042
1042
  --tw-ring-color: var(--color-blue-500);
1043
1043
  }
1044
1044
  }
1045
+ .disabled\:cursor-not-allowed {
1046
+ &:disabled {
1047
+ cursor: not-allowed;
1048
+ }
1049
+ }
1050
+ .disabled\:opacity-50 {
1051
+ &:disabled {
1052
+ opacity: 50%;
1053
+ }
1054
+ }
1045
1055
  .md\:grid-cols-4 {
1046
1056
  @media (width >= 48rem) {
1047
1057
  grid-template-columns: repeat(4, minmax(0, 1fr));
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.24",
4
+ "version": "0.0.25",
5
5
  "license": "AGPL-3.0-only",
6
6
  "type": "module",
7
7
  "files": [