@adventurelabs/scout-core 1.0.120 → 1.0.121
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/constants/db.d.ts +1 -0
- package/dist/constants/db.js +2 -0
- package/dist/helpers/artifacts.d.ts +9 -0
- package/dist/helpers/artifacts.js +121 -0
- package/dist/helpers/index.d.ts +1 -0
- package/dist/helpers/index.js +1 -0
- package/dist/helpers/storage.d.ts +2 -11
- package/dist/helpers/storage.js +10 -54
- package/dist/helpers/tags.js +66 -8
- package/dist/providers/ScoutRefreshProvider.d.ts +74 -0
- package/dist/store/scout.d.ts +9 -1
- package/dist/store/scout.js +15 -1
- package/dist/types/db.d.ts +5 -0
- package/dist/types/herd_module.d.ts +6 -2
- package/dist/types/herd_module.js +25 -4
- package/dist/types/supabase.d.ts +74 -0
- package/package.json +1 -1
package/dist/constants/db.d.ts
CHANGED
package/dist/constants/db.js
CHANGED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { IArtifactWithMediaUrl } from "../types/db";
|
|
2
|
+
import { IWebResponseCompatible } from "../types/requests";
|
|
3
|
+
import { SupabaseClient } from "@supabase/supabase-js";
|
|
4
|
+
export declare function server_get_artifacts_by_herd(herd_id: number, limit?: number, offset?: number, client?: SupabaseClient): Promise<IWebResponseCompatible<IArtifactWithMediaUrl[]>>;
|
|
5
|
+
export declare function server_get_artifacts_by_device_id(device_id: number, limit?: number, offset?: number, client?: SupabaseClient): Promise<IWebResponseCompatible<IArtifactWithMediaUrl[]>>;
|
|
6
|
+
export declare function server_get_total_artifacts_by_herd(herd_id: number): Promise<IWebResponseCompatible<number>>;
|
|
7
|
+
export declare function server_get_artifacts_by_device_ids_batch(device_ids: number[], limit_per_device?: number, client?: SupabaseClient): Promise<{
|
|
8
|
+
[device_id: number]: IArtifactWithMediaUrl[];
|
|
9
|
+
}>;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use server";
|
|
2
|
+
import { newServerClient } from "../supabase/server";
|
|
3
|
+
import { IWebResponse, } from "../types/requests";
|
|
4
|
+
import { generateSignedUrlsBatch } from "./storage";
|
|
5
|
+
export async function server_get_artifacts_by_herd(herd_id, limit = 50, offset = 0, client) {
|
|
6
|
+
const supabase = client || (await newServerClient());
|
|
7
|
+
const { data, error } = await supabase.rpc("get_artifacts_for_herd", {
|
|
8
|
+
herd_id_caller: herd_id,
|
|
9
|
+
limit_caller: limit,
|
|
10
|
+
offset_caller: offset,
|
|
11
|
+
});
|
|
12
|
+
if (error) {
|
|
13
|
+
return IWebResponse.error(error.message).to_compatible();
|
|
14
|
+
}
|
|
15
|
+
if (!data) {
|
|
16
|
+
return IWebResponse.error("No artifacts found for herd").to_compatible();
|
|
17
|
+
}
|
|
18
|
+
// Generate signed URLs for artifacts
|
|
19
|
+
const uniqueFilePaths = Array.from(new Set(data
|
|
20
|
+
.map((artifact) => artifact.file_path)
|
|
21
|
+
.filter((path) => !!path)));
|
|
22
|
+
if (uniqueFilePaths.length === 0) {
|
|
23
|
+
return IWebResponse.success(data).to_compatible();
|
|
24
|
+
}
|
|
25
|
+
const signedUrls = await generateSignedUrlsBatch(uniqueFilePaths, undefined, client);
|
|
26
|
+
const urlMap = new Map();
|
|
27
|
+
uniqueFilePaths.forEach((path, index) => {
|
|
28
|
+
urlMap.set(path, signedUrls[index]);
|
|
29
|
+
});
|
|
30
|
+
const artifactsWithUrls = data.map((artifact) => ({
|
|
31
|
+
...artifact,
|
|
32
|
+
media_url: artifact.file_path
|
|
33
|
+
? urlMap.get(artifact.file_path) || null
|
|
34
|
+
: null,
|
|
35
|
+
}));
|
|
36
|
+
return IWebResponse.success(artifactsWithUrls).to_compatible();
|
|
37
|
+
}
|
|
38
|
+
export async function server_get_artifacts_by_device_id(device_id, limit = 50, offset = 0, client) {
|
|
39
|
+
const supabase = client || (await newServerClient());
|
|
40
|
+
const { data, error } = await supabase.rpc("get_artifacts_for_device", {
|
|
41
|
+
device_id_caller: device_id,
|
|
42
|
+
limit_caller: limit,
|
|
43
|
+
offset_caller: offset,
|
|
44
|
+
});
|
|
45
|
+
if (error) {
|
|
46
|
+
return IWebResponse.error(error.message).to_compatible();
|
|
47
|
+
}
|
|
48
|
+
if (!data) {
|
|
49
|
+
return IWebResponse.error("No artifacts found for device").to_compatible();
|
|
50
|
+
}
|
|
51
|
+
// Generate signed URLs for artifacts
|
|
52
|
+
const uniqueFilePaths = Array.from(new Set(data
|
|
53
|
+
.map((artifact) => artifact.file_path)
|
|
54
|
+
.filter((path) => !!path)));
|
|
55
|
+
if (uniqueFilePaths.length === 0) {
|
|
56
|
+
return IWebResponse.success(data).to_compatible();
|
|
57
|
+
}
|
|
58
|
+
const signedUrls = await generateSignedUrlsBatch(uniqueFilePaths, undefined, client);
|
|
59
|
+
const urlMap = new Map();
|
|
60
|
+
uniqueFilePaths.forEach((path, index) => {
|
|
61
|
+
urlMap.set(path, signedUrls[index]);
|
|
62
|
+
});
|
|
63
|
+
const artifactsWithUrls = data.map((artifact) => ({
|
|
64
|
+
...artifact,
|
|
65
|
+
media_url: artifact.file_path
|
|
66
|
+
? urlMap.get(artifact.file_path) || null
|
|
67
|
+
: null,
|
|
68
|
+
}));
|
|
69
|
+
return IWebResponse.success(artifactsWithUrls).to_compatible();
|
|
70
|
+
}
|
|
71
|
+
export async function server_get_total_artifacts_by_herd(herd_id) {
|
|
72
|
+
const supabase = await newServerClient();
|
|
73
|
+
const { data, error } = await supabase.rpc("get_total_artifacts_for_herd", {
|
|
74
|
+
herd_id_caller: herd_id,
|
|
75
|
+
});
|
|
76
|
+
if (error) {
|
|
77
|
+
return IWebResponse.error(error.message).to_compatible();
|
|
78
|
+
}
|
|
79
|
+
return IWebResponse.success(data || 0).to_compatible();
|
|
80
|
+
}
|
|
81
|
+
export async function server_get_artifacts_by_device_ids_batch(device_ids, limit_per_device = 10, client) {
|
|
82
|
+
const supabase = client || (await newServerClient());
|
|
83
|
+
if (device_ids.length === 0) {
|
|
84
|
+
return {};
|
|
85
|
+
}
|
|
86
|
+
const { data, error } = await supabase.rpc("get_artifacts_for_devices_batch", {
|
|
87
|
+
device_ids: device_ids,
|
|
88
|
+
limit_per_device: limit_per_device,
|
|
89
|
+
});
|
|
90
|
+
if (error || !data) {
|
|
91
|
+
console.warn("Error fetching artifacts batch:", error?.message);
|
|
92
|
+
return {};
|
|
93
|
+
}
|
|
94
|
+
// Generate signed URLs for artifacts
|
|
95
|
+
const uniqueFilePaths = Array.from(new Set(data
|
|
96
|
+
.map((artifact) => artifact.file_path)
|
|
97
|
+
.filter((path) => !!path)));
|
|
98
|
+
let artifactsWithUrls = data;
|
|
99
|
+
if (uniqueFilePaths.length > 0) {
|
|
100
|
+
const signedUrls = await generateSignedUrlsBatch(uniqueFilePaths, undefined, client);
|
|
101
|
+
const urlMap = new Map();
|
|
102
|
+
uniqueFilePaths.forEach((path, index) => {
|
|
103
|
+
urlMap.set(path, signedUrls[index]);
|
|
104
|
+
});
|
|
105
|
+
artifactsWithUrls = data.map((artifact) => ({
|
|
106
|
+
...artifact,
|
|
107
|
+
media_url: artifact.file_path
|
|
108
|
+
? urlMap.get(artifact.file_path) || null
|
|
109
|
+
: null,
|
|
110
|
+
}));
|
|
111
|
+
}
|
|
112
|
+
// Group artifacts by device_id
|
|
113
|
+
const artifactsByDevice = {};
|
|
114
|
+
artifactsWithUrls.forEach((artifact) => {
|
|
115
|
+
if (!artifactsByDevice[artifact.device_id]) {
|
|
116
|
+
artifactsByDevice[artifact.device_id] = [];
|
|
117
|
+
}
|
|
118
|
+
artifactsByDevice[artifact.device_id].push(artifact);
|
|
119
|
+
});
|
|
120
|
+
return artifactsByDevice;
|
|
121
|
+
}
|
package/dist/helpers/index.d.ts
CHANGED
package/dist/helpers/index.js
CHANGED
|
@@ -3,18 +3,9 @@ import { Database } from "../types/supabase";
|
|
|
3
3
|
/**
|
|
4
4
|
* Generates a signed URL for a file in Supabase storage
|
|
5
5
|
* @param filePath - The path to the file in storage (e.g., "events/123/image.jpg")
|
|
6
|
-
* @param expiresIn - Number of seconds until the URL expires (default:
|
|
6
|
+
* @param expiresIn - Number of seconds until the URL expires (default: 12 hours)
|
|
7
7
|
* @param supabaseClient - Optional Supabase client (will create new one if not provided)
|
|
8
8
|
* @returns Promise<string | null> - The signed URL or null if error
|
|
9
9
|
*/
|
|
10
10
|
export declare function generateSignedUrl(filePath: string, expiresIn?: number, supabaseClient?: SupabaseClient<Database>): Promise<string | null>;
|
|
11
|
-
export declare function generateSignedUrlsBatch(filePaths: string[], expiresIn?: number, supabaseClient?: SupabaseClient<Database>): Promise<
|
|
12
|
-
export declare function addSignedUrlsToEventsBatch(events: any[], supabaseClient?: SupabaseClient<Database>): Promise<any[]>;
|
|
13
|
-
export declare function addSignedUrlsToEvents(events: any[], supabaseClient?: SupabaseClient<Database>): Promise<any[]>;
|
|
14
|
-
/**
|
|
15
|
-
* Generates a signed URL for a single event and sets it as media_url
|
|
16
|
-
* @param event - Event object that may have file_path
|
|
17
|
-
* @param supabaseClient - Optional Supabase client (will create new one if not provided)
|
|
18
|
-
* @returns Promise<Object> - Event with signed URL set as media_url
|
|
19
|
-
*/
|
|
20
|
-
export declare function addSignedUrlToEvent(event: any, supabaseClient?: SupabaseClient<Database>): Promise<any>;
|
|
11
|
+
export declare function generateSignedUrlsBatch(filePaths: string[], expiresIn?: number, supabaseClient?: SupabaseClient<Database>): Promise<(string | null)[]>;
|
package/dist/helpers/storage.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use server";
|
|
2
2
|
import { newServerClient } from "../supabase/server";
|
|
3
|
-
import { BUCKET_NAME_SCOUT } from "../constants/db";
|
|
3
|
+
import { BUCKET_NAME_SCOUT, SIGNED_URL_EXPIRATION_SECONDS, } from "../constants/db";
|
|
4
4
|
/**
|
|
5
5
|
* Generates a signed URL for a file in Supabase storage
|
|
6
6
|
* @param filePath - The path to the file in storage (e.g., "events/123/image.jpg")
|
|
7
|
-
* @param expiresIn - Number of seconds until the URL expires (default:
|
|
7
|
+
* @param expiresIn - Number of seconds until the URL expires (default: 12 hours)
|
|
8
8
|
* @param supabaseClient - Optional Supabase client (will create new one if not provided)
|
|
9
9
|
* @returns Promise<string | null> - The signed URL or null if error
|
|
10
10
|
*/
|
|
11
|
-
export async function generateSignedUrl(filePath, expiresIn =
|
|
11
|
+
export async function generateSignedUrl(filePath, expiresIn = SIGNED_URL_EXPIRATION_SECONDS, supabaseClient) {
|
|
12
12
|
try {
|
|
13
13
|
const supabase = supabaseClient || (await newServerClient());
|
|
14
14
|
const { data, error } = await supabase.storage
|
|
@@ -25,10 +25,9 @@ export async function generateSignedUrl(filePath, expiresIn = 3600, supabaseClie
|
|
|
25
25
|
return null;
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
-
export async function generateSignedUrlsBatch(filePaths, expiresIn =
|
|
28
|
+
export async function generateSignedUrlsBatch(filePaths, expiresIn = SIGNED_URL_EXPIRATION_SECONDS, supabaseClient) {
|
|
29
29
|
try {
|
|
30
30
|
const supabase = supabaseClient || (await newServerClient());
|
|
31
|
-
const urlMap = new Map();
|
|
32
31
|
const signedUrlPromises = filePaths.map(async (filePath) => {
|
|
33
32
|
try {
|
|
34
33
|
const { data, error } = await supabase.storage
|
|
@@ -36,63 +35,20 @@ export async function generateSignedUrlsBatch(filePaths, expiresIn = 3600, supab
|
|
|
36
35
|
.createSignedUrl(filePath, expiresIn);
|
|
37
36
|
if (error) {
|
|
38
37
|
console.error(`Error generating signed URL for ${filePath}:`, error.message);
|
|
39
|
-
return
|
|
38
|
+
return null;
|
|
40
39
|
}
|
|
41
|
-
return
|
|
40
|
+
return data.signedUrl;
|
|
42
41
|
}
|
|
43
42
|
catch (error) {
|
|
44
|
-
console.error(`
|
|
45
|
-
return
|
|
43
|
+
console.error(`Exception generating signed URL for ${filePath}:`, error);
|
|
44
|
+
return null;
|
|
46
45
|
}
|
|
47
46
|
});
|
|
48
47
|
const results = await Promise.all(signedUrlPromises);
|
|
49
|
-
results
|
|
50
|
-
urlMap.set(filePath, signedUrl);
|
|
51
|
-
});
|
|
52
|
-
return urlMap;
|
|
48
|
+
return results;
|
|
53
49
|
}
|
|
54
50
|
catch (error) {
|
|
55
51
|
console.error("Error in generateSignedUrlsBatch:", error);
|
|
56
|
-
return new
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
export async function addSignedUrlsToEventsBatch(events, supabaseClient) {
|
|
60
|
-
const filePaths = events
|
|
61
|
-
.map((event) => event.file_path)
|
|
62
|
-
.filter((path) => path)
|
|
63
|
-
.filter((path, index, array) => array.indexOf(path) === index);
|
|
64
|
-
if (filePaths.length === 0) {
|
|
65
|
-
return events;
|
|
66
|
-
}
|
|
67
|
-
const urlMap = await generateSignedUrlsBatch(filePaths, 3600, supabaseClient);
|
|
68
|
-
return events.map((event) => {
|
|
69
|
-
if (event.file_path && urlMap.has(event.file_path)) {
|
|
70
|
-
const signedUrl = urlMap.get(event.file_path);
|
|
71
|
-
return {
|
|
72
|
-
...event,
|
|
73
|
-
media_url: signedUrl || event.media_url,
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
return event;
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
export async function addSignedUrlsToEvents(events, supabaseClient) {
|
|
80
|
-
return addSignedUrlsToEventsBatch(events, supabaseClient);
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Generates a signed URL for a single event and sets it as media_url
|
|
84
|
-
* @param event - Event object that may have file_path
|
|
85
|
-
* @param supabaseClient - Optional Supabase client (will create new one if not provided)
|
|
86
|
-
* @returns Promise<Object> - Event with signed URL set as media_url
|
|
87
|
-
*/
|
|
88
|
-
export async function addSignedUrlToEvent(event, supabaseClient) {
|
|
89
|
-
// If event has a file_path, generate a signed URL and set it as media_url
|
|
90
|
-
if (event.file_path) {
|
|
91
|
-
const signedUrl = await generateSignedUrl(event.file_path, 3600, supabaseClient);
|
|
92
|
-
return {
|
|
93
|
-
...event,
|
|
94
|
-
media_url: signedUrl || event.media_url, // Fall back to existing media_url if signed URL fails
|
|
95
|
-
};
|
|
52
|
+
return new Array(filePaths.length).fill(null);
|
|
96
53
|
}
|
|
97
|
-
return event;
|
|
98
54
|
}
|
package/dist/helpers/tags.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// add tag to db
|
|
3
3
|
import { newServerClient } from "../supabase/server";
|
|
4
4
|
import { EnumWebResponse, IWebResponse, } from "../types/requests";
|
|
5
|
-
import {
|
|
5
|
+
import { generateSignedUrlsBatch, generateSignedUrl } from "./storage";
|
|
6
6
|
// Helper functions to extract coordinates from location field
|
|
7
7
|
function extractLatitude(location) {
|
|
8
8
|
try {
|
|
@@ -169,8 +169,22 @@ export async function server_get_more_events_with_tags_by_herd(herd_id, offset,
|
|
|
169
169
|
event.tags = event.tags.filter((tag) => tag !== null);
|
|
170
170
|
return event;
|
|
171
171
|
});
|
|
172
|
-
//
|
|
173
|
-
const
|
|
172
|
+
// Generate signed URLs for events
|
|
173
|
+
const filePaths = filtered_data
|
|
174
|
+
.map((event) => event.file_path)
|
|
175
|
+
.filter((path) => !!path);
|
|
176
|
+
let eventsWithSignedUrls = filtered_data;
|
|
177
|
+
if (filePaths.length > 0) {
|
|
178
|
+
const signedUrls = await generateSignedUrlsBatch(filePaths, undefined, supabase);
|
|
179
|
+
const urlMap = new Map();
|
|
180
|
+
filePaths.forEach((path, index) => {
|
|
181
|
+
urlMap.set(path, signedUrls[index]);
|
|
182
|
+
});
|
|
183
|
+
eventsWithSignedUrls = filtered_data.map((event) => ({
|
|
184
|
+
...event,
|
|
185
|
+
media_url: event.file_path ? urlMap.get(event.file_path) || null : null,
|
|
186
|
+
}));
|
|
187
|
+
}
|
|
174
188
|
return IWebResponse.success(eventsWithSignedUrls).to_compatible();
|
|
175
189
|
}
|
|
176
190
|
export async function server_get_events_and_tags_for_device(device_id, limit = 3) {
|
|
@@ -188,8 +202,23 @@ export async function server_get_events_and_tags_for_device(device_id, limit = 3
|
|
|
188
202
|
data: [],
|
|
189
203
|
};
|
|
190
204
|
}
|
|
191
|
-
//
|
|
192
|
-
const
|
|
205
|
+
// Generate signed URLs for events
|
|
206
|
+
const eventData = data || [];
|
|
207
|
+
const filePaths = eventData
|
|
208
|
+
.map((event) => event.file_path)
|
|
209
|
+
.filter((path) => !!path);
|
|
210
|
+
let eventsWithSignedUrls = eventData;
|
|
211
|
+
if (filePaths.length > 0) {
|
|
212
|
+
const signedUrls = await generateSignedUrlsBatch(filePaths, undefined, supabase);
|
|
213
|
+
const urlMap = new Map();
|
|
214
|
+
filePaths.forEach((path, index) => {
|
|
215
|
+
urlMap.set(path, signedUrls[index]);
|
|
216
|
+
});
|
|
217
|
+
eventsWithSignedUrls = eventData.map((event) => ({
|
|
218
|
+
...event,
|
|
219
|
+
media_url: event.file_path ? urlMap.get(event.file_path) || null : null,
|
|
220
|
+
}));
|
|
221
|
+
}
|
|
193
222
|
return IWebResponse.success(eventsWithSignedUrls).to_compatible();
|
|
194
223
|
}
|
|
195
224
|
export async function server_get_events_and_tags_for_devices_batch(device_ids, limit = 1) {
|
|
@@ -256,9 +285,31 @@ export async function server_get_events_and_tags_for_devices_batch(device_ids, l
|
|
|
256
285
|
});
|
|
257
286
|
// Add signed URLs to all events
|
|
258
287
|
const result = {};
|
|
288
|
+
// Get all file paths for batch URL generation
|
|
289
|
+
const allFilePaths = [];
|
|
290
|
+
for (const device_id in eventsByDevice) {
|
|
291
|
+
const events = eventsByDevice[device_id];
|
|
292
|
+
events.forEach((event) => {
|
|
293
|
+
if (event.file_path && !allFilePaths.includes(event.file_path)) {
|
|
294
|
+
allFilePaths.push(event.file_path);
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
// Generate all signed URLs at once
|
|
299
|
+
const signedUrls = allFilePaths.length > 0
|
|
300
|
+
? await generateSignedUrlsBatch(allFilePaths, undefined, supabase)
|
|
301
|
+
: [];
|
|
302
|
+
const urlMap = new Map();
|
|
303
|
+
allFilePaths.forEach((path, index) => {
|
|
304
|
+
urlMap.set(path, signedUrls[index]);
|
|
305
|
+
});
|
|
306
|
+
// Apply signed URLs to events
|
|
259
307
|
for (const device_id in eventsByDevice) {
|
|
260
308
|
const events = eventsByDevice[device_id];
|
|
261
|
-
const eventsWithSignedUrls =
|
|
309
|
+
const eventsWithSignedUrls = events.map((event) => ({
|
|
310
|
+
...event,
|
|
311
|
+
media_url: event.file_path ? urlMap.get(event.file_path) || null : null,
|
|
312
|
+
}));
|
|
262
313
|
result[parseInt(device_id)] = eventsWithSignedUrls;
|
|
263
314
|
}
|
|
264
315
|
return IWebResponse.success(result).to_compatible();
|
|
@@ -369,7 +420,14 @@ export async function get_event_and_tags_by_event_id(event_id) {
|
|
|
369
420
|
earthranger_url: data[0].earthranger_url,
|
|
370
421
|
file_path: data[0].file_path,
|
|
371
422
|
};
|
|
372
|
-
//
|
|
373
|
-
|
|
423
|
+
// Generate signed URL for event
|
|
424
|
+
let eventWithSignedUrl = transformedData;
|
|
425
|
+
if (transformedData.file_path) {
|
|
426
|
+
const signedUrl = await generateSignedUrl(transformedData.file_path, undefined, supabase);
|
|
427
|
+
eventWithSignedUrl = {
|
|
428
|
+
...transformedData,
|
|
429
|
+
media_url: signedUrl,
|
|
430
|
+
};
|
|
431
|
+
}
|
|
374
432
|
return IWebResponse.success(eventWithSignedUrl).to_compatible();
|
|
375
433
|
}
|
|
@@ -1037,6 +1037,74 @@ export declare function useSupabase(): SupabaseClient<Database, "public", "publi
|
|
|
1037
1037
|
status: string;
|
|
1038
1038
|
}[];
|
|
1039
1039
|
};
|
|
1040
|
+
get_artifacts_for_device: {
|
|
1041
|
+
Args: {
|
|
1042
|
+
device_id_caller: number;
|
|
1043
|
+
limit_caller?: number;
|
|
1044
|
+
offset_caller?: number;
|
|
1045
|
+
};
|
|
1046
|
+
Returns: {
|
|
1047
|
+
created_at: string;
|
|
1048
|
+
device_id: number;
|
|
1049
|
+
file_path: string;
|
|
1050
|
+
id: number;
|
|
1051
|
+
modality: string | null;
|
|
1052
|
+
session_id: number | null;
|
|
1053
|
+
timestamp_observation: string | null;
|
|
1054
|
+
updated_at: string | null;
|
|
1055
|
+
}[];
|
|
1056
|
+
SetofOptions: {
|
|
1057
|
+
from: "*";
|
|
1058
|
+
to: "artifacts";
|
|
1059
|
+
isOneToOne: false;
|
|
1060
|
+
isSetofReturn: true;
|
|
1061
|
+
};
|
|
1062
|
+
};
|
|
1063
|
+
get_artifacts_for_devices_batch: {
|
|
1064
|
+
Args: {
|
|
1065
|
+
device_ids: number[];
|
|
1066
|
+
limit_per_device?: number;
|
|
1067
|
+
};
|
|
1068
|
+
Returns: {
|
|
1069
|
+
created_at: string;
|
|
1070
|
+
device_id: number;
|
|
1071
|
+
file_path: string;
|
|
1072
|
+
id: number;
|
|
1073
|
+
modality: string | null;
|
|
1074
|
+
session_id: number | null;
|
|
1075
|
+
timestamp_observation: string | null;
|
|
1076
|
+
updated_at: string | null;
|
|
1077
|
+
}[];
|
|
1078
|
+
SetofOptions: {
|
|
1079
|
+
from: "*";
|
|
1080
|
+
to: "artifacts";
|
|
1081
|
+
isOneToOne: false;
|
|
1082
|
+
isSetofReturn: true;
|
|
1083
|
+
};
|
|
1084
|
+
};
|
|
1085
|
+
get_artifacts_for_herd: {
|
|
1086
|
+
Args: {
|
|
1087
|
+
herd_id_caller: number;
|
|
1088
|
+
limit_caller?: number;
|
|
1089
|
+
offset_caller?: number;
|
|
1090
|
+
};
|
|
1091
|
+
Returns: {
|
|
1092
|
+
created_at: string;
|
|
1093
|
+
device_id: number;
|
|
1094
|
+
file_path: string;
|
|
1095
|
+
id: number;
|
|
1096
|
+
modality: string | null;
|
|
1097
|
+
session_id: number | null;
|
|
1098
|
+
timestamp_observation: string | null;
|
|
1099
|
+
updated_at: string | null;
|
|
1100
|
+
}[];
|
|
1101
|
+
SetofOptions: {
|
|
1102
|
+
from: "*";
|
|
1103
|
+
to: "artifacts";
|
|
1104
|
+
isOneToOne: false;
|
|
1105
|
+
isSetofReturn: true;
|
|
1106
|
+
};
|
|
1107
|
+
};
|
|
1040
1108
|
get_connectivity_with_coordinates: {
|
|
1041
1109
|
Args: {
|
|
1042
1110
|
session_id_caller: number;
|
|
@@ -1212,6 +1280,12 @@ export declare function useSupabase(): SupabaseClient<Database, "public", "publi
|
|
|
1212
1280
|
isSetofReturn: true;
|
|
1213
1281
|
};
|
|
1214
1282
|
};
|
|
1283
|
+
get_total_artifacts_for_herd: {
|
|
1284
|
+
Args: {
|
|
1285
|
+
herd_id_caller: number;
|
|
1286
|
+
};
|
|
1287
|
+
Returns: number;
|
|
1288
|
+
};
|
|
1215
1289
|
get_total_events_for_herd_with_session_filter: {
|
|
1216
1290
|
Args: {
|
|
1217
1291
|
exclude_session_events: boolean;
|
package/dist/store/scout.d.ts
CHANGED
|
@@ -88,6 +88,14 @@ export declare const scoutSlice: import("@reduxjs/toolkit").Slice<ScoutState, {
|
|
|
88
88
|
payload: any;
|
|
89
89
|
type: string;
|
|
90
90
|
}) => void;
|
|
91
|
+
replaceArtifactsForHerdModule: (state: import("immer").WritableDraft<ScoutState>, action: {
|
|
92
|
+
payload: any;
|
|
93
|
+
type: string;
|
|
94
|
+
}) => void;
|
|
95
|
+
appendArtifactsToHerdModule: (state: import("immer").WritableDraft<ScoutState>, action: {
|
|
96
|
+
payload: any;
|
|
97
|
+
type: string;
|
|
98
|
+
}) => void;
|
|
91
99
|
appendPlansToHerdModule: (state: import("immer").WritableDraft<ScoutState>, action: {
|
|
92
100
|
payload: any;
|
|
93
101
|
type: string;
|
|
@@ -165,6 +173,6 @@ export declare const scoutSlice: import("@reduxjs/toolkit").Slice<ScoutState, {
|
|
|
165
173
|
type: string;
|
|
166
174
|
}) => void;
|
|
167
175
|
}, "scout", "scout", import("@reduxjs/toolkit").SliceSelectors<ScoutState>>;
|
|
168
|
-
export declare const setHerdModules: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setHerdModules">, setStatus: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setStatus">, setHerdModulesLoadingState: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setHerdModulesLoadingState">, setHerdModulesLoadedInMs: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setHerdModulesLoadedInMs">, setHerdModulesApiServerProcessingDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setHerdModulesApiServerProcessingDuration">, setHerdModulesApiTotalRequestDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setHerdModulesApiTotalRequestDuration">, setUserApiDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setUserApiDuration">, setDataProcessingDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setDataProcessingDuration">, setCacheLoadDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setCacheLoadDuration">, setActiveHerdId: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setActiveHerdId">, setActiveDeviceId: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setActiveDeviceId">, setDataSource: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setDataSource">, setDataSourceInfo: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setDataSourceInfo">, appendEventsToHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/appendEventsToHerdModule">, replaceEventsForHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/replaceEventsForHerdModule">, updateEventValuesForHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updateEventValuesForHerdModule">, updatePageIndexForHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updatePageIndexForHerdModule">, appendPlansToHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/appendPlansToHerdModule">, setUser: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setUser">, addTag: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/addTag">, deleteTag: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/deleteTag">, updateTag: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updateTag">, addNewDeviceToHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/addNewDeviceToHerdModule">, updateDeviceForHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updateDeviceForHerdModule">, addDevice: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/addDevice">, deleteDevice: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/deleteDevice">, updateDevice: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updateDevice">, addPlan: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/addPlan">, deletePlan: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/deletePlan">, updatePlan: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updatePlan">, addSessionToStore: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/addSessionToStore">, deleteSessionFromStore: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/deleteSessionFromStore">, updateSessionInStore: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updateSessionInStore">, setActiveHerdGpsTrackersConnectivity: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setActiveHerdGpsTrackersConnectivity">;
|
|
176
|
+
export declare const setHerdModules: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setHerdModules">, setStatus: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setStatus">, setHerdModulesLoadingState: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setHerdModulesLoadingState">, setHerdModulesLoadedInMs: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setHerdModulesLoadedInMs">, setHerdModulesApiServerProcessingDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setHerdModulesApiServerProcessingDuration">, setHerdModulesApiTotalRequestDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setHerdModulesApiTotalRequestDuration">, setUserApiDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setUserApiDuration">, setDataProcessingDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setDataProcessingDuration">, setCacheLoadDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setCacheLoadDuration">, setActiveHerdId: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setActiveHerdId">, setActiveDeviceId: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setActiveDeviceId">, setDataSource: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setDataSource">, setDataSourceInfo: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setDataSourceInfo">, appendEventsToHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/appendEventsToHerdModule">, replaceEventsForHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/replaceEventsForHerdModule">, appendArtifactsToHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/appendArtifactsToHerdModule">, replaceArtifactsForHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/replaceArtifactsForHerdModule">, updateEventValuesForHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updateEventValuesForHerdModule">, updatePageIndexForHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updatePageIndexForHerdModule">, appendPlansToHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/appendPlansToHerdModule">, setUser: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setUser">, addTag: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/addTag">, deleteTag: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/deleteTag">, updateTag: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updateTag">, addNewDeviceToHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/addNewDeviceToHerdModule">, updateDeviceForHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updateDeviceForHerdModule">, addDevice: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/addDevice">, deleteDevice: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/deleteDevice">, updateDevice: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updateDevice">, addPlan: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/addPlan">, deletePlan: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/deletePlan">, updatePlan: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updatePlan">, addSessionToStore: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/addSessionToStore">, deleteSessionFromStore: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/deleteSessionFromStore">, updateSessionInStore: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updateSessionInStore">, setActiveHerdGpsTrackersConnectivity: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setActiveHerdGpsTrackersConnectivity">;
|
|
169
177
|
declare const _default: import("redux").Reducer<ScoutState>;
|
|
170
178
|
export default _default;
|
package/dist/store/scout.js
CHANGED
|
@@ -85,6 +85,20 @@ export const scoutSlice = createSlice({
|
|
|
85
85
|
herd_module.events = [...herd_module.events, ...events];
|
|
86
86
|
}
|
|
87
87
|
},
|
|
88
|
+
replaceArtifactsForHerdModule: (state, action) => {
|
|
89
|
+
const { herd_id, artifacts } = action.payload;
|
|
90
|
+
const herd_module = state.herd_modules.find((hm) => hm.herd.id.toString() === herd_id);
|
|
91
|
+
if (herd_module) {
|
|
92
|
+
herd_module.artifacts = artifacts;
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
appendArtifactsToHerdModule: (state, action) => {
|
|
96
|
+
const { herd_id, artifacts } = action.payload;
|
|
97
|
+
const herd_module = state.herd_modules.find((hm) => hm.herd.id.toString() === herd_id);
|
|
98
|
+
if (herd_module) {
|
|
99
|
+
herd_module.artifacts = [...herd_module.artifacts, ...artifacts];
|
|
100
|
+
}
|
|
101
|
+
},
|
|
88
102
|
appendPlansToHerdModule: (state, action) => {
|
|
89
103
|
const { herd_id, plan } = action.payload;
|
|
90
104
|
const herd_module = state.herd_modules.find((hm) => hm.herd.id.toString() === herd_id);
|
|
@@ -273,5 +287,5 @@ export const scoutSlice = createSlice({
|
|
|
273
287
|
},
|
|
274
288
|
});
|
|
275
289
|
// Action creators are generated for each case reducer function
|
|
276
|
-
export const { setHerdModules, setStatus, setHerdModulesLoadingState, setHerdModulesLoadedInMs, setHerdModulesApiServerProcessingDuration, setHerdModulesApiTotalRequestDuration, setUserApiDuration, setDataProcessingDuration, setCacheLoadDuration, setActiveHerdId, setActiveDeviceId, setDataSource, setDataSourceInfo, appendEventsToHerdModule, replaceEventsForHerdModule, updateEventValuesForHerdModule, updatePageIndexForHerdModule, appendPlansToHerdModule, setUser, addTag, deleteTag, updateTag, addNewDeviceToHerdModule, updateDeviceForHerdModule, addDevice, deleteDevice, updateDevice, addPlan, deletePlan, updatePlan, addSessionToStore, deleteSessionFromStore, updateSessionInStore, setActiveHerdGpsTrackersConnectivity, } = scoutSlice.actions;
|
|
290
|
+
export const { setHerdModules, setStatus, setHerdModulesLoadingState, setHerdModulesLoadedInMs, setHerdModulesApiServerProcessingDuration, setHerdModulesApiTotalRequestDuration, setUserApiDuration, setDataProcessingDuration, setCacheLoadDuration, setActiveHerdId, setActiveDeviceId, setDataSource, setDataSourceInfo, appendEventsToHerdModule, replaceEventsForHerdModule, appendArtifactsToHerdModule, replaceArtifactsForHerdModule, updateEventValuesForHerdModule, updatePageIndexForHerdModule, appendPlansToHerdModule, setUser, addTag, deleteTag, updateTag, addNewDeviceToHerdModule, updateDeviceForHerdModule, addDevice, deleteDevice, updateDevice, addPlan, deletePlan, updatePlan, addSessionToStore, deleteSessionFromStore, updateSessionInStore, setActiveHerdGpsTrackersConnectivity, } = scoutSlice.actions;
|
|
277
291
|
export default scoutSlice.reducer;
|
package/dist/types/db.d.ts
CHANGED
|
@@ -26,8 +26,13 @@ export type IOperator = Database["public"]["Tables"]["operators"]["Row"];
|
|
|
26
26
|
export type IProvider = Database["public"]["Tables"]["providers"]["Row"];
|
|
27
27
|
export type IComponent = Database["public"]["Tables"]["components"]["Row"];
|
|
28
28
|
export type IVersionsSoftware = Database["public"]["Tables"]["versions_software"]["Row"];
|
|
29
|
+
export type IArtifact = Database["public"]["Tables"]["artifacts"]["Row"];
|
|
30
|
+
export type IArtifactWithMediaUrl = IArtifact & {
|
|
31
|
+
media_url?: string | null;
|
|
32
|
+
};
|
|
29
33
|
export type ComponentInsert = Database["public"]["Tables"]["components"]["Insert"];
|
|
30
34
|
export type VersionsSoftwareInsert = Database["public"]["Tables"]["versions_software"]["Insert"];
|
|
35
|
+
export type ArtifactInsert = Database["public"]["Tables"]["artifacts"]["Insert"];
|
|
31
36
|
export type IEventWithTags = Database["public"]["CompositeTypes"]["event_with_tags"] & {
|
|
32
37
|
earthranger_url: string | null;
|
|
33
38
|
file_path: string | null;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SupabaseClient } from "@supabase/supabase-js";
|
|
2
|
-
import { IDevice, IEventWithTags, IHerd, IPlan, ILayer, IProvider, IUserAndRole, IZoneWithActions, ISessionWithCoordinates } from "../types/db";
|
|
2
|
+
import { IDevice, IEventWithTags, IHerd, IPlan, ILayer, IProvider, IUserAndRole, IZoneWithActions, ISessionWithCoordinates, IArtifactWithMediaUrl } from "../types/db";
|
|
3
3
|
import { EnumWebResponse } from "./requests";
|
|
4
4
|
export declare enum EnumHerdModulesLoadingState {
|
|
5
5
|
NOT_LOADING = "NOT_LOADING",
|
|
@@ -13,16 +13,18 @@ export declare class HerdModule {
|
|
|
13
13
|
events: IEventWithTags[];
|
|
14
14
|
zones: IZoneWithActions[];
|
|
15
15
|
sessions: ISessionWithCoordinates[];
|
|
16
|
+
artifacts: IArtifactWithMediaUrl[];
|
|
16
17
|
timestamp_last_refreshed: number;
|
|
17
18
|
user_roles: IUserAndRole[] | null;
|
|
18
19
|
events_page_index: number;
|
|
19
20
|
total_events: number;
|
|
20
21
|
total_events_with_filters: number;
|
|
22
|
+
total_artifacts: number;
|
|
21
23
|
labels: string[];
|
|
22
24
|
plans: IPlan[];
|
|
23
25
|
layers: ILayer[];
|
|
24
26
|
providers: IProvider[];
|
|
25
|
-
constructor(herd: IHerd, devices: IDevice[], events: IEventWithTags[], timestamp_last_refreshed: number, user_roles?: IUserAndRole[] | null, events_page_index?: number, total_events?: number, total_events_with_filters?: number, labels?: string[], plans?: IPlan[], zones?: IZoneWithActions[], sessions?: ISessionWithCoordinates[], layers?: ILayer[], providers?: IProvider[]);
|
|
27
|
+
constructor(herd: IHerd, devices: IDevice[], events: IEventWithTags[], timestamp_last_refreshed: number, user_roles?: IUserAndRole[] | null, events_page_index?: number, total_events?: number, total_events_with_filters?: number, labels?: string[], plans?: IPlan[], zones?: IZoneWithActions[], sessions?: ISessionWithCoordinates[], layers?: ILayer[], providers?: IProvider[], artifacts?: IArtifactWithMediaUrl[], total_artifacts?: number);
|
|
26
28
|
to_serializable(): IHerdModule;
|
|
27
29
|
static from_herd(herd: IHerd, client: SupabaseClient): Promise<HerdModule>;
|
|
28
30
|
}
|
|
@@ -41,6 +43,8 @@ export interface IHerdModule {
|
|
|
41
43
|
sessions: ISessionWithCoordinates[];
|
|
42
44
|
layers: ILayer[];
|
|
43
45
|
providers: IProvider[];
|
|
46
|
+
artifacts: IArtifactWithMediaUrl[];
|
|
47
|
+
total_artifacts: number;
|
|
44
48
|
}
|
|
45
49
|
export interface IHerdModulesResponse {
|
|
46
50
|
data: IHerdModule[];
|
|
@@ -10,6 +10,7 @@ import { EnumWebResponse } from "./requests";
|
|
|
10
10
|
import { server_get_more_zones_and_actions_for_herd } from "../helpers/zones";
|
|
11
11
|
import { server_list_api_keys_batch } from "../api_keys/actions";
|
|
12
12
|
import { server_get_sessions_by_herd_id } from "../helpers/sessions";
|
|
13
|
+
import { server_get_artifacts_by_herd, server_get_total_artifacts_by_herd, } from "../helpers/artifacts";
|
|
13
14
|
export var EnumHerdModulesLoadingState;
|
|
14
15
|
(function (EnumHerdModulesLoadingState) {
|
|
15
16
|
EnumHerdModulesLoadingState["NOT_LOADING"] = "NOT_LOADING";
|
|
@@ -18,11 +19,12 @@ export var EnumHerdModulesLoadingState;
|
|
|
18
19
|
EnumHerdModulesLoadingState["UNSUCCESSFULLY_LOADED"] = "UNSUCCESSFULLY_LOADED";
|
|
19
20
|
})(EnumHerdModulesLoadingState || (EnumHerdModulesLoadingState = {}));
|
|
20
21
|
export class HerdModule {
|
|
21
|
-
constructor(herd, devices, events, timestamp_last_refreshed, user_roles = null, events_page_index = 0, total_events = 0, total_events_with_filters = 0, labels = [], plans = [], zones = [], sessions = [], layers = [], providers = []) {
|
|
22
|
+
constructor(herd, devices, events, timestamp_last_refreshed, user_roles = null, events_page_index = 0, total_events = 0, total_events_with_filters = 0, labels = [], plans = [], zones = [], sessions = [], layers = [], providers = [], artifacts = [], total_artifacts = 0) {
|
|
22
23
|
this.user_roles = null;
|
|
23
24
|
this.events_page_index = 0;
|
|
24
25
|
this.total_events = 0;
|
|
25
26
|
this.total_events_with_filters = 0;
|
|
27
|
+
this.total_artifacts = 0;
|
|
26
28
|
this.labels = [];
|
|
27
29
|
this.plans = [];
|
|
28
30
|
this.layers = [];
|
|
@@ -41,6 +43,8 @@ export class HerdModule {
|
|
|
41
43
|
this.sessions = sessions;
|
|
42
44
|
this.layers = layers;
|
|
43
45
|
this.providers = providers;
|
|
46
|
+
this.artifacts = artifacts;
|
|
47
|
+
this.total_artifacts = total_artifacts;
|
|
44
48
|
}
|
|
45
49
|
to_serializable() {
|
|
46
50
|
return {
|
|
@@ -58,6 +62,8 @@ export class HerdModule {
|
|
|
58
62
|
sessions: this.sessions,
|
|
59
63
|
layers: this.layers,
|
|
60
64
|
providers: this.providers,
|
|
65
|
+
artifacts: this.artifacts,
|
|
66
|
+
total_artifacts: this.total_artifacts,
|
|
61
67
|
};
|
|
62
68
|
}
|
|
63
69
|
static async from_herd(herd, client) {
|
|
@@ -97,6 +103,14 @@ export class HerdModule {
|
|
|
97
103
|
console.warn(`[HerdModule] Failed to get providers:`, error);
|
|
98
104
|
return { status: EnumWebResponse.ERROR, data: null };
|
|
99
105
|
}),
|
|
106
|
+
server_get_artifacts_by_herd(herd.id, 50, 0).catch((error) => {
|
|
107
|
+
console.warn(`[HerdModule] Failed to get artifacts:`, error);
|
|
108
|
+
return { status: EnumWebResponse.ERROR, data: null };
|
|
109
|
+
}),
|
|
110
|
+
server_get_total_artifacts_by_herd(herd.id).catch((error) => {
|
|
111
|
+
console.warn(`[HerdModule] Failed to get total artifacts count:`, error);
|
|
112
|
+
return { status: EnumWebResponse.ERROR, data: null };
|
|
113
|
+
}),
|
|
100
114
|
]);
|
|
101
115
|
// Load devices
|
|
102
116
|
const devicesPromise = get_devices_by_herd(herd.id, client);
|
|
@@ -129,7 +143,7 @@ export class HerdModule {
|
|
|
129
143
|
}
|
|
130
144
|
}
|
|
131
145
|
// Extract herd-level data with safe fallbacks
|
|
132
|
-
const [res_zones, res_user_roles, total_event_count, res_plans, res_sessions, res_layers, res_providers,] = herdLevelResults;
|
|
146
|
+
const [res_zones, res_user_roles, total_event_count, res_plans, res_sessions, res_layers, res_providers, res_artifacts, total_artifact_count,] = herdLevelResults;
|
|
133
147
|
const zones = res_zones.status === "fulfilled" && res_zones.value?.data
|
|
134
148
|
? res_zones.value.data
|
|
135
149
|
: [];
|
|
@@ -152,19 +166,26 @@ export class HerdModule {
|
|
|
152
166
|
const providers = res_providers.status === "fulfilled" && res_providers.value?.data
|
|
153
167
|
? res_providers.value.data
|
|
154
168
|
: [];
|
|
169
|
+
const artifacts = res_artifacts.status === "fulfilled" && res_artifacts.value?.data
|
|
170
|
+
? res_artifacts.value.data
|
|
171
|
+
: [];
|
|
172
|
+
const total_artifacts = total_artifact_count.status === "fulfilled" &&
|
|
173
|
+
total_artifact_count.value?.data
|
|
174
|
+
? total_artifact_count.value.data
|
|
175
|
+
: 0;
|
|
155
176
|
// TODO: store in DB and retrieve on load?
|
|
156
177
|
const newLabels = LABELS;
|
|
157
178
|
const endTime = Date.now();
|
|
158
179
|
const loadTime = endTime - startTime;
|
|
159
180
|
console.log(`[HerdModule] Loaded herd ${herd.slug} in ${loadTime}ms (${new_devices.length} devices)`);
|
|
160
|
-
return new HerdModule(herd, new_devices, [], Date.now(), user_roles, 0, total_events, total_events, newLabels, plans, zones, sessions, layers, providers);
|
|
181
|
+
return new HerdModule(herd, new_devices, [], Date.now(), user_roles, 0, total_events, total_events, newLabels, plans, zones, sessions, layers, providers, artifacts, total_artifacts);
|
|
161
182
|
}
|
|
162
183
|
catch (error) {
|
|
163
184
|
const endTime = Date.now();
|
|
164
185
|
const loadTime = endTime - startTime;
|
|
165
186
|
console.error(`[HerdModule] Critical error in HerdModule.from_herd (${loadTime}ms):`, error);
|
|
166
187
|
// Return a minimal but valid HerdModule instance to prevent complete failure
|
|
167
|
-
return new HerdModule(herd, [], [], Date.now(), null, 0, 0, 0, [], [], [], [], [], []);
|
|
188
|
+
return new HerdModule(herd, [], [], Date.now(), null, 0, 0, 0, [], [], [], [], [], [], [], 0);
|
|
168
189
|
}
|
|
169
190
|
}
|
|
170
191
|
}
|
package/dist/types/supabase.d.ts
CHANGED
|
@@ -1091,6 +1091,74 @@ export type Database = {
|
|
|
1091
1091
|
status: string;
|
|
1092
1092
|
}[];
|
|
1093
1093
|
};
|
|
1094
|
+
get_artifacts_for_device: {
|
|
1095
|
+
Args: {
|
|
1096
|
+
device_id_caller: number;
|
|
1097
|
+
limit_caller?: number;
|
|
1098
|
+
offset_caller?: number;
|
|
1099
|
+
};
|
|
1100
|
+
Returns: {
|
|
1101
|
+
created_at: string;
|
|
1102
|
+
device_id: number;
|
|
1103
|
+
file_path: string;
|
|
1104
|
+
id: number;
|
|
1105
|
+
modality: string | null;
|
|
1106
|
+
session_id: number | null;
|
|
1107
|
+
timestamp_observation: string | null;
|
|
1108
|
+
updated_at: string | null;
|
|
1109
|
+
}[];
|
|
1110
|
+
SetofOptions: {
|
|
1111
|
+
from: "*";
|
|
1112
|
+
to: "artifacts";
|
|
1113
|
+
isOneToOne: false;
|
|
1114
|
+
isSetofReturn: true;
|
|
1115
|
+
};
|
|
1116
|
+
};
|
|
1117
|
+
get_artifacts_for_devices_batch: {
|
|
1118
|
+
Args: {
|
|
1119
|
+
device_ids: number[];
|
|
1120
|
+
limit_per_device?: number;
|
|
1121
|
+
};
|
|
1122
|
+
Returns: {
|
|
1123
|
+
created_at: string;
|
|
1124
|
+
device_id: number;
|
|
1125
|
+
file_path: string;
|
|
1126
|
+
id: number;
|
|
1127
|
+
modality: string | null;
|
|
1128
|
+
session_id: number | null;
|
|
1129
|
+
timestamp_observation: string | null;
|
|
1130
|
+
updated_at: string | null;
|
|
1131
|
+
}[];
|
|
1132
|
+
SetofOptions: {
|
|
1133
|
+
from: "*";
|
|
1134
|
+
to: "artifacts";
|
|
1135
|
+
isOneToOne: false;
|
|
1136
|
+
isSetofReturn: true;
|
|
1137
|
+
};
|
|
1138
|
+
};
|
|
1139
|
+
get_artifacts_for_herd: {
|
|
1140
|
+
Args: {
|
|
1141
|
+
herd_id_caller: number;
|
|
1142
|
+
limit_caller?: number;
|
|
1143
|
+
offset_caller?: number;
|
|
1144
|
+
};
|
|
1145
|
+
Returns: {
|
|
1146
|
+
created_at: string;
|
|
1147
|
+
device_id: number;
|
|
1148
|
+
file_path: string;
|
|
1149
|
+
id: number;
|
|
1150
|
+
modality: string | null;
|
|
1151
|
+
session_id: number | null;
|
|
1152
|
+
timestamp_observation: string | null;
|
|
1153
|
+
updated_at: string | null;
|
|
1154
|
+
}[];
|
|
1155
|
+
SetofOptions: {
|
|
1156
|
+
from: "*";
|
|
1157
|
+
to: "artifacts";
|
|
1158
|
+
isOneToOne: false;
|
|
1159
|
+
isSetofReturn: true;
|
|
1160
|
+
};
|
|
1161
|
+
};
|
|
1094
1162
|
get_connectivity_with_coordinates: {
|
|
1095
1163
|
Args: {
|
|
1096
1164
|
session_id_caller: number;
|
|
@@ -1266,6 +1334,12 @@ export type Database = {
|
|
|
1266
1334
|
isSetofReturn: true;
|
|
1267
1335
|
};
|
|
1268
1336
|
};
|
|
1337
|
+
get_total_artifacts_for_herd: {
|
|
1338
|
+
Args: {
|
|
1339
|
+
herd_id_caller: number;
|
|
1340
|
+
};
|
|
1341
|
+
Returns: number;
|
|
1342
|
+
};
|
|
1269
1343
|
get_total_events_for_herd_with_session_filter: {
|
|
1270
1344
|
Args: {
|
|
1271
1345
|
exclude_session_events: boolean;
|