@weirdfingers/boards 0.6.1 → 0.7.0
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/index.d.mts +24 -9
- package/dist/index.d.ts +24 -9
- package/dist/index.js +197 -69
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +196 -69
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -1
- package/src/graphql/__tests__/operations.test.ts +53 -0
- package/src/graphql/operations.ts +9 -2
- package/src/hooks/__tests__/useMultiUpload.test.ts +238 -0
- package/src/hooks/useBoard.ts +4 -2
- package/src/hooks/useGeneration.ts +44 -0
- package/src/hooks/useMultiUpload.ts +309 -0
- package/src/index.ts +7 -5
- package/src/hooks/useUpload.ts +0 -175
package/dist/index.d.mts
CHANGED
|
@@ -389,6 +389,7 @@ declare const REMOVE_BOARD_MEMBER: urql.TypedDocumentNode<any, urql.AnyVariables
|
|
|
389
389
|
declare const CREATE_GENERATION: urql.TypedDocumentNode<any, urql.AnyVariables>;
|
|
390
390
|
declare const CANCEL_GENERATION: urql.TypedDocumentNode<any, urql.AnyVariables>;
|
|
391
391
|
declare const RETRY_GENERATION: urql.TypedDocumentNode<any, urql.AnyVariables>;
|
|
392
|
+
declare const DELETE_GENERATION: urql.TypedDocumentNode<any, urql.AnyVariables>;
|
|
392
393
|
declare const UPLOAD_ARTIFACT_FROM_URL: urql.TypedDocumentNode<any, urql.AnyVariables>;
|
|
393
394
|
interface CreateBoardInput {
|
|
394
395
|
title: string;
|
|
@@ -398,6 +399,7 @@ interface CreateBoardInput {
|
|
|
398
399
|
metadata?: Record<string, unknown>;
|
|
399
400
|
}
|
|
400
401
|
interface UpdateBoardInput {
|
|
402
|
+
id: string;
|
|
401
403
|
title?: string;
|
|
402
404
|
description?: string;
|
|
403
405
|
isPublic?: boolean;
|
|
@@ -651,6 +653,7 @@ interface GenerationHook {
|
|
|
651
653
|
submit: (request: GenerationRequest) => Promise<string>;
|
|
652
654
|
cancel: (jobId: string) => Promise<void>;
|
|
653
655
|
retry: (jobId: string) => Promise<void>;
|
|
656
|
+
deleteGeneration: (jobId: string) => Promise<void>;
|
|
654
657
|
history: GenerationResult[];
|
|
655
658
|
clearHistory: () => void;
|
|
656
659
|
}
|
|
@@ -678,17 +681,17 @@ interface GeneratorsHook {
|
|
|
678
681
|
declare function useGenerators(options?: UseGeneratorsOptions): GeneratorsHook;
|
|
679
682
|
|
|
680
683
|
/**
|
|
681
|
-
* Hook for uploading artifacts
|
|
684
|
+
* Hook for uploading multiple artifacts concurrently with individual progress tracking.
|
|
682
685
|
*/
|
|
683
686
|
|
|
684
|
-
interface
|
|
687
|
+
interface MultiUploadRequest {
|
|
685
688
|
boardId: string;
|
|
686
689
|
artifactType: ArtifactType;
|
|
687
690
|
source: File | string;
|
|
688
691
|
userDescription?: string;
|
|
689
692
|
parentGenerationId?: string;
|
|
690
693
|
}
|
|
691
|
-
interface
|
|
694
|
+
interface MultiUploadResult {
|
|
692
695
|
id: string;
|
|
693
696
|
storageUrl: string;
|
|
694
697
|
thumbnailUrl?: string;
|
|
@@ -696,13 +699,25 @@ interface UploadResult {
|
|
|
696
699
|
artifactType: ArtifactType;
|
|
697
700
|
generatorName: string;
|
|
698
701
|
}
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
+
type UploadStatus = "pending" | "uploading" | "completed" | "failed";
|
|
703
|
+
interface UploadItem {
|
|
704
|
+
id: string;
|
|
705
|
+
file: File | string;
|
|
706
|
+
fileName: string;
|
|
707
|
+
status: UploadStatus;
|
|
702
708
|
progress: number;
|
|
703
|
-
|
|
709
|
+
result?: MultiUploadResult;
|
|
710
|
+
error?: Error;
|
|
711
|
+
}
|
|
712
|
+
interface MultiUploadHook {
|
|
713
|
+
uploadMultiple: (requests: MultiUploadRequest[]) => Promise<MultiUploadResult[]>;
|
|
714
|
+
uploads: UploadItem[];
|
|
715
|
+
isUploading: boolean;
|
|
716
|
+
overallProgress: number;
|
|
717
|
+
clearUploads: () => void;
|
|
718
|
+
cancelUpload: (uploadId: string) => void;
|
|
704
719
|
}
|
|
705
|
-
declare function
|
|
720
|
+
declare function useMultiUpload(): MultiUploadHook;
|
|
706
721
|
|
|
707
722
|
/**
|
|
708
723
|
* Hook for accessing generation lineage (ancestry and descendants).
|
|
@@ -907,4 +922,4 @@ declare function BoardsProvider({ children, apiUrl, graphqlUrl, subscriptionUrl,
|
|
|
907
922
|
|
|
908
923
|
declare const VERSION = "0.1.0";
|
|
909
924
|
|
|
910
|
-
export { ADD_BOARD_MEMBER, ANCESTRY_NODE_FRAGMENT, ARTIFACT_LINEAGE_FRAGMENT, type AncestryNode, type ApiConfig, type Artifact$1 as Artifact, type ArtifactLineage, type ArtifactSlot, type ArtifactSlotInfo, ArtifactType, type AuthContextValue, AuthProvider, type AuthProviderConfig, type AuthState$1 as AuthState, BOARD_FRAGMENT, BaseAuthProvider, BoardRole, BoardsProvider, CANCEL_GENERATION, CREATE_BOARD, CREATE_GENERATION, type CreateBoardInput, type CreateGenerationInput, DELETE_BOARD, DESCENDANT_NODE_FRAGMENT, type DescendantNode, type DropdownField, GENERATION_FRAGMENT, GET_ANCESTRY, GET_BOARD, GET_BOARDS, GET_CURRENT_USER, GET_DESCENDANTS, GET_GENERATION, GET_GENERATIONS, GET_GENERATORS, GET_INPUT_ARTIFACTS, GenerationStatus, type Generator, type GeneratorInfo, type GeneratorSelectionContextValue, GeneratorSelectionProvider, NoAuthProvider, type NumberInputField, type ParsedGeneratorSchema, type PromptField, REMOVE_BOARD_MEMBER, RETRY_GENERATION, type SettingsField, type SignInOptions, type SliderField, type TextInputField, UPDATE_BOARD, UPDATE_BOARD_MEMBER_ROLE, UPLOAD_ARTIFACT_FROM_URL, USER_FRAGMENT, type UpdateBoardInput, type UploadArtifactInput, type
|
|
925
|
+
export { ADD_BOARD_MEMBER, ANCESTRY_NODE_FRAGMENT, ARTIFACT_LINEAGE_FRAGMENT, type AncestryNode, type ApiConfig, type Artifact$1 as Artifact, type ArtifactLineage, type ArtifactSlot, type ArtifactSlotInfo, ArtifactType, type AuthContextValue, AuthProvider, type AuthProviderConfig, type AuthState$1 as AuthState, BOARD_FRAGMENT, BaseAuthProvider, BoardRole, BoardsProvider, CANCEL_GENERATION, CREATE_BOARD, CREATE_GENERATION, type CreateBoardInput, type CreateGenerationInput, DELETE_BOARD, DELETE_GENERATION, DESCENDANT_NODE_FRAGMENT, type DescendantNode, type DropdownField, GENERATION_FRAGMENT, GET_ANCESTRY, GET_BOARD, GET_BOARDS, GET_CURRENT_USER, GET_DESCENDANTS, GET_GENERATION, GET_GENERATIONS, GET_GENERATORS, GET_INPUT_ARTIFACTS, GenerationStatus, type Generator, type GeneratorInfo, type GeneratorSelectionContextValue, GeneratorSelectionProvider, type MultiUploadHook, type MultiUploadRequest, type MultiUploadResult, NoAuthProvider, type NumberInputField, type ParsedGeneratorSchema, type PromptField, REMOVE_BOARD_MEMBER, RETRY_GENERATION, type SettingsField, type SignInOptions, type SliderField, type TextInputField, UPDATE_BOARD, UPDATE_BOARD_MEMBER_ROLE, UPLOAD_ARTIFACT_FROM_URL, USER_FRAGMENT, type UpdateBoardInput, type UploadArtifactInput, type UploadItem, type UploadStatus, type User$1 as User, VERSION, createGraphQLClient, getArtifactType, isArtifactReference, parseArtifactSlot, parseGeneratorSchema, parseSettingsField, useAncestry, useApiConfig, useAuth, useAuthOptional, useBoard, useBoards, useDescendants, useGeneration, useGeneratorSelection, useGenerators, useInputArtifacts, useLineage, useMultiUpload };
|
package/dist/index.d.ts
CHANGED
|
@@ -389,6 +389,7 @@ declare const REMOVE_BOARD_MEMBER: urql.TypedDocumentNode<any, urql.AnyVariables
|
|
|
389
389
|
declare const CREATE_GENERATION: urql.TypedDocumentNode<any, urql.AnyVariables>;
|
|
390
390
|
declare const CANCEL_GENERATION: urql.TypedDocumentNode<any, urql.AnyVariables>;
|
|
391
391
|
declare const RETRY_GENERATION: urql.TypedDocumentNode<any, urql.AnyVariables>;
|
|
392
|
+
declare const DELETE_GENERATION: urql.TypedDocumentNode<any, urql.AnyVariables>;
|
|
392
393
|
declare const UPLOAD_ARTIFACT_FROM_URL: urql.TypedDocumentNode<any, urql.AnyVariables>;
|
|
393
394
|
interface CreateBoardInput {
|
|
394
395
|
title: string;
|
|
@@ -398,6 +399,7 @@ interface CreateBoardInput {
|
|
|
398
399
|
metadata?: Record<string, unknown>;
|
|
399
400
|
}
|
|
400
401
|
interface UpdateBoardInput {
|
|
402
|
+
id: string;
|
|
401
403
|
title?: string;
|
|
402
404
|
description?: string;
|
|
403
405
|
isPublic?: boolean;
|
|
@@ -651,6 +653,7 @@ interface GenerationHook {
|
|
|
651
653
|
submit: (request: GenerationRequest) => Promise<string>;
|
|
652
654
|
cancel: (jobId: string) => Promise<void>;
|
|
653
655
|
retry: (jobId: string) => Promise<void>;
|
|
656
|
+
deleteGeneration: (jobId: string) => Promise<void>;
|
|
654
657
|
history: GenerationResult[];
|
|
655
658
|
clearHistory: () => void;
|
|
656
659
|
}
|
|
@@ -678,17 +681,17 @@ interface GeneratorsHook {
|
|
|
678
681
|
declare function useGenerators(options?: UseGeneratorsOptions): GeneratorsHook;
|
|
679
682
|
|
|
680
683
|
/**
|
|
681
|
-
* Hook for uploading artifacts
|
|
684
|
+
* Hook for uploading multiple artifacts concurrently with individual progress tracking.
|
|
682
685
|
*/
|
|
683
686
|
|
|
684
|
-
interface
|
|
687
|
+
interface MultiUploadRequest {
|
|
685
688
|
boardId: string;
|
|
686
689
|
artifactType: ArtifactType;
|
|
687
690
|
source: File | string;
|
|
688
691
|
userDescription?: string;
|
|
689
692
|
parentGenerationId?: string;
|
|
690
693
|
}
|
|
691
|
-
interface
|
|
694
|
+
interface MultiUploadResult {
|
|
692
695
|
id: string;
|
|
693
696
|
storageUrl: string;
|
|
694
697
|
thumbnailUrl?: string;
|
|
@@ -696,13 +699,25 @@ interface UploadResult {
|
|
|
696
699
|
artifactType: ArtifactType;
|
|
697
700
|
generatorName: string;
|
|
698
701
|
}
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
+
type UploadStatus = "pending" | "uploading" | "completed" | "failed";
|
|
703
|
+
interface UploadItem {
|
|
704
|
+
id: string;
|
|
705
|
+
file: File | string;
|
|
706
|
+
fileName: string;
|
|
707
|
+
status: UploadStatus;
|
|
702
708
|
progress: number;
|
|
703
|
-
|
|
709
|
+
result?: MultiUploadResult;
|
|
710
|
+
error?: Error;
|
|
711
|
+
}
|
|
712
|
+
interface MultiUploadHook {
|
|
713
|
+
uploadMultiple: (requests: MultiUploadRequest[]) => Promise<MultiUploadResult[]>;
|
|
714
|
+
uploads: UploadItem[];
|
|
715
|
+
isUploading: boolean;
|
|
716
|
+
overallProgress: number;
|
|
717
|
+
clearUploads: () => void;
|
|
718
|
+
cancelUpload: (uploadId: string) => void;
|
|
704
719
|
}
|
|
705
|
-
declare function
|
|
720
|
+
declare function useMultiUpload(): MultiUploadHook;
|
|
706
721
|
|
|
707
722
|
/**
|
|
708
723
|
* Hook for accessing generation lineage (ancestry and descendants).
|
|
@@ -907,4 +922,4 @@ declare function BoardsProvider({ children, apiUrl, graphqlUrl, subscriptionUrl,
|
|
|
907
922
|
|
|
908
923
|
declare const VERSION = "0.1.0";
|
|
909
924
|
|
|
910
|
-
export { ADD_BOARD_MEMBER, ANCESTRY_NODE_FRAGMENT, ARTIFACT_LINEAGE_FRAGMENT, type AncestryNode, type ApiConfig, type Artifact$1 as Artifact, type ArtifactLineage, type ArtifactSlot, type ArtifactSlotInfo, ArtifactType, type AuthContextValue, AuthProvider, type AuthProviderConfig, type AuthState$1 as AuthState, BOARD_FRAGMENT, BaseAuthProvider, BoardRole, BoardsProvider, CANCEL_GENERATION, CREATE_BOARD, CREATE_GENERATION, type CreateBoardInput, type CreateGenerationInput, DELETE_BOARD, DESCENDANT_NODE_FRAGMENT, type DescendantNode, type DropdownField, GENERATION_FRAGMENT, GET_ANCESTRY, GET_BOARD, GET_BOARDS, GET_CURRENT_USER, GET_DESCENDANTS, GET_GENERATION, GET_GENERATIONS, GET_GENERATORS, GET_INPUT_ARTIFACTS, GenerationStatus, type Generator, type GeneratorInfo, type GeneratorSelectionContextValue, GeneratorSelectionProvider, NoAuthProvider, type NumberInputField, type ParsedGeneratorSchema, type PromptField, REMOVE_BOARD_MEMBER, RETRY_GENERATION, type SettingsField, type SignInOptions, type SliderField, type TextInputField, UPDATE_BOARD, UPDATE_BOARD_MEMBER_ROLE, UPLOAD_ARTIFACT_FROM_URL, USER_FRAGMENT, type UpdateBoardInput, type UploadArtifactInput, type
|
|
925
|
+
export { ADD_BOARD_MEMBER, ANCESTRY_NODE_FRAGMENT, ARTIFACT_LINEAGE_FRAGMENT, type AncestryNode, type ApiConfig, type Artifact$1 as Artifact, type ArtifactLineage, type ArtifactSlot, type ArtifactSlotInfo, ArtifactType, type AuthContextValue, AuthProvider, type AuthProviderConfig, type AuthState$1 as AuthState, BOARD_FRAGMENT, BaseAuthProvider, BoardRole, BoardsProvider, CANCEL_GENERATION, CREATE_BOARD, CREATE_GENERATION, type CreateBoardInput, type CreateGenerationInput, DELETE_BOARD, DELETE_GENERATION, DESCENDANT_NODE_FRAGMENT, type DescendantNode, type DropdownField, GENERATION_FRAGMENT, GET_ANCESTRY, GET_BOARD, GET_BOARDS, GET_CURRENT_USER, GET_DESCENDANTS, GET_GENERATION, GET_GENERATIONS, GET_GENERATORS, GET_INPUT_ARTIFACTS, GenerationStatus, type Generator, type GeneratorInfo, type GeneratorSelectionContextValue, GeneratorSelectionProvider, type MultiUploadHook, type MultiUploadRequest, type MultiUploadResult, NoAuthProvider, type NumberInputField, type ParsedGeneratorSchema, type PromptField, REMOVE_BOARD_MEMBER, RETRY_GENERATION, type SettingsField, type SignInOptions, type SliderField, type TextInputField, UPDATE_BOARD, UPDATE_BOARD_MEMBER_ROLE, UPLOAD_ARTIFACT_FROM_URL, USER_FRAGMENT, type UpdateBoardInput, type UploadArtifactInput, type UploadItem, type UploadStatus, type User$1 as User, VERSION, createGraphQLClient, getArtifactType, isArtifactReference, parseArtifactSlot, parseGeneratorSchema, parseSettingsField, useAncestry, useApiConfig, useAuth, useAuthOptional, useBoard, useBoards, useDescendants, useGeneration, useGeneratorSelection, useGenerators, useInputArtifacts, useLineage, useMultiUpload };
|
package/dist/index.js
CHANGED
|
@@ -33,6 +33,7 @@ __export(index_exports, {
|
|
|
33
33
|
CREATE_BOARD: () => CREATE_BOARD,
|
|
34
34
|
CREATE_GENERATION: () => CREATE_GENERATION,
|
|
35
35
|
DELETE_BOARD: () => DELETE_BOARD,
|
|
36
|
+
DELETE_GENERATION: () => DELETE_GENERATION,
|
|
36
37
|
DESCENDANT_NODE_FRAGMENT: () => DESCENDANT_NODE_FRAGMENT,
|
|
37
38
|
GENERATION_FRAGMENT: () => GENERATION_FRAGMENT,
|
|
38
39
|
GET_ANCESTRY: () => GET_ANCESTRY,
|
|
@@ -72,7 +73,7 @@ __export(index_exports, {
|
|
|
72
73
|
useGenerators: () => useGenerators,
|
|
73
74
|
useInputArtifacts: () => useInputArtifacts,
|
|
74
75
|
useLineage: () => useLineage,
|
|
75
|
-
|
|
76
|
+
useMultiUpload: () => useMultiUpload
|
|
76
77
|
});
|
|
77
78
|
module.exports = __toCommonJS(index_exports);
|
|
78
79
|
|
|
@@ -820,8 +821,8 @@ var CREATE_BOARD = import_urql2.gql`
|
|
|
820
821
|
`;
|
|
821
822
|
var UPDATE_BOARD = import_urql2.gql`
|
|
822
823
|
${BOARD_FRAGMENT}
|
|
823
|
-
mutation UpdateBoard($
|
|
824
|
-
updateBoard(
|
|
824
|
+
mutation UpdateBoard($input: UpdateBoardInput!) {
|
|
825
|
+
updateBoard(input: $input) {
|
|
825
826
|
...BoardFragment
|
|
826
827
|
}
|
|
827
828
|
}
|
|
@@ -887,6 +888,11 @@ var RETRY_GENERATION = import_urql2.gql`
|
|
|
887
888
|
}
|
|
888
889
|
}
|
|
889
890
|
`;
|
|
891
|
+
var DELETE_GENERATION = import_urql2.gql`
|
|
892
|
+
mutation DeleteGeneration($id: UUID!) {
|
|
893
|
+
deleteGeneration(id: $id)
|
|
894
|
+
}
|
|
895
|
+
`;
|
|
890
896
|
var UPLOAD_ARTIFACT_FROM_URL = import_urql2.gql`
|
|
891
897
|
${GENERATION_FRAGMENT}
|
|
892
898
|
mutation UploadArtifactFromUrl($input: UploadArtifactInput!) {
|
|
@@ -1049,8 +1055,10 @@ function useBoard(boardId, options) {
|
|
|
1049
1055
|
throw new Error("Board ID is required");
|
|
1050
1056
|
}
|
|
1051
1057
|
const result = await updateBoardMutation({
|
|
1052
|
-
|
|
1053
|
-
|
|
1058
|
+
input: {
|
|
1059
|
+
id: boardId,
|
|
1060
|
+
...updates
|
|
1061
|
+
}
|
|
1054
1062
|
});
|
|
1055
1063
|
if (result.error) {
|
|
1056
1064
|
throw new Error(result.error.message);
|
|
@@ -1173,6 +1181,7 @@ function useGeneration() {
|
|
|
1173
1181
|
const [, createGenerationMutation] = (0, import_urql5.useMutation)(CREATE_GENERATION);
|
|
1174
1182
|
const [, cancelGenerationMutation] = (0, import_urql5.useMutation)(CANCEL_GENERATION);
|
|
1175
1183
|
const [, retryGenerationMutation] = (0, import_urql5.useMutation)(RETRY_GENERATION);
|
|
1184
|
+
const [, deleteGenerationMutation] = (0, import_urql5.useMutation)(DELETE_GENERATION);
|
|
1176
1185
|
(0, import_react6.useEffect)(() => {
|
|
1177
1186
|
return () => {
|
|
1178
1187
|
abortControllers.current.forEach((controller) => {
|
|
@@ -1382,6 +1391,36 @@ function useGeneration() {
|
|
|
1382
1391
|
},
|
|
1383
1392
|
[retryGenerationMutation, connectToSSE]
|
|
1384
1393
|
);
|
|
1394
|
+
const deleteGeneration = (0, import_react6.useCallback)(
|
|
1395
|
+
async (jobId) => {
|
|
1396
|
+
try {
|
|
1397
|
+
const result2 = await deleteGenerationMutation({ id: jobId });
|
|
1398
|
+
if (result2.error) {
|
|
1399
|
+
throw new Error(result2.error.message);
|
|
1400
|
+
}
|
|
1401
|
+
if (!result2.data?.deleteGeneration) {
|
|
1402
|
+
throw new Error("Failed to delete generation");
|
|
1403
|
+
}
|
|
1404
|
+
const controller = abortControllers.current.get(jobId);
|
|
1405
|
+
if (controller) {
|
|
1406
|
+
controller.abort();
|
|
1407
|
+
abortControllers.current.delete(jobId);
|
|
1408
|
+
}
|
|
1409
|
+
if (progress?.jobId === jobId) {
|
|
1410
|
+
setProgress(null);
|
|
1411
|
+
setResult(null);
|
|
1412
|
+
setIsGenerating(false);
|
|
1413
|
+
}
|
|
1414
|
+
setHistory((prev) => prev.filter((item) => item.jobId !== jobId));
|
|
1415
|
+
} catch (err) {
|
|
1416
|
+
setError(
|
|
1417
|
+
err instanceof Error ? err : new Error("Failed to delete generation")
|
|
1418
|
+
);
|
|
1419
|
+
throw err;
|
|
1420
|
+
}
|
|
1421
|
+
},
|
|
1422
|
+
[deleteGenerationMutation, progress]
|
|
1423
|
+
);
|
|
1385
1424
|
const clearHistory = (0, import_react6.useCallback)(() => {
|
|
1386
1425
|
setHistory([]);
|
|
1387
1426
|
}, []);
|
|
@@ -1393,6 +1432,7 @@ function useGeneration() {
|
|
|
1393
1432
|
submit,
|
|
1394
1433
|
cancel,
|
|
1395
1434
|
retry,
|
|
1435
|
+
deleteGeneration,
|
|
1396
1436
|
history,
|
|
1397
1437
|
clearHistory
|
|
1398
1438
|
};
|
|
@@ -1415,21 +1455,44 @@ function useGenerators(options = {}) {
|
|
|
1415
1455
|
};
|
|
1416
1456
|
}
|
|
1417
1457
|
|
|
1418
|
-
// src/hooks/
|
|
1458
|
+
// src/hooks/useMultiUpload.ts
|
|
1419
1459
|
var import_react8 = require("react");
|
|
1420
1460
|
var import_urql7 = require("urql");
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1461
|
+
var uploadIdCounter = 0;
|
|
1462
|
+
function generateUploadId() {
|
|
1463
|
+
return `upload-${Date.now()}-${++uploadIdCounter}`;
|
|
1464
|
+
}
|
|
1465
|
+
function getFileName(source) {
|
|
1466
|
+
if (typeof source === "string") {
|
|
1467
|
+
try {
|
|
1468
|
+
const url = new URL(source);
|
|
1469
|
+
const pathParts = url.pathname.split("/");
|
|
1470
|
+
return pathParts[pathParts.length - 1] || source;
|
|
1471
|
+
} catch {
|
|
1472
|
+
return source;
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
return source.name;
|
|
1476
|
+
}
|
|
1477
|
+
function useMultiUpload() {
|
|
1478
|
+
const [uploads, setUploads] = (0, import_react8.useState)([]);
|
|
1479
|
+
const abortControllersRef = (0, import_react8.useRef)(/* @__PURE__ */ new Map());
|
|
1425
1480
|
const { apiUrl } = useApiConfig();
|
|
1426
1481
|
const auth = useAuth();
|
|
1427
1482
|
const [, uploadFromUrlMutation] = (0, import_urql7.useMutation)(UPLOAD_ARTIFACT_FROM_URL);
|
|
1428
|
-
const
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1483
|
+
const updateUpload = (0, import_react8.useCallback)(
|
|
1484
|
+
(uploadId, updates) => {
|
|
1485
|
+
setUploads(
|
|
1486
|
+
(prev) => prev.map(
|
|
1487
|
+
(item) => item.id === uploadId ? { ...item, ...updates } : item
|
|
1488
|
+
)
|
|
1489
|
+
);
|
|
1490
|
+
},
|
|
1491
|
+
[]
|
|
1492
|
+
);
|
|
1493
|
+
const uploadSingle = (0, import_react8.useCallback)(
|
|
1494
|
+
async (uploadId, request) => {
|
|
1495
|
+
updateUpload(uploadId, { status: "uploading", progress: 0 });
|
|
1433
1496
|
try {
|
|
1434
1497
|
if (typeof request.source === "string") {
|
|
1435
1498
|
const result2 = await uploadFromUrlMutation({
|
|
@@ -1447,9 +1510,7 @@ function useUpload() {
|
|
|
1447
1510
|
if (!result2.data?.uploadArtifact) {
|
|
1448
1511
|
throw new Error("Upload failed");
|
|
1449
1512
|
}
|
|
1450
|
-
|
|
1451
|
-
setIsUploading(false);
|
|
1452
|
-
return {
|
|
1513
|
+
const uploadResult = {
|
|
1453
1514
|
id: result2.data.uploadArtifact.id,
|
|
1454
1515
|
storageUrl: result2.data.uploadArtifact.storageUrl,
|
|
1455
1516
|
thumbnailUrl: result2.data.uploadArtifact.thumbnailUrl,
|
|
@@ -1457,6 +1518,12 @@ function useUpload() {
|
|
|
1457
1518
|
artifactType: result2.data.uploadArtifact.artifactType,
|
|
1458
1519
|
generatorName: result2.data.uploadArtifact.generatorName
|
|
1459
1520
|
};
|
|
1521
|
+
updateUpload(uploadId, {
|
|
1522
|
+
status: "completed",
|
|
1523
|
+
progress: 100,
|
|
1524
|
+
result: uploadResult
|
|
1525
|
+
});
|
|
1526
|
+
return uploadResult;
|
|
1460
1527
|
}
|
|
1461
1528
|
const formData = new FormData();
|
|
1462
1529
|
formData.append("board_id", request.boardId);
|
|
@@ -1473,68 +1540,128 @@ function useUpload() {
|
|
|
1473
1540
|
if (token) {
|
|
1474
1541
|
headers.Authorization = `Bearer ${token}`;
|
|
1475
1542
|
}
|
|
1476
|
-
const result = await new Promise(
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
}
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
const data = JSON.parse(xhr.responseText);
|
|
1488
|
-
resolve({
|
|
1489
|
-
id: data.id,
|
|
1490
|
-
storageUrl: data.storageUrl,
|
|
1491
|
-
thumbnailUrl: data.thumbnailUrl,
|
|
1492
|
-
status: "completed",
|
|
1493
|
-
artifactType: data.artifactType,
|
|
1494
|
-
generatorName: data.generatorName
|
|
1495
|
-
});
|
|
1496
|
-
} catch (err) {
|
|
1497
|
-
reject(new Error("Failed to parse response"));
|
|
1543
|
+
const result = await new Promise(
|
|
1544
|
+
(resolve, reject) => {
|
|
1545
|
+
const xhr = new XMLHttpRequest();
|
|
1546
|
+
abortControllersRef.current.set(uploadId, () => xhr.abort());
|
|
1547
|
+
const cleanup = () => {
|
|
1548
|
+
abortControllersRef.current.delete(uploadId);
|
|
1549
|
+
};
|
|
1550
|
+
xhr.upload.addEventListener("progress", (e) => {
|
|
1551
|
+
if (e.lengthComputable) {
|
|
1552
|
+
const percentComplete = e.loaded / e.total * 100;
|
|
1553
|
+
updateUpload(uploadId, { progress: percentComplete });
|
|
1498
1554
|
}
|
|
1499
|
-
}
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1555
|
+
});
|
|
1556
|
+
xhr.addEventListener("load", () => {
|
|
1557
|
+
cleanup();
|
|
1558
|
+
if (xhr.status === 200) {
|
|
1559
|
+
try {
|
|
1560
|
+
const data = JSON.parse(xhr.responseText);
|
|
1561
|
+
resolve({
|
|
1562
|
+
id: data.id,
|
|
1563
|
+
storageUrl: data.storageUrl,
|
|
1564
|
+
thumbnailUrl: data.thumbnailUrl,
|
|
1565
|
+
status: "completed",
|
|
1566
|
+
artifactType: data.artifactType,
|
|
1567
|
+
generatorName: data.generatorName
|
|
1568
|
+
});
|
|
1569
|
+
} catch (err) {
|
|
1570
|
+
reject(new Error("Failed to parse response"));
|
|
1571
|
+
}
|
|
1572
|
+
} else {
|
|
1573
|
+
try {
|
|
1574
|
+
const errorData = JSON.parse(xhr.responseText);
|
|
1575
|
+
reject(
|
|
1576
|
+
new Error(
|
|
1577
|
+
errorData.detail || `Upload failed: ${xhr.statusText}`
|
|
1578
|
+
)
|
|
1579
|
+
);
|
|
1580
|
+
} catch {
|
|
1581
|
+
reject(new Error(`Upload failed: ${xhr.statusText}`));
|
|
1582
|
+
}
|
|
1505
1583
|
}
|
|
1506
|
-
}
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1584
|
+
});
|
|
1585
|
+
xhr.addEventListener("error", () => {
|
|
1586
|
+
cleanup();
|
|
1587
|
+
reject(new Error("Upload failed: Network error"));
|
|
1588
|
+
});
|
|
1589
|
+
xhr.addEventListener("abort", () => {
|
|
1590
|
+
cleanup();
|
|
1591
|
+
reject(new Error("Upload cancelled"));
|
|
1592
|
+
});
|
|
1593
|
+
xhr.addEventListener("loadend", () => {
|
|
1594
|
+
cleanup();
|
|
1595
|
+
});
|
|
1596
|
+
xhr.open("POST", `${apiUrl}/api/uploads/artifact`);
|
|
1597
|
+
Object.entries(headers).forEach(([key, value]) => {
|
|
1598
|
+
xhr.setRequestHeader(key, value);
|
|
1599
|
+
});
|
|
1600
|
+
xhr.send(formData);
|
|
1601
|
+
}
|
|
1602
|
+
);
|
|
1603
|
+
updateUpload(uploadId, {
|
|
1604
|
+
status: "completed",
|
|
1605
|
+
progress: 100,
|
|
1606
|
+
result
|
|
1519
1607
|
});
|
|
1520
|
-
setProgress(100);
|
|
1521
|
-
setIsUploading(false);
|
|
1522
1608
|
return result;
|
|
1523
1609
|
} catch (err) {
|
|
1524
1610
|
const uploadError = err instanceof Error ? err : new Error("Upload failed");
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1611
|
+
updateUpload(uploadId, {
|
|
1612
|
+
status: "failed",
|
|
1613
|
+
error: uploadError
|
|
1614
|
+
});
|
|
1528
1615
|
throw uploadError;
|
|
1529
1616
|
}
|
|
1530
1617
|
},
|
|
1531
|
-
[uploadFromUrlMutation, apiUrl, auth]
|
|
1618
|
+
[uploadFromUrlMutation, apiUrl, auth, updateUpload]
|
|
1619
|
+
);
|
|
1620
|
+
const uploadMultiple = (0, import_react8.useCallback)(
|
|
1621
|
+
async (requests) => {
|
|
1622
|
+
const newUploads = requests.map((request) => ({
|
|
1623
|
+
id: generateUploadId(),
|
|
1624
|
+
file: request.source,
|
|
1625
|
+
fileName: getFileName(request.source),
|
|
1626
|
+
status: "pending",
|
|
1627
|
+
progress: 0
|
|
1628
|
+
}));
|
|
1629
|
+
setUploads((prev) => [...prev, ...newUploads]);
|
|
1630
|
+
const results = await Promise.allSettled(
|
|
1631
|
+
requests.map(
|
|
1632
|
+
(request, index) => uploadSingle(newUploads[index].id, request)
|
|
1633
|
+
)
|
|
1634
|
+
);
|
|
1635
|
+
const successfulResults = [];
|
|
1636
|
+
results.forEach((result) => {
|
|
1637
|
+
if (result.status === "fulfilled") {
|
|
1638
|
+
successfulResults.push(result.value);
|
|
1639
|
+
}
|
|
1640
|
+
});
|
|
1641
|
+
return successfulResults;
|
|
1642
|
+
},
|
|
1643
|
+
[uploadSingle]
|
|
1532
1644
|
);
|
|
1645
|
+
const clearUploads = (0, import_react8.useCallback)(() => {
|
|
1646
|
+
abortControllersRef.current.forEach((abort) => abort());
|
|
1647
|
+
abortControllersRef.current.clear();
|
|
1648
|
+
setUploads([]);
|
|
1649
|
+
}, []);
|
|
1650
|
+
const cancelUpload = (0, import_react8.useCallback)((uploadId) => {
|
|
1651
|
+
const abort = abortControllersRef.current.get(uploadId);
|
|
1652
|
+
if (abort) {
|
|
1653
|
+
abort();
|
|
1654
|
+
}
|
|
1655
|
+
}, []);
|
|
1656
|
+
const isUploading = uploads.some((u) => u.status === "uploading");
|
|
1657
|
+
const overallProgress = uploads.length > 0 ? uploads.reduce((sum, u) => sum + u.progress, 0) / uploads.length : 0;
|
|
1533
1658
|
return {
|
|
1534
|
-
|
|
1659
|
+
uploadMultiple,
|
|
1660
|
+
uploads,
|
|
1535
1661
|
isUploading,
|
|
1536
|
-
|
|
1537
|
-
|
|
1662
|
+
overallProgress,
|
|
1663
|
+
clearUploads,
|
|
1664
|
+
cancelUpload
|
|
1538
1665
|
};
|
|
1539
1666
|
}
|
|
1540
1667
|
|
|
@@ -1652,6 +1779,7 @@ var VERSION = "0.1.0";
|
|
|
1652
1779
|
CREATE_BOARD,
|
|
1653
1780
|
CREATE_GENERATION,
|
|
1654
1781
|
DELETE_BOARD,
|
|
1782
|
+
DELETE_GENERATION,
|
|
1655
1783
|
DESCENDANT_NODE_FRAGMENT,
|
|
1656
1784
|
GENERATION_FRAGMENT,
|
|
1657
1785
|
GET_ANCESTRY,
|
|
@@ -1691,6 +1819,6 @@ var VERSION = "0.1.0";
|
|
|
1691
1819
|
useGenerators,
|
|
1692
1820
|
useInputArtifacts,
|
|
1693
1821
|
useLineage,
|
|
1694
|
-
|
|
1822
|
+
useMultiUpload
|
|
1695
1823
|
});
|
|
1696
1824
|
//# sourceMappingURL=index.js.map
|