@adventurelabs/scout-core 1.0.23 → 1.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.
- package/LICENSE +594 -0
- package/README.md +21 -21
- package/dist/helpers/index.d.ts +1 -0
- package/dist/helpers/index.js +1 -0
- package/dist/helpers/sessions.d.ts +30 -0
- package/dist/helpers/sessions.js +241 -0
- package/dist/hooks/useScoutDbListener.js +12 -0
- package/dist/providers/ScoutRefreshProvider.d.ts +130 -6
- package/dist/store/scout.js +6 -0
- package/dist/supabase/server.d.ts +130 -6
- package/dist/types/db.d.ts +18 -1
- package/dist/types/db.js +1 -16
- package/dist/types/supabase.d.ts +135 -6
- package/package.json +5 -5
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { SupabaseClient } from "@supabase/supabase-js";
|
|
2
|
+
import { Database } from "../types/supabase";
|
|
3
|
+
import { ISession, IConnectivity, IEvent } from "../types/db";
|
|
4
|
+
export type SessionInput = Omit<ISession, "id" | "inserted_at">;
|
|
5
|
+
export type SessionUpdateInput = Partial<SessionInput> & {
|
|
6
|
+
id: number;
|
|
7
|
+
};
|
|
8
|
+
export type SessionUpsertInput = SessionInput | SessionUpdateInput;
|
|
9
|
+
export type ConnectivityInput = Omit<IConnectivity, "id" | "inserted_at">;
|
|
10
|
+
export type ConnectivityUpdateInput = Partial<ConnectivityInput> & {
|
|
11
|
+
id: number;
|
|
12
|
+
};
|
|
13
|
+
export type ConnectivityUpsertInput = ConnectivityInput | ConnectivityUpdateInput;
|
|
14
|
+
export declare function getSessionsByHerdId(supabase: SupabaseClient<Database>, herdId: number): Promise<ISession[]>;
|
|
15
|
+
export declare function getConnectivityBySessionId(supabase: SupabaseClient<Database>, sessionId: number): Promise<IConnectivity[]>;
|
|
16
|
+
export declare function getEventsBySessionId(supabase: SupabaseClient<Database>, sessionId: number): Promise<IEvent[]>;
|
|
17
|
+
export declare function upsertSession(supabase: SupabaseClient<Database>, sessionData: SessionUpsertInput): Promise<ISession>;
|
|
18
|
+
export declare function upsertSessions(supabase: SupabaseClient<Database>, sessionsData: SessionUpsertInput[]): Promise<ISession[]>;
|
|
19
|
+
export declare function upsertConnectivity(supabase: SupabaseClient<Database>, connectivityData: ConnectivityUpsertInput): Promise<IConnectivity>;
|
|
20
|
+
export declare function upsertConnectivityBatch(supabase: SupabaseClient<Database>, connectivityDataArray: ConnectivityUpsertInput[]): Promise<IConnectivity[]>;
|
|
21
|
+
export declare function getSessionWithConnectivityAndEvents(supabase: SupabaseClient<Database>, sessionId: number): Promise<{
|
|
22
|
+
session: ISession;
|
|
23
|
+
connectivity: IConnectivity[];
|
|
24
|
+
events: IEvent[];
|
|
25
|
+
}>;
|
|
26
|
+
export declare function getSessionsByDeviceId(supabase: SupabaseClient<Database>, deviceId: number): Promise<ISession[]>;
|
|
27
|
+
export declare function deleteSession(supabase: SupabaseClient<Database>, sessionId: number): Promise<void>;
|
|
28
|
+
export declare function deleteSessions(supabase: SupabaseClient<Database>, sessionIds: number[]): Promise<void>;
|
|
29
|
+
export declare function deleteConnectivity(supabase: SupabaseClient<Database>, connectivityId: number): Promise<void>;
|
|
30
|
+
export declare function deleteConnectivityBatch(supabase: SupabaseClient<Database>, connectivityIds: number[]): Promise<void>;
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
// Get sessions by herd id
|
|
2
|
+
export async function getSessionsByHerdId(supabase, herdId) {
|
|
3
|
+
const { data, error } = await supabase
|
|
4
|
+
.from("sessions")
|
|
5
|
+
.select(`
|
|
6
|
+
*,
|
|
7
|
+
devices!inner(herd_id)
|
|
8
|
+
`)
|
|
9
|
+
.eq("devices.herd_id", herdId)
|
|
10
|
+
.order("timestamp_start", { ascending: false });
|
|
11
|
+
if (error) {
|
|
12
|
+
throw new Error(`Failed to get sessions by herd id: ${error.message}`);
|
|
13
|
+
}
|
|
14
|
+
return data || [];
|
|
15
|
+
}
|
|
16
|
+
// Get connectivity by session id
|
|
17
|
+
export async function getConnectivityBySessionId(supabase, sessionId) {
|
|
18
|
+
const { data, error } = await supabase
|
|
19
|
+
.from("connectivity")
|
|
20
|
+
.select("*")
|
|
21
|
+
.eq("session_id", sessionId)
|
|
22
|
+
.order("timestamp_start", { ascending: true });
|
|
23
|
+
if (error) {
|
|
24
|
+
throw new Error(`Failed to get connectivity by session id: ${error.message}`);
|
|
25
|
+
}
|
|
26
|
+
return data || [];
|
|
27
|
+
}
|
|
28
|
+
// Get events by session id
|
|
29
|
+
export async function getEventsBySessionId(supabase, sessionId) {
|
|
30
|
+
const { data, error } = await supabase
|
|
31
|
+
.from("events")
|
|
32
|
+
.select("*")
|
|
33
|
+
.eq("session_id", sessionId)
|
|
34
|
+
.order("timestamp_observation", { ascending: true });
|
|
35
|
+
if (error) {
|
|
36
|
+
throw new Error(`Failed to get events by session id: ${error.message}`);
|
|
37
|
+
}
|
|
38
|
+
return data || [];
|
|
39
|
+
}
|
|
40
|
+
// Create or update session
|
|
41
|
+
export async function upsertSession(supabase, sessionData) {
|
|
42
|
+
const isUpdate = "id" in sessionData;
|
|
43
|
+
if (isUpdate) {
|
|
44
|
+
// Update existing session
|
|
45
|
+
const { id, ...updateData } = sessionData;
|
|
46
|
+
const { data, error } = await supabase
|
|
47
|
+
.from("sessions")
|
|
48
|
+
.update(updateData)
|
|
49
|
+
.eq("id", id)
|
|
50
|
+
.select()
|
|
51
|
+
.single();
|
|
52
|
+
if (error) {
|
|
53
|
+
throw new Error(`Failed to update session: ${error.message}`);
|
|
54
|
+
}
|
|
55
|
+
return data;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
// Create new session
|
|
59
|
+
const { data, error } = await supabase
|
|
60
|
+
.from("sessions")
|
|
61
|
+
.insert(sessionData)
|
|
62
|
+
.select()
|
|
63
|
+
.single();
|
|
64
|
+
if (error) {
|
|
65
|
+
throw new Error(`Failed to create session: ${error.message}`);
|
|
66
|
+
}
|
|
67
|
+
return data;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// Batch upsert sessions
|
|
71
|
+
export async function upsertSessions(supabase, sessionsData) {
|
|
72
|
+
if (sessionsData.length === 0) {
|
|
73
|
+
return [];
|
|
74
|
+
}
|
|
75
|
+
// Separate updates and inserts
|
|
76
|
+
const updates = sessionsData.filter((s) => "id" in s);
|
|
77
|
+
const inserts = sessionsData.filter((s) => !("id" in s));
|
|
78
|
+
const results = [];
|
|
79
|
+
// Handle updates
|
|
80
|
+
if (updates.length > 0) {
|
|
81
|
+
for (const sessionData of updates) {
|
|
82
|
+
try {
|
|
83
|
+
const result = await upsertSession(supabase, sessionData);
|
|
84
|
+
results.push(result);
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
throw new Error(`Failed to update session ${sessionData.id}: ${error}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Handle inserts
|
|
92
|
+
if (inserts.length > 0) {
|
|
93
|
+
const { data, error } = await supabase
|
|
94
|
+
.from("sessions")
|
|
95
|
+
.insert(inserts)
|
|
96
|
+
.select();
|
|
97
|
+
if (error) {
|
|
98
|
+
throw new Error(`Failed to create sessions: ${error.message}`);
|
|
99
|
+
}
|
|
100
|
+
results.push(...(data || []));
|
|
101
|
+
}
|
|
102
|
+
return results;
|
|
103
|
+
}
|
|
104
|
+
// Create or update connectivity
|
|
105
|
+
export async function upsertConnectivity(supabase, connectivityData) {
|
|
106
|
+
const isUpdate = "id" in connectivityData;
|
|
107
|
+
if (isUpdate) {
|
|
108
|
+
// Update existing connectivity
|
|
109
|
+
const { id, ...updateData } = connectivityData;
|
|
110
|
+
const { data, error } = await supabase
|
|
111
|
+
.from("connectivity")
|
|
112
|
+
.update(updateData)
|
|
113
|
+
.eq("id", id)
|
|
114
|
+
.select()
|
|
115
|
+
.single();
|
|
116
|
+
if (error) {
|
|
117
|
+
throw new Error(`Failed to update connectivity: ${error.message}`);
|
|
118
|
+
}
|
|
119
|
+
return data;
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
// Create new connectivity
|
|
123
|
+
const { data, error } = await supabase
|
|
124
|
+
.from("connectivity")
|
|
125
|
+
.insert(connectivityData)
|
|
126
|
+
.select()
|
|
127
|
+
.single();
|
|
128
|
+
if (error) {
|
|
129
|
+
throw new Error(`Failed to create connectivity: ${error.message}`);
|
|
130
|
+
}
|
|
131
|
+
return data;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// Batch upsert connectivity
|
|
135
|
+
export async function upsertConnectivityBatch(supabase, connectivityDataArray) {
|
|
136
|
+
if (connectivityDataArray.length === 0) {
|
|
137
|
+
return [];
|
|
138
|
+
}
|
|
139
|
+
// Separate updates and inserts
|
|
140
|
+
const updates = connectivityDataArray.filter((c) => "id" in c);
|
|
141
|
+
const inserts = connectivityDataArray.filter((c) => !("id" in c));
|
|
142
|
+
const results = [];
|
|
143
|
+
// Handle updates
|
|
144
|
+
if (updates.length > 0) {
|
|
145
|
+
for (const connectivityData of updates) {
|
|
146
|
+
try {
|
|
147
|
+
const result = await upsertConnectivity(supabase, connectivityData);
|
|
148
|
+
results.push(result);
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
throw new Error(`Failed to update connectivity ${connectivityData.id}: ${error}`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// Handle inserts
|
|
156
|
+
if (inserts.length > 0) {
|
|
157
|
+
const { data, error } = await supabase
|
|
158
|
+
.from("connectivity")
|
|
159
|
+
.insert(inserts)
|
|
160
|
+
.select();
|
|
161
|
+
if (error) {
|
|
162
|
+
throw new Error(`Failed to create connectivity entries: ${error.message}`);
|
|
163
|
+
}
|
|
164
|
+
results.push(...(data || []));
|
|
165
|
+
}
|
|
166
|
+
return results;
|
|
167
|
+
}
|
|
168
|
+
// Get session with connectivity and events
|
|
169
|
+
export async function getSessionWithConnectivityAndEvents(supabase, sessionId) {
|
|
170
|
+
const [sessionResult, connectivityResult, eventsResult] = await Promise.all([
|
|
171
|
+
supabase.from("sessions").select("*").eq("id", sessionId).single(),
|
|
172
|
+
getConnectivityBySessionId(supabase, sessionId),
|
|
173
|
+
getEventsBySessionId(supabase, sessionId),
|
|
174
|
+
]);
|
|
175
|
+
if (sessionResult.error) {
|
|
176
|
+
throw new Error(`Failed to get session: ${sessionResult.error.message}`);
|
|
177
|
+
}
|
|
178
|
+
return {
|
|
179
|
+
session: sessionResult.data,
|
|
180
|
+
connectivity: connectivityResult,
|
|
181
|
+
events: eventsResult,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
// Get sessions for a device
|
|
185
|
+
export async function getSessionsByDeviceId(supabase, deviceId) {
|
|
186
|
+
const { data, error } = await supabase
|
|
187
|
+
.from("sessions")
|
|
188
|
+
.select("*")
|
|
189
|
+
.eq("device_id", deviceId)
|
|
190
|
+
.order("timestamp_start", { ascending: false });
|
|
191
|
+
if (error) {
|
|
192
|
+
throw new Error(`Failed to get sessions by device id: ${error.message}`);
|
|
193
|
+
}
|
|
194
|
+
return data || [];
|
|
195
|
+
}
|
|
196
|
+
// Delete session and all related data
|
|
197
|
+
export async function deleteSession(supabase, sessionId) {
|
|
198
|
+
const { error } = await supabase
|
|
199
|
+
.from("sessions")
|
|
200
|
+
.delete()
|
|
201
|
+
.eq("id", sessionId);
|
|
202
|
+
if (error) {
|
|
203
|
+
throw new Error(`Failed to delete session: ${error.message}`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
// Batch delete sessions
|
|
207
|
+
export async function deleteSessions(supabase, sessionIds) {
|
|
208
|
+
if (sessionIds.length === 0) {
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
const { error } = await supabase
|
|
212
|
+
.from("sessions")
|
|
213
|
+
.delete()
|
|
214
|
+
.in("id", sessionIds);
|
|
215
|
+
if (error) {
|
|
216
|
+
throw new Error(`Failed to delete sessions: ${error.message}`);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
// Delete connectivity entry
|
|
220
|
+
export async function deleteConnectivity(supabase, connectivityId) {
|
|
221
|
+
const { error } = await supabase
|
|
222
|
+
.from("connectivity")
|
|
223
|
+
.delete()
|
|
224
|
+
.eq("id", connectivityId);
|
|
225
|
+
if (error) {
|
|
226
|
+
throw new Error(`Failed to delete connectivity: ${error.message}`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
// Batch delete connectivity entries
|
|
230
|
+
export async function deleteConnectivityBatch(supabase, connectivityIds) {
|
|
231
|
+
if (connectivityIds.length === 0) {
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
const { error } = await supabase
|
|
235
|
+
.from("connectivity")
|
|
236
|
+
.delete()
|
|
237
|
+
.in("id", connectivityIds);
|
|
238
|
+
if (error) {
|
|
239
|
+
throw new Error(`Failed to delete connectivity entries: ${error.message}`);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
@@ -12,6 +12,18 @@ export function useScoutDbListener(scoutSupabase) {
|
|
|
12
12
|
}
|
|
13
13
|
function handleTagDeletes(payload) {
|
|
14
14
|
console.log("[DB Listener] Tag DELETE received:", payload.old);
|
|
15
|
+
console.log("[DB Listener] Tag DELETE - payload structure:", {
|
|
16
|
+
hasOld: !!payload.old,
|
|
17
|
+
oldId: payload.old?.id,
|
|
18
|
+
oldEventId: payload.old?.event_id,
|
|
19
|
+
oldClassName: payload.old?.class_name,
|
|
20
|
+
fullPayload: payload,
|
|
21
|
+
});
|
|
22
|
+
if (!payload.old || !payload.old.id) {
|
|
23
|
+
console.error("[DB Listener] Tag DELETE - Invalid payload, missing tag data");
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
console.log("[DB Listener] Tag DELETE - Dispatching deleteTag action with ID:", payload.old.id);
|
|
15
27
|
dispatch(deleteTag(payload.old));
|
|
16
28
|
}
|
|
17
29
|
function handleTagUpdates(payload) {
|
|
@@ -39,6 +39,60 @@ export declare function useSupabase(): SupabaseClient<Database, "public", {
|
|
|
39
39
|
referencedColumns: ["id"];
|
|
40
40
|
}];
|
|
41
41
|
};
|
|
42
|
+
connectivity: {
|
|
43
|
+
Row: {
|
|
44
|
+
altitude: number;
|
|
45
|
+
h11_index: number;
|
|
46
|
+
h12_index: number;
|
|
47
|
+
h13_index: number;
|
|
48
|
+
h14_index: number;
|
|
49
|
+
heading: number;
|
|
50
|
+
id: number;
|
|
51
|
+
inserted_at: string;
|
|
52
|
+
location: unknown;
|
|
53
|
+
noise: number;
|
|
54
|
+
session_id: number;
|
|
55
|
+
signal: number;
|
|
56
|
+
timestamp_start: string;
|
|
57
|
+
};
|
|
58
|
+
Insert: {
|
|
59
|
+
altitude: number;
|
|
60
|
+
h11_index: number;
|
|
61
|
+
h12_index: number;
|
|
62
|
+
h13_index: number;
|
|
63
|
+
h14_index: number;
|
|
64
|
+
heading: number;
|
|
65
|
+
id?: number;
|
|
66
|
+
inserted_at?: string;
|
|
67
|
+
location: unknown;
|
|
68
|
+
noise: number;
|
|
69
|
+
session_id: number;
|
|
70
|
+
signal: number;
|
|
71
|
+
timestamp_start: string;
|
|
72
|
+
};
|
|
73
|
+
Update: {
|
|
74
|
+
altitude?: number;
|
|
75
|
+
h11_index?: number;
|
|
76
|
+
h12_index?: number;
|
|
77
|
+
h13_index?: number;
|
|
78
|
+
h14_index?: number;
|
|
79
|
+
heading?: number;
|
|
80
|
+
id?: number;
|
|
81
|
+
inserted_at?: string;
|
|
82
|
+
location?: unknown;
|
|
83
|
+
noise?: number;
|
|
84
|
+
session_id?: number;
|
|
85
|
+
signal?: number;
|
|
86
|
+
timestamp_start?: string;
|
|
87
|
+
};
|
|
88
|
+
Relationships: [{
|
|
89
|
+
foreignKeyName: "connectivity_session_id_fkey";
|
|
90
|
+
columns: ["session_id"];
|
|
91
|
+
isOneToOne: false;
|
|
92
|
+
referencedRelation: "sessions";
|
|
93
|
+
referencedColumns: ["id"];
|
|
94
|
+
}];
|
|
95
|
+
};
|
|
42
96
|
devices: {
|
|
43
97
|
Row: {
|
|
44
98
|
altitude: number | null;
|
|
@@ -112,22 +166,24 @@ export declare function useSupabase(): SupabaseClient<Database, "public", {
|
|
|
112
166
|
location: unknown | null;
|
|
113
167
|
media_type: Database["public"]["Enums"]["media_type"];
|
|
114
168
|
media_url: string | null;
|
|
115
|
-
message: string;
|
|
169
|
+
message: string | null;
|
|
170
|
+
session_id: number | null;
|
|
116
171
|
timestamp_observation: string;
|
|
117
172
|
};
|
|
118
173
|
Insert: {
|
|
119
|
-
altitude
|
|
174
|
+
altitude?: number;
|
|
120
175
|
device_id: number;
|
|
121
176
|
earthranger_url?: string | null;
|
|
122
177
|
file_path?: string | null;
|
|
123
|
-
heading
|
|
178
|
+
heading?: number;
|
|
124
179
|
id?: number;
|
|
125
180
|
inserted_at?: string;
|
|
126
181
|
is_public?: boolean;
|
|
127
182
|
location?: unknown | null;
|
|
128
183
|
media_type?: Database["public"]["Enums"]["media_type"];
|
|
129
184
|
media_url?: string | null;
|
|
130
|
-
message
|
|
185
|
+
message?: string | null;
|
|
186
|
+
session_id?: number | null;
|
|
131
187
|
timestamp_observation?: string;
|
|
132
188
|
};
|
|
133
189
|
Update: {
|
|
@@ -142,7 +198,8 @@ export declare function useSupabase(): SupabaseClient<Database, "public", {
|
|
|
142
198
|
location?: unknown | null;
|
|
143
199
|
media_type?: Database["public"]["Enums"]["media_type"];
|
|
144
200
|
media_url?: string | null;
|
|
145
|
-
message?: string;
|
|
201
|
+
message?: string | null;
|
|
202
|
+
session_id?: number | null;
|
|
146
203
|
timestamp_observation?: string;
|
|
147
204
|
};
|
|
148
205
|
Relationships: [{
|
|
@@ -151,6 +208,12 @@ export declare function useSupabase(): SupabaseClient<Database, "public", {
|
|
|
151
208
|
isOneToOne: false;
|
|
152
209
|
referencedRelation: "devices";
|
|
153
210
|
referencedColumns: ["id"];
|
|
211
|
+
}, {
|
|
212
|
+
foreignKeyName: "events_session_id_fkey";
|
|
213
|
+
columns: ["session_id"];
|
|
214
|
+
isOneToOne: false;
|
|
215
|
+
referencedRelation: "sessions";
|
|
216
|
+
referencedColumns: ["id"];
|
|
154
217
|
}];
|
|
155
218
|
};
|
|
156
219
|
herds: {
|
|
@@ -231,6 +294,66 @@ export declare function useSupabase(): SupabaseClient<Database, "public", {
|
|
|
231
294
|
referencedColumns: ["id"];
|
|
232
295
|
}];
|
|
233
296
|
};
|
|
297
|
+
sessions: {
|
|
298
|
+
Row: {
|
|
299
|
+
altitude_average: number;
|
|
300
|
+
altitude_max: number;
|
|
301
|
+
altitude_min: number;
|
|
302
|
+
device_id: number;
|
|
303
|
+
distance_max_from_start: number;
|
|
304
|
+
distance_total: number;
|
|
305
|
+
id: number;
|
|
306
|
+
inserted_at: string;
|
|
307
|
+
locations: unknown;
|
|
308
|
+
software_version: string;
|
|
309
|
+
timestamp_end: string;
|
|
310
|
+
timestamp_start: string;
|
|
311
|
+
velocity_average: number;
|
|
312
|
+
velocity_max: number;
|
|
313
|
+
velocity_min: number;
|
|
314
|
+
};
|
|
315
|
+
Insert: {
|
|
316
|
+
altitude_average: number;
|
|
317
|
+
altitude_max: number;
|
|
318
|
+
altitude_min: number;
|
|
319
|
+
device_id: number;
|
|
320
|
+
distance_max_from_start: number;
|
|
321
|
+
distance_total: number;
|
|
322
|
+
id?: number;
|
|
323
|
+
inserted_at?: string;
|
|
324
|
+
locations: unknown;
|
|
325
|
+
software_version: string;
|
|
326
|
+
timestamp_end: string;
|
|
327
|
+
timestamp_start: string;
|
|
328
|
+
velocity_average: number;
|
|
329
|
+
velocity_max: number;
|
|
330
|
+
velocity_min: number;
|
|
331
|
+
};
|
|
332
|
+
Update: {
|
|
333
|
+
altitude_average?: number;
|
|
334
|
+
altitude_max?: number;
|
|
335
|
+
altitude_min?: number;
|
|
336
|
+
device_id?: number;
|
|
337
|
+
distance_max_from_start?: number;
|
|
338
|
+
distance_total?: number;
|
|
339
|
+
id?: number;
|
|
340
|
+
inserted_at?: string;
|
|
341
|
+
locations?: unknown;
|
|
342
|
+
software_version?: string;
|
|
343
|
+
timestamp_end?: string;
|
|
344
|
+
timestamp_start?: string;
|
|
345
|
+
velocity_average?: number;
|
|
346
|
+
velocity_max?: number;
|
|
347
|
+
velocity_min?: number;
|
|
348
|
+
};
|
|
349
|
+
Relationships: [{
|
|
350
|
+
foreignKeyName: "sessions_device_id_fkey";
|
|
351
|
+
columns: ["device_id"];
|
|
352
|
+
isOneToOne: false;
|
|
353
|
+
referencedRelation: "devices";
|
|
354
|
+
referencedColumns: ["id"];
|
|
355
|
+
}];
|
|
356
|
+
};
|
|
234
357
|
tags: {
|
|
235
358
|
Row: {
|
|
236
359
|
class_name: string;
|
|
@@ -505,7 +628,8 @@ export declare function useSupabase(): SupabaseClient<Database, "public", {
|
|
|
505
628
|
location: unknown | null;
|
|
506
629
|
media_type: Database["public"]["Enums"]["media_type"];
|
|
507
630
|
media_url: string | null;
|
|
508
|
-
message: string;
|
|
631
|
+
message: string | null;
|
|
632
|
+
session_id: number | null;
|
|
509
633
|
timestamp_observation: string;
|
|
510
634
|
}[];
|
|
511
635
|
};
|
package/dist/store/scout.js
CHANGED
|
@@ -76,19 +76,25 @@ export const scoutSlice = createSlice({
|
|
|
76
76
|
}
|
|
77
77
|
},
|
|
78
78
|
deleteTag(state, action) {
|
|
79
|
+
console.log("[Redux] deleteTag action called with:", action.payload);
|
|
80
|
+
console.log("[Redux] deleteTag - Looking for tag ID:", action.payload.id);
|
|
79
81
|
for (const herd_module of state.herd_modules) {
|
|
80
82
|
for (const event of herd_module.events) {
|
|
81
83
|
if (!event.tags) {
|
|
82
84
|
continue;
|
|
83
85
|
}
|
|
86
|
+
console.log(`[Redux] deleteTag - Checking event ${event.id}, has ${event.tags.length} tags`);
|
|
84
87
|
for (const tag of event.tags) {
|
|
85
88
|
if (tag.id === action.payload.id) {
|
|
89
|
+
console.log(`[Redux] deleteTag - Found tag ${tag.id} in event ${event.id}, removing it`);
|
|
86
90
|
event.tags = event.tags.filter((t) => t.id !== tag.id);
|
|
91
|
+
console.log(`[Redux] deleteTag - After removal, event ${event.id} has ${event.tags.length} tags`);
|
|
87
92
|
return;
|
|
88
93
|
}
|
|
89
94
|
}
|
|
90
95
|
}
|
|
91
96
|
}
|
|
97
|
+
console.log("[Redux] deleteTag - Tag not found in any event");
|
|
92
98
|
},
|
|
93
99
|
updateTag(state, action) {
|
|
94
100
|
for (const herd_module of state.herd_modules) {
|
|
@@ -37,6 +37,60 @@ export declare function newServerClient(): Promise<import("@supabase/supabase-js
|
|
|
37
37
|
referencedColumns: ["id"];
|
|
38
38
|
}];
|
|
39
39
|
};
|
|
40
|
+
connectivity: {
|
|
41
|
+
Row: {
|
|
42
|
+
altitude: number;
|
|
43
|
+
h11_index: number;
|
|
44
|
+
h12_index: number;
|
|
45
|
+
h13_index: number;
|
|
46
|
+
h14_index: number;
|
|
47
|
+
heading: number;
|
|
48
|
+
id: number;
|
|
49
|
+
inserted_at: string;
|
|
50
|
+
location: unknown;
|
|
51
|
+
noise: number;
|
|
52
|
+
session_id: number;
|
|
53
|
+
signal: number;
|
|
54
|
+
timestamp_start: string;
|
|
55
|
+
};
|
|
56
|
+
Insert: {
|
|
57
|
+
altitude: number;
|
|
58
|
+
h11_index: number;
|
|
59
|
+
h12_index: number;
|
|
60
|
+
h13_index: number;
|
|
61
|
+
h14_index: number;
|
|
62
|
+
heading: number;
|
|
63
|
+
id?: number;
|
|
64
|
+
inserted_at?: string;
|
|
65
|
+
location: unknown;
|
|
66
|
+
noise: number;
|
|
67
|
+
session_id: number;
|
|
68
|
+
signal: number;
|
|
69
|
+
timestamp_start: string;
|
|
70
|
+
};
|
|
71
|
+
Update: {
|
|
72
|
+
altitude?: number;
|
|
73
|
+
h11_index?: number;
|
|
74
|
+
h12_index?: number;
|
|
75
|
+
h13_index?: number;
|
|
76
|
+
h14_index?: number;
|
|
77
|
+
heading?: number;
|
|
78
|
+
id?: number;
|
|
79
|
+
inserted_at?: string;
|
|
80
|
+
location?: unknown;
|
|
81
|
+
noise?: number;
|
|
82
|
+
session_id?: number;
|
|
83
|
+
signal?: number;
|
|
84
|
+
timestamp_start?: string;
|
|
85
|
+
};
|
|
86
|
+
Relationships: [{
|
|
87
|
+
foreignKeyName: "connectivity_session_id_fkey";
|
|
88
|
+
columns: ["session_id"];
|
|
89
|
+
isOneToOne: false;
|
|
90
|
+
referencedRelation: "sessions";
|
|
91
|
+
referencedColumns: ["id"];
|
|
92
|
+
}];
|
|
93
|
+
};
|
|
40
94
|
devices: {
|
|
41
95
|
Row: {
|
|
42
96
|
altitude: number | null;
|
|
@@ -110,22 +164,24 @@ export declare function newServerClient(): Promise<import("@supabase/supabase-js
|
|
|
110
164
|
location: unknown | null;
|
|
111
165
|
media_type: Database["public"]["Enums"]["media_type"];
|
|
112
166
|
media_url: string | null;
|
|
113
|
-
message: string;
|
|
167
|
+
message: string | null;
|
|
168
|
+
session_id: number | null;
|
|
114
169
|
timestamp_observation: string;
|
|
115
170
|
};
|
|
116
171
|
Insert: {
|
|
117
|
-
altitude
|
|
172
|
+
altitude?: number;
|
|
118
173
|
device_id: number;
|
|
119
174
|
earthranger_url?: string | null;
|
|
120
175
|
file_path?: string | null;
|
|
121
|
-
heading
|
|
176
|
+
heading?: number;
|
|
122
177
|
id?: number;
|
|
123
178
|
inserted_at?: string;
|
|
124
179
|
is_public?: boolean;
|
|
125
180
|
location?: unknown | null;
|
|
126
181
|
media_type?: Database["public"]["Enums"]["media_type"];
|
|
127
182
|
media_url?: string | null;
|
|
128
|
-
message
|
|
183
|
+
message?: string | null;
|
|
184
|
+
session_id?: number | null;
|
|
129
185
|
timestamp_observation?: string;
|
|
130
186
|
};
|
|
131
187
|
Update: {
|
|
@@ -140,7 +196,8 @@ export declare function newServerClient(): Promise<import("@supabase/supabase-js
|
|
|
140
196
|
location?: unknown | null;
|
|
141
197
|
media_type?: Database["public"]["Enums"]["media_type"];
|
|
142
198
|
media_url?: string | null;
|
|
143
|
-
message?: string;
|
|
199
|
+
message?: string | null;
|
|
200
|
+
session_id?: number | null;
|
|
144
201
|
timestamp_observation?: string;
|
|
145
202
|
};
|
|
146
203
|
Relationships: [{
|
|
@@ -149,6 +206,12 @@ export declare function newServerClient(): Promise<import("@supabase/supabase-js
|
|
|
149
206
|
isOneToOne: false;
|
|
150
207
|
referencedRelation: "devices";
|
|
151
208
|
referencedColumns: ["id"];
|
|
209
|
+
}, {
|
|
210
|
+
foreignKeyName: "events_session_id_fkey";
|
|
211
|
+
columns: ["session_id"];
|
|
212
|
+
isOneToOne: false;
|
|
213
|
+
referencedRelation: "sessions";
|
|
214
|
+
referencedColumns: ["id"];
|
|
152
215
|
}];
|
|
153
216
|
};
|
|
154
217
|
herds: {
|
|
@@ -229,6 +292,66 @@ export declare function newServerClient(): Promise<import("@supabase/supabase-js
|
|
|
229
292
|
referencedColumns: ["id"];
|
|
230
293
|
}];
|
|
231
294
|
};
|
|
295
|
+
sessions: {
|
|
296
|
+
Row: {
|
|
297
|
+
altitude_average: number;
|
|
298
|
+
altitude_max: number;
|
|
299
|
+
altitude_min: number;
|
|
300
|
+
device_id: number;
|
|
301
|
+
distance_max_from_start: number;
|
|
302
|
+
distance_total: number;
|
|
303
|
+
id: number;
|
|
304
|
+
inserted_at: string;
|
|
305
|
+
locations: unknown;
|
|
306
|
+
software_version: string;
|
|
307
|
+
timestamp_end: string;
|
|
308
|
+
timestamp_start: string;
|
|
309
|
+
velocity_average: number;
|
|
310
|
+
velocity_max: number;
|
|
311
|
+
velocity_min: number;
|
|
312
|
+
};
|
|
313
|
+
Insert: {
|
|
314
|
+
altitude_average: number;
|
|
315
|
+
altitude_max: number;
|
|
316
|
+
altitude_min: number;
|
|
317
|
+
device_id: number;
|
|
318
|
+
distance_max_from_start: number;
|
|
319
|
+
distance_total: number;
|
|
320
|
+
id?: number;
|
|
321
|
+
inserted_at?: string;
|
|
322
|
+
locations: unknown;
|
|
323
|
+
software_version: string;
|
|
324
|
+
timestamp_end: string;
|
|
325
|
+
timestamp_start: string;
|
|
326
|
+
velocity_average: number;
|
|
327
|
+
velocity_max: number;
|
|
328
|
+
velocity_min: number;
|
|
329
|
+
};
|
|
330
|
+
Update: {
|
|
331
|
+
altitude_average?: number;
|
|
332
|
+
altitude_max?: number;
|
|
333
|
+
altitude_min?: number;
|
|
334
|
+
device_id?: number;
|
|
335
|
+
distance_max_from_start?: number;
|
|
336
|
+
distance_total?: number;
|
|
337
|
+
id?: number;
|
|
338
|
+
inserted_at?: string;
|
|
339
|
+
locations?: unknown;
|
|
340
|
+
software_version?: string;
|
|
341
|
+
timestamp_end?: string;
|
|
342
|
+
timestamp_start?: string;
|
|
343
|
+
velocity_average?: number;
|
|
344
|
+
velocity_max?: number;
|
|
345
|
+
velocity_min?: number;
|
|
346
|
+
};
|
|
347
|
+
Relationships: [{
|
|
348
|
+
foreignKeyName: "sessions_device_id_fkey";
|
|
349
|
+
columns: ["device_id"];
|
|
350
|
+
isOneToOne: false;
|
|
351
|
+
referencedRelation: "devices";
|
|
352
|
+
referencedColumns: ["id"];
|
|
353
|
+
}];
|
|
354
|
+
};
|
|
232
355
|
tags: {
|
|
233
356
|
Row: {
|
|
234
357
|
class_name: string;
|
|
@@ -503,7 +626,8 @@ export declare function newServerClient(): Promise<import("@supabase/supabase-js
|
|
|
503
626
|
location: unknown | null;
|
|
504
627
|
media_type: Database["public"]["Enums"]["media_type"];
|
|
505
628
|
media_url: string | null;
|
|
506
|
-
message: string;
|
|
629
|
+
message: string | null;
|
|
630
|
+
session_id: number | null;
|
|
507
631
|
timestamp_observation: string;
|
|
508
632
|
}[];
|
|
509
633
|
};
|