@optifye/dashboard-core 6.6.7 → 6.6.8
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 +92 -7
- package/dist/index.d.ts +92 -7
- package/dist/index.js +1755 -1363
- package/dist/index.mjs +836 -450
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import
|
|
1
|
+
import * as React21 from 'react';
|
|
2
|
+
import React21__default, { createContext, useRef, useCallback, useState, useMemo, useEffect, memo, forwardRef, useImperativeHandle, useContext, useLayoutEffect, useId, Children, isValidElement, useInsertionEffect, Fragment as Fragment$1, createElement, Component } from 'react';
|
|
3
3
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
import { useRouter } from 'next/router';
|
|
5
5
|
import { toZonedTime, formatInTimeZone } from 'date-fns-tz';
|
|
6
6
|
import { subDays, format, parseISO, isValid, formatDistanceToNow, isFuture, isToday } from 'date-fns';
|
|
7
7
|
import mixpanel from 'mixpanel-browser';
|
|
8
8
|
import { EventEmitter } from 'events';
|
|
9
|
-
import {
|
|
9
|
+
import { createClient, REALTIME_SUBSCRIBE_STATES } from '@supabase/supabase-js';
|
|
10
10
|
import Hls2 from 'hls.js';
|
|
11
11
|
import useSWR from 'swr';
|
|
12
12
|
import { noop, warning, invariant, progress, secondsToMilliseconds, millisecondsToSeconds, memo as memo$1 } from 'motion-utils';
|
|
@@ -153,8 +153,9 @@ var DEFAULT_WORKSPACE_CONFIG = {
|
|
|
153
153
|
totalWorkspaces: 42
|
|
154
154
|
};
|
|
155
155
|
var DEFAULT_DATE_TIME_CONFIG = {
|
|
156
|
-
defaultTimezone: "
|
|
157
|
-
|
|
156
|
+
defaultTimezone: "UTC",
|
|
157
|
+
// Should be overridden by database timezone
|
|
158
|
+
defaultLocale: "en-US",
|
|
158
159
|
dateFormatOptions: {
|
|
159
160
|
day: "2-digit",
|
|
160
161
|
month: "short",
|
|
@@ -268,14 +269,14 @@ var _getDashboardConfigInstance = () => {
|
|
|
268
269
|
}
|
|
269
270
|
return dashboardConfigInstance;
|
|
270
271
|
};
|
|
271
|
-
var DashboardConfigContext =
|
|
272
|
+
var DashboardConfigContext = React21.createContext(void 0);
|
|
272
273
|
var DashboardProvider = ({ config: userProvidedConfig, children }) => {
|
|
273
|
-
const fullConfig =
|
|
274
|
+
const fullConfig = React21.useMemo(() => mergeWithDefaultConfig(userProvidedConfig), [userProvidedConfig]);
|
|
274
275
|
_setDashboardConfigInstance(fullConfig);
|
|
275
|
-
|
|
276
|
+
React21.useEffect(() => {
|
|
276
277
|
_setDashboardConfigInstance(fullConfig);
|
|
277
278
|
}, [fullConfig]);
|
|
278
|
-
|
|
279
|
+
React21.useEffect(() => {
|
|
279
280
|
if (!fullConfig.theme) return;
|
|
280
281
|
const styleId = "dashboard-core-theme-vars";
|
|
281
282
|
let styleEl = document.getElementById(styleId);
|
|
@@ -301,7 +302,7 @@ var DashboardProvider = ({ config: userProvidedConfig, children }) => {
|
|
|
301
302
|
return /* @__PURE__ */ jsx(DashboardConfigContext.Provider, { value: fullConfig, children });
|
|
302
303
|
};
|
|
303
304
|
var useDashboardConfig = () => {
|
|
304
|
-
const ctx =
|
|
305
|
+
const ctx = React21.useContext(DashboardConfigContext);
|
|
305
306
|
if (!ctx) throw new Error("useDashboardConfig must be used within a DashboardProvider");
|
|
306
307
|
return ctx;
|
|
307
308
|
};
|
|
@@ -426,7 +427,7 @@ var memoizedOutputArrayAggregation = createMemoizedFunction(
|
|
|
426
427
|
},
|
|
427
428
|
(arrays) => arrays.map((arr) => arr.length).join("-")
|
|
428
429
|
);
|
|
429
|
-
var getOperationalDate = (timezone
|
|
430
|
+
var getOperationalDate = (timezone, date = /* @__PURE__ */ new Date(), shiftStartTime = "06:00") => {
|
|
430
431
|
const zonedDate = toZonedTime(date, timezone);
|
|
431
432
|
const hours = zonedDate.getHours();
|
|
432
433
|
const [startHour = 6] = shiftStartTime.split(":").map(Number);
|
|
@@ -1888,7 +1889,7 @@ var workspaceService = {
|
|
|
1888
1889
|
}
|
|
1889
1890
|
const totalDayOutput = outputWorkspaces.reduce((sum, ws) => sum + (ws.action_total_day_output || 0), 0);
|
|
1890
1891
|
const totalPPH = outputWorkspaces.reduce((sum, ws) => sum + (ws.action_pph_threshold || 0), 0);
|
|
1891
|
-
const operationalDate = getOperationalDate(defaultTimezone);
|
|
1892
|
+
const operationalDate = getOperationalDate(defaultTimezone || "UTC");
|
|
1892
1893
|
const thresholdData = {
|
|
1893
1894
|
factory_id: configuredFactoryId,
|
|
1894
1895
|
line_id: lineId,
|
|
@@ -4528,6 +4529,154 @@ var createSupervisorService = (supabase) => {
|
|
|
4528
4529
|
var simulateApiDelay = (ms = 1e3) => {
|
|
4529
4530
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
4530
4531
|
};
|
|
4532
|
+
var TimezoneService = class _TimezoneService {
|
|
4533
|
+
constructor() {
|
|
4534
|
+
this.timezoneCache = /* @__PURE__ */ new Map();
|
|
4535
|
+
this.supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL || "";
|
|
4536
|
+
this.supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || "";
|
|
4537
|
+
}
|
|
4538
|
+
static getInstance() {
|
|
4539
|
+
if (!_TimezoneService.instance) {
|
|
4540
|
+
_TimezoneService.instance = new _TimezoneService();
|
|
4541
|
+
}
|
|
4542
|
+
return _TimezoneService.instance;
|
|
4543
|
+
}
|
|
4544
|
+
/**
|
|
4545
|
+
* Fetch timezone for a specific line from Supabase
|
|
4546
|
+
*/
|
|
4547
|
+
async getTimezoneForLine(lineId, defaultTimezone = "Asia/Kolkata") {
|
|
4548
|
+
if (this.timezoneCache.has(lineId)) {
|
|
4549
|
+
return this.timezoneCache.get(lineId);
|
|
4550
|
+
}
|
|
4551
|
+
try {
|
|
4552
|
+
const supabase = createClient(this.supabaseUrl, this.supabaseAnonKey);
|
|
4553
|
+
const { data, error } = await supabase.from("line_operating_hours").select("timezone").eq("line_id", lineId).order("created_at", { ascending: false }).limit(1).single();
|
|
4554
|
+
if (error) {
|
|
4555
|
+
console.warn(`Failed to fetch timezone for line ${lineId}:`, error);
|
|
4556
|
+
return defaultTimezone;
|
|
4557
|
+
}
|
|
4558
|
+
if (data?.timezone) {
|
|
4559
|
+
this.timezoneCache.set(lineId, data.timezone);
|
|
4560
|
+
return data.timezone;
|
|
4561
|
+
}
|
|
4562
|
+
return defaultTimezone;
|
|
4563
|
+
} catch (error) {
|
|
4564
|
+
console.error("Error fetching timezone:", error);
|
|
4565
|
+
return defaultTimezone;
|
|
4566
|
+
}
|
|
4567
|
+
}
|
|
4568
|
+
/**
|
|
4569
|
+
* Fetch timezone for a company's factory
|
|
4570
|
+
*/
|
|
4571
|
+
async getTimezoneForCompany(companyId, defaultTimezone = "Asia/Kolkata") {
|
|
4572
|
+
const cacheKey = `company-${companyId}`;
|
|
4573
|
+
if (this.timezoneCache.has(cacheKey)) {
|
|
4574
|
+
return this.timezoneCache.get(cacheKey);
|
|
4575
|
+
}
|
|
4576
|
+
try {
|
|
4577
|
+
const supabase = createClient(this.supabaseUrl, this.supabaseAnonKey);
|
|
4578
|
+
const { data, error } = await supabase.from("line_operating_hours").select(`
|
|
4579
|
+
timezone,
|
|
4580
|
+
line:lines!inner(
|
|
4581
|
+
company_id
|
|
4582
|
+
)
|
|
4583
|
+
`).eq("lines.company_id", companyId).order("created_at", { ascending: false }).limit(1);
|
|
4584
|
+
if (error) {
|
|
4585
|
+
console.warn(`Failed to fetch timezone for company ${companyId}:`, error);
|
|
4586
|
+
return defaultTimezone;
|
|
4587
|
+
}
|
|
4588
|
+
if (data?.[0]?.timezone) {
|
|
4589
|
+
this.timezoneCache.set(cacheKey, data[0].timezone);
|
|
4590
|
+
return data[0].timezone;
|
|
4591
|
+
}
|
|
4592
|
+
return defaultTimezone;
|
|
4593
|
+
} catch (error) {
|
|
4594
|
+
console.error("Error fetching company timezone:", error);
|
|
4595
|
+
return defaultTimezone;
|
|
4596
|
+
}
|
|
4597
|
+
}
|
|
4598
|
+
/**
|
|
4599
|
+
* Fetch timezone for a workspace
|
|
4600
|
+
*/
|
|
4601
|
+
async getTimezoneForWorkspace(workspaceId, defaultTimezone = "Asia/Kolkata") {
|
|
4602
|
+
const cacheKey = `workspace-${workspaceId}`;
|
|
4603
|
+
if (this.timezoneCache.has(cacheKey)) {
|
|
4604
|
+
return this.timezoneCache.get(cacheKey);
|
|
4605
|
+
}
|
|
4606
|
+
try {
|
|
4607
|
+
const supabase = createClient(this.supabaseUrl, this.supabaseAnonKey);
|
|
4608
|
+
const { data: workspaceData, error: workspaceError } = await supabase.from("workspaces").select("line_id").eq("id", workspaceId).single();
|
|
4609
|
+
if (workspaceError) {
|
|
4610
|
+
console.warn(`Failed to fetch workspace ${workspaceId}:`, workspaceError);
|
|
4611
|
+
return defaultTimezone;
|
|
4612
|
+
}
|
|
4613
|
+
if (workspaceData?.line_id) {
|
|
4614
|
+
return this.getTimezoneForLine(workspaceData.line_id, defaultTimezone);
|
|
4615
|
+
}
|
|
4616
|
+
const { data: cameraData, error: cameraError } = await supabase.from("cameras").select("line_id").eq("workspace_id", workspaceId).limit(1).single();
|
|
4617
|
+
if (!cameraError && cameraData?.line_id) {
|
|
4618
|
+
return this.getTimezoneForLine(cameraData.line_id, defaultTimezone);
|
|
4619
|
+
}
|
|
4620
|
+
return defaultTimezone;
|
|
4621
|
+
} catch (error) {
|
|
4622
|
+
console.error("Error fetching workspace timezone:", error);
|
|
4623
|
+
return defaultTimezone;
|
|
4624
|
+
}
|
|
4625
|
+
}
|
|
4626
|
+
/**
|
|
4627
|
+
* Batch fetch timezones for multiple lines
|
|
4628
|
+
*/
|
|
4629
|
+
async getTimezonesForLines(lineIds, defaultTimezone = "Asia/Kolkata") {
|
|
4630
|
+
const result = /* @__PURE__ */ new Map();
|
|
4631
|
+
const uncachedLineIds = lineIds.filter((id3) => !this.timezoneCache.has(id3));
|
|
4632
|
+
if (uncachedLineIds.length === 0) {
|
|
4633
|
+
lineIds.forEach((id3) => {
|
|
4634
|
+
result.set(id3, this.timezoneCache.get(id3) || defaultTimezone);
|
|
4635
|
+
});
|
|
4636
|
+
return result;
|
|
4637
|
+
}
|
|
4638
|
+
try {
|
|
4639
|
+
const supabase = createClient(this.supabaseUrl, this.supabaseAnonKey);
|
|
4640
|
+
const { data, error } = await supabase.from("line_operating_hours").select("line_id, timezone").in("line_id", uncachedLineIds).order("created_at", { ascending: false });
|
|
4641
|
+
if (error) {
|
|
4642
|
+
console.warn("Failed to fetch timezones for lines:", error);
|
|
4643
|
+
lineIds.forEach((id3) => result.set(id3, defaultTimezone));
|
|
4644
|
+
return result;
|
|
4645
|
+
}
|
|
4646
|
+
const timezoneMap = /* @__PURE__ */ new Map();
|
|
4647
|
+
data?.forEach((item) => {
|
|
4648
|
+
if (!timezoneMap.has(item.line_id)) {
|
|
4649
|
+
timezoneMap.set(item.line_id, item.timezone);
|
|
4650
|
+
this.timezoneCache.set(item.line_id, item.timezone);
|
|
4651
|
+
}
|
|
4652
|
+
});
|
|
4653
|
+
lineIds.forEach((id3) => {
|
|
4654
|
+
const timezone = this.timezoneCache.get(id3) || timezoneMap.get(id3) || defaultTimezone;
|
|
4655
|
+
result.set(id3, timezone);
|
|
4656
|
+
});
|
|
4657
|
+
return result;
|
|
4658
|
+
} catch (error) {
|
|
4659
|
+
console.error("Error batch fetching timezones:", error);
|
|
4660
|
+
lineIds.forEach((id3) => result.set(id3, defaultTimezone));
|
|
4661
|
+
return result;
|
|
4662
|
+
}
|
|
4663
|
+
}
|
|
4664
|
+
/**
|
|
4665
|
+
* Clear timezone cache
|
|
4666
|
+
*/
|
|
4667
|
+
clearCache() {
|
|
4668
|
+
this.timezoneCache.clear();
|
|
4669
|
+
}
|
|
4670
|
+
/**
|
|
4671
|
+
* Clear specific entry from cache
|
|
4672
|
+
*/
|
|
4673
|
+
clearCacheEntry(key) {
|
|
4674
|
+
this.timezoneCache.delete(key);
|
|
4675
|
+
this.timezoneCache.delete(`company-${key}`);
|
|
4676
|
+
this.timezoneCache.delete(`workspace-${key}`);
|
|
4677
|
+
}
|
|
4678
|
+
};
|
|
4679
|
+
var timezoneService = TimezoneService.getInstance();
|
|
4531
4680
|
var AuthContext = createContext({
|
|
4532
4681
|
session: null,
|
|
4533
4682
|
user: null,
|
|
@@ -5001,18 +5150,96 @@ var useClipFilter = () => {
|
|
|
5001
5150
|
}
|
|
5002
5151
|
return context;
|
|
5003
5152
|
};
|
|
5153
|
+
var TimezoneContext = createContext(void 0);
|
|
5154
|
+
function TimezoneProvider({
|
|
5155
|
+
children,
|
|
5156
|
+
workspaceId: propWorkspaceId,
|
|
5157
|
+
lineId: propLineId,
|
|
5158
|
+
companyId: propCompanyId,
|
|
5159
|
+
fallbackTimezone = "Asia/Kolkata"
|
|
5160
|
+
// Last resort fallback ONLY
|
|
5161
|
+
}) {
|
|
5162
|
+
const dashboardConfig = useDashboardConfig();
|
|
5163
|
+
const workspaceConfig = useWorkspaceConfig();
|
|
5164
|
+
const [timezone, setTimezone] = useState(fallbackTimezone);
|
|
5165
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
5166
|
+
const [error, setError] = useState(null);
|
|
5167
|
+
const workspaceId = propWorkspaceId || (workspaceConfig && typeof workspaceConfig === "object" && "id" in workspaceConfig ? workspaceConfig.id : void 0);
|
|
5168
|
+
const lineId = propLineId;
|
|
5169
|
+
const companyId = propCompanyId || (dashboardConfig && typeof dashboardConfig === "object" && "company" in dashboardConfig ? dashboardConfig.company?.id : void 0);
|
|
5170
|
+
const fetchTimezone = async () => {
|
|
5171
|
+
setIsLoading(true);
|
|
5172
|
+
setError(null);
|
|
5173
|
+
try {
|
|
5174
|
+
let fetchedTimezone = null;
|
|
5175
|
+
if (lineId) {
|
|
5176
|
+
console.log(`[TimezoneContext] Fetching timezone for line: ${lineId}`);
|
|
5177
|
+
fetchedTimezone = await timezoneService.getTimezoneForLine(lineId, fallbackTimezone);
|
|
5178
|
+
} else if (workspaceId) {
|
|
5179
|
+
console.log(`[TimezoneContext] Fetching timezone for workspace: ${workspaceId}`);
|
|
5180
|
+
fetchedTimezone = await timezoneService.getTimezoneForWorkspace(workspaceId, fallbackTimezone);
|
|
5181
|
+
} else if (companyId) {
|
|
5182
|
+
console.log(`[TimezoneContext] Fetching timezone for company: ${companyId}`);
|
|
5183
|
+
fetchedTimezone = await timezoneService.getTimezoneForCompany(companyId, fallbackTimezone);
|
|
5184
|
+
} else {
|
|
5185
|
+
console.warn("[TimezoneContext] No ID available to fetch timezone, using fallback");
|
|
5186
|
+
fetchedTimezone = fallbackTimezone;
|
|
5187
|
+
}
|
|
5188
|
+
console.log(`[TimezoneContext] Timezone resolved to: ${fetchedTimezone}`);
|
|
5189
|
+
if (fetchedTimezone === fallbackTimezone) {
|
|
5190
|
+
console.warn(`[TimezoneContext] WARNING: Using fallback timezone ${fallbackTimezone}. This should not happen in production!`);
|
|
5191
|
+
}
|
|
5192
|
+
setTimezone(fetchedTimezone);
|
|
5193
|
+
} catch (err) {
|
|
5194
|
+
console.error("[TimezoneContext] Error fetching timezone:", err);
|
|
5195
|
+
setError(err instanceof Error ? err : new Error("Failed to fetch timezone"));
|
|
5196
|
+
console.error(`[TimezoneContext] CRITICAL: Failed to fetch timezone from database, falling back to ${fallbackTimezone}`);
|
|
5197
|
+
setTimezone(fallbackTimezone);
|
|
5198
|
+
} finally {
|
|
5199
|
+
setIsLoading(false);
|
|
5200
|
+
}
|
|
5201
|
+
};
|
|
5202
|
+
useEffect(() => {
|
|
5203
|
+
fetchTimezone();
|
|
5204
|
+
}, [lineId, workspaceId, companyId]);
|
|
5205
|
+
const value = {
|
|
5206
|
+
timezone,
|
|
5207
|
+
isLoading,
|
|
5208
|
+
error,
|
|
5209
|
+
refetch: fetchTimezone
|
|
5210
|
+
};
|
|
5211
|
+
return /* @__PURE__ */ jsx(TimezoneContext.Provider, { value, children });
|
|
5212
|
+
}
|
|
5213
|
+
function useTimezoneContext() {
|
|
5214
|
+
const context = useContext(TimezoneContext);
|
|
5215
|
+
if (!context) {
|
|
5216
|
+
throw new Error("useTimezoneContext must be used within TimezoneProvider");
|
|
5217
|
+
}
|
|
5218
|
+
return context;
|
|
5219
|
+
}
|
|
5220
|
+
function useAppTimezone() {
|
|
5221
|
+
const { timezone } = useTimezoneContext();
|
|
5222
|
+
return timezone;
|
|
5223
|
+
}
|
|
5224
|
+
function withTimezone(Component3) {
|
|
5225
|
+
return function WithTimezoneComponent(props) {
|
|
5226
|
+
const timezone = useAppTimezone();
|
|
5227
|
+
return /* @__PURE__ */ jsx(Component3, { ...props, timezone });
|
|
5228
|
+
};
|
|
5229
|
+
}
|
|
5004
5230
|
var DEFAULT_COMPANY_ID = "default-company-id";
|
|
5005
5231
|
var useWorkspaceMetrics = (workspaceId) => {
|
|
5006
5232
|
const supabase = useSupabase();
|
|
5007
5233
|
const entityConfig = useEntityConfig();
|
|
5008
5234
|
useDatabaseConfig();
|
|
5009
5235
|
const dateTimeConfig = useDateTimeConfig();
|
|
5236
|
+
const timezone = useAppTimezone();
|
|
5010
5237
|
const [workspaceMetrics, setWorkspaceMetrics] = useState(null);
|
|
5011
5238
|
const [isLoading, setIsLoading] = useState(true);
|
|
5012
5239
|
const [error, setError] = useState(null);
|
|
5013
5240
|
const fetchWorkspaceMetrics = useCallback(async () => {
|
|
5014
5241
|
try {
|
|
5015
|
-
const operationalDate = getOperationalDate(dateTimeConfig.defaultTimezone);
|
|
5242
|
+
const operationalDate = getOperationalDate(timezone || dateTimeConfig.defaultTimezone || "UTC");
|
|
5016
5243
|
const { data, error: fetchError } = await supabase.from("overview_workspace_metrics").select("*").eq("workspace_id", workspaceId).eq("date", operationalDate).single();
|
|
5017
5244
|
if (fetchError) throw fetchError;
|
|
5018
5245
|
setWorkspaceMetrics(data);
|
|
@@ -5025,7 +5252,7 @@ var useWorkspaceMetrics = (workspaceId) => {
|
|
|
5025
5252
|
}, [supabase, workspaceId, dateTimeConfig.defaultTimezone]);
|
|
5026
5253
|
useEffect(() => {
|
|
5027
5254
|
let channels = [];
|
|
5028
|
-
const operationalDate = getOperationalDate(dateTimeConfig.defaultTimezone);
|
|
5255
|
+
const operationalDate = getOperationalDate(timezone || dateTimeConfig.defaultTimezone || "UTC");
|
|
5029
5256
|
const setupSubscriptions = () => {
|
|
5030
5257
|
const companyId = entityConfig.companyId || DEFAULT_COMPANY_ID;
|
|
5031
5258
|
const metricsTablePrefix = getMetricsTablePrefix();
|
|
@@ -5076,12 +5303,13 @@ var useWorkspaceMetrics = (workspaceId) => {
|
|
|
5076
5303
|
var useLineMetrics = (lineId) => {
|
|
5077
5304
|
const supabase = useSupabase();
|
|
5078
5305
|
const dateTimeConfig = useDateTimeConfig();
|
|
5306
|
+
const timezone = useAppTimezone();
|
|
5079
5307
|
const [lineMetrics, setLineMetrics] = useState(null);
|
|
5080
5308
|
const [isLoading, setIsLoading] = useState(true);
|
|
5081
5309
|
const [error, setError] = useState(null);
|
|
5082
5310
|
const fetchLineMetrics = useCallback(async () => {
|
|
5083
5311
|
try {
|
|
5084
|
-
const operationalDate = getOperationalDate(dateTimeConfig.defaultTimezone);
|
|
5312
|
+
const operationalDate = getOperationalDate(timezone || dateTimeConfig.defaultTimezone || "UTC");
|
|
5085
5313
|
const { data, error: fetchError } = await supabase.from("overview_line_metrics").select("*").eq("line_id", lineId).eq("date", operationalDate).single();
|
|
5086
5314
|
if (fetchError) throw fetchError;
|
|
5087
5315
|
setLineMetrics(data);
|
|
@@ -5094,7 +5322,7 @@ var useLineMetrics = (lineId) => {
|
|
|
5094
5322
|
}, [supabase, lineId, dateTimeConfig.defaultTimezone]);
|
|
5095
5323
|
useEffect(() => {
|
|
5096
5324
|
let channels = [];
|
|
5097
|
-
const operationalDate = getOperationalDate(dateTimeConfig.defaultTimezone);
|
|
5325
|
+
const operationalDate = getOperationalDate(timezone || dateTimeConfig.defaultTimezone || "UTC");
|
|
5098
5326
|
const setupSubscriptions = () => {
|
|
5099
5327
|
const lineMetricsChannel = supabase.channel("line-base-metrics").on(
|
|
5100
5328
|
"postgres_changes",
|
|
@@ -5729,7 +5957,7 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
|
|
|
5729
5957
|
return;
|
|
5730
5958
|
}
|
|
5731
5959
|
const channels = [];
|
|
5732
|
-
const operationalDate = date || getOperationalDate();
|
|
5960
|
+
const operationalDate = date || getOperationalDate(defaultTimezone || "UTC");
|
|
5733
5961
|
const currentShift = getCurrentShift(defaultTimezone, shiftConfig);
|
|
5734
5962
|
const queryShiftId = shiftId ?? currentShift.shiftId;
|
|
5735
5963
|
const metricsChannel = supabase.channel(`workspace-metrics-${workspaceId}`).on(
|
|
@@ -5833,6 +6061,7 @@ var useLineWorkspaceMetrics = (lineId, options) => {
|
|
|
5833
6061
|
const databaseConfig = useDatabaseConfig();
|
|
5834
6062
|
const dateTimeConfig = useDateTimeConfig();
|
|
5835
6063
|
const shiftConfig = useShiftConfig();
|
|
6064
|
+
const timezone = useAppTimezone();
|
|
5836
6065
|
const supabase = useSupabase();
|
|
5837
6066
|
const [workspaces, setWorkspaces] = useState([]);
|
|
5838
6067
|
const [loading, setLoading] = useState(true);
|
|
@@ -5846,8 +6075,8 @@ var useLineWorkspaceMetrics = (lineId, options) => {
|
|
|
5846
6075
|
return options?.initialShiftId !== void 0 ? options.initialShiftId : currentShift.shiftId;
|
|
5847
6076
|
}, [options?.initialShiftId, dateTimeConfig.defaultTimezone, shiftConfig]);
|
|
5848
6077
|
const queryDate = useMemo(() => {
|
|
5849
|
-
return options?.initialDate || getOperationalDate(dateTimeConfig.defaultTimezone);
|
|
5850
|
-
}, [options?.initialDate, dateTimeConfig.defaultTimezone]);
|
|
6078
|
+
return options?.initialDate || getOperationalDate(timezone || dateTimeConfig.defaultTimezone || "UTC");
|
|
6079
|
+
}, [options?.initialDate, timezone, dateTimeConfig.defaultTimezone]);
|
|
5851
6080
|
const metricsTable = useMemo(() => {
|
|
5852
6081
|
const companyId = entityConfig.companyId;
|
|
5853
6082
|
if (!companyId) return "";
|
|
@@ -6634,7 +6863,8 @@ var useRealtimeLineMetrics = ({
|
|
|
6634
6863
|
() => urlShiftId !== void 0 ? urlShiftId : currentShift.shiftId,
|
|
6635
6864
|
[urlShiftId, currentShift.shiftId]
|
|
6636
6865
|
);
|
|
6637
|
-
const
|
|
6866
|
+
const timezone = useAppTimezone();
|
|
6867
|
+
const date = useMemo(() => urlDate || getOperationalDate(timezone || dateTimeConfig.defaultTimezone || "UTC"), [urlDate, timezone, dateTimeConfig.defaultTimezone]);
|
|
6638
6868
|
const fetchData = useCallback(async () => {
|
|
6639
6869
|
try {
|
|
6640
6870
|
if (!lineIdRef.current || isFetchingRef.current) return;
|
|
@@ -6874,7 +7104,7 @@ var useRealtimeLineMetrics = ({
|
|
|
6874
7104
|
if (process.env.NODE_ENV === "development") {
|
|
6875
7105
|
console.log("Line metrics update received:", payloadData);
|
|
6876
7106
|
}
|
|
6877
|
-
const currentDate = urlDate || getOperationalDate(dateTimeConfig.defaultTimezone);
|
|
7107
|
+
const currentDate = urlDate || getOperationalDate(timezone || dateTimeConfig.defaultTimezone || "UTC");
|
|
6878
7108
|
if (payloadData?.date === currentDate && payloadData?.shift_id === shiftId) {
|
|
6879
7109
|
queueUpdate();
|
|
6880
7110
|
}
|
|
@@ -6897,7 +7127,7 @@ var useRealtimeLineMetrics = ({
|
|
|
6897
7127
|
if (process.env.NODE_ENV === "development") {
|
|
6898
7128
|
console.log(`${metricsTablePrefix} update received:`, payloadData);
|
|
6899
7129
|
}
|
|
6900
|
-
const currentDate = urlDate || getOperationalDate(dateTimeConfig.defaultTimezone);
|
|
7130
|
+
const currentDate = urlDate || getOperationalDate(timezone || dateTimeConfig.defaultTimezone || "UTC");
|
|
6901
7131
|
if (payloadData?.date === currentDate && payloadData?.shift_id === shiftId) {
|
|
6902
7132
|
queueUpdate();
|
|
6903
7133
|
}
|
|
@@ -8212,6 +8442,7 @@ var useAllWorkspaceMetrics = (options) => {
|
|
|
8212
8442
|
const databaseConfig = useDatabaseConfig();
|
|
8213
8443
|
const dateTimeConfig = useDateTimeConfig();
|
|
8214
8444
|
const shiftConfig = useShiftConfig();
|
|
8445
|
+
const timezone = useAppTimezone();
|
|
8215
8446
|
const supabase = useSupabase();
|
|
8216
8447
|
const [workspaces, setWorkspaces] = useState([]);
|
|
8217
8448
|
const [loading, setLoading] = useState(true);
|
|
@@ -8225,8 +8456,8 @@ var useAllWorkspaceMetrics = (options) => {
|
|
|
8225
8456
|
return options?.initialShiftId !== void 0 ? options.initialShiftId : currentShift.shiftId;
|
|
8226
8457
|
}, [options?.initialShiftId, dateTimeConfig.defaultTimezone, shiftConfig]);
|
|
8227
8458
|
const queryDate = useMemo(() => {
|
|
8228
|
-
return options?.initialDate || getOperationalDate(dateTimeConfig.defaultTimezone);
|
|
8229
|
-
}, [options?.initialDate, dateTimeConfig.defaultTimezone]);
|
|
8459
|
+
return options?.initialDate || getOperationalDate(timezone || dateTimeConfig.defaultTimezone || "UTC");
|
|
8460
|
+
}, [options?.initialDate, timezone, dateTimeConfig.defaultTimezone]);
|
|
8230
8461
|
const metricsTable = useMemo(() => {
|
|
8231
8462
|
const companyId = entityConfig.companyId;
|
|
8232
8463
|
if (!companyId) return "";
|
|
@@ -12231,7 +12462,7 @@ var MotionConfigContext = createContext({
|
|
|
12231
12462
|
});
|
|
12232
12463
|
|
|
12233
12464
|
// ../../node_modules/framer-motion/dist/es/components/AnimatePresence/PopChild.mjs
|
|
12234
|
-
var PopChildMeasure = class extends
|
|
12465
|
+
var PopChildMeasure = class extends React21.Component {
|
|
12235
12466
|
getSnapshotBeforeUpdate(prevProps) {
|
|
12236
12467
|
const element = this.props.childRef.current;
|
|
12237
12468
|
if (element && prevProps.isPresent && !this.props.isPresent) {
|
|
@@ -12286,7 +12517,7 @@ function PopChild({ children, isPresent }) {
|
|
|
12286
12517
|
document.head.removeChild(style);
|
|
12287
12518
|
};
|
|
12288
12519
|
}, [isPresent]);
|
|
12289
|
-
return jsx(PopChildMeasure, { isPresent, childRef: ref, sizeRef: size, children:
|
|
12520
|
+
return jsx(PopChildMeasure, { isPresent, childRef: ref, sizeRef: size, children: React21.cloneElement(children, { ref }) });
|
|
12290
12521
|
}
|
|
12291
12522
|
|
|
12292
12523
|
// ../../node_modules/framer-motion/dist/es/components/AnimatePresence/PresenceChild.mjs
|
|
@@ -12323,7 +12554,7 @@ var PresenceChild = ({ children, initial, isPresent, onExitComplete, custom, pre
|
|
|
12323
12554
|
useMemo(() => {
|
|
12324
12555
|
presenceChildren.forEach((_, key) => presenceChildren.set(key, false));
|
|
12325
12556
|
}, [isPresent]);
|
|
12326
|
-
|
|
12557
|
+
React21.useEffect(() => {
|
|
12327
12558
|
!isPresent && !presenceChildren.size && onExitComplete && onExitComplete();
|
|
12328
12559
|
}, [isPresent]);
|
|
12329
12560
|
if (mode === "popLayout") {
|
|
@@ -19607,7 +19838,7 @@ var LoadingPage = ({
|
|
|
19607
19838
|
subMessage = "Please wait while we prepare your data",
|
|
19608
19839
|
className
|
|
19609
19840
|
}) => {
|
|
19610
|
-
|
|
19841
|
+
React21__default.useEffect(() => {
|
|
19611
19842
|
console.log("LoadingPage rendered with message:", message);
|
|
19612
19843
|
const timeout = setTimeout(() => {
|
|
19613
19844
|
console.warn("LoadingPage has been visible for more than 8 seconds. This might indicate an issue.");
|
|
@@ -19648,15 +19879,15 @@ var withAuth = (WrappedComponent2, options) => {
|
|
|
19648
19879
|
requireAuth: true,
|
|
19649
19880
|
...options
|
|
19650
19881
|
};
|
|
19651
|
-
const WithAuthComponent =
|
|
19882
|
+
const WithAuthComponent = React21.memo(function WithAuthComponent2(props) {
|
|
19652
19883
|
const { session, loading, error } = useAuth();
|
|
19653
19884
|
const router = useRouter();
|
|
19654
|
-
|
|
19885
|
+
React21.useEffect(() => {
|
|
19655
19886
|
if (process.env.NODE_ENV === "development" && process.env.DEBUG_AUTH === "true") {
|
|
19656
19887
|
console.log("withAuth state:", { loading, hasSession: !!session, requireAuth: defaultOptions.requireAuth });
|
|
19657
19888
|
}
|
|
19658
19889
|
}, [session, loading]);
|
|
19659
|
-
|
|
19890
|
+
React21.useEffect(() => {
|
|
19660
19891
|
if (!loading && defaultOptions.requireAuth && !session && !error) {
|
|
19661
19892
|
console.log("Redirecting to login from withAuth");
|
|
19662
19893
|
router.replace(defaultOptions.redirectTo);
|
|
@@ -20032,11 +20263,11 @@ var BarChartComponent = ({
|
|
|
20032
20263
|
aspect = 2,
|
|
20033
20264
|
...restOfChartProps
|
|
20034
20265
|
}) => {
|
|
20035
|
-
const containerRef =
|
|
20036
|
-
const [containerReady, setContainerReady] =
|
|
20266
|
+
const containerRef = React21__default.useRef(null);
|
|
20267
|
+
const [containerReady, setContainerReady] = React21__default.useState(false);
|
|
20037
20268
|
const themeConfig = useThemeConfig();
|
|
20038
20269
|
const { formatNumber } = useFormatNumber();
|
|
20039
|
-
|
|
20270
|
+
React21__default.useEffect(() => {
|
|
20040
20271
|
const checkContainerDimensions = () => {
|
|
20041
20272
|
if (containerRef.current) {
|
|
20042
20273
|
const rect = containerRef.current.getBoundingClientRect();
|
|
@@ -20134,7 +20365,7 @@ var BarChartComponent = ({
|
|
|
20134
20365
|
}
|
|
20135
20366
|
return /* @__PURE__ */ jsx("div", { className: clsx("w-full", className), children: chartContent });
|
|
20136
20367
|
};
|
|
20137
|
-
var BarChart =
|
|
20368
|
+
var BarChart = React21__default.memo(BarChartComponent, (prevProps, nextProps) => {
|
|
20138
20369
|
if (prevProps.xAxisDataKey !== nextProps.xAxisDataKey || prevProps.xAxisLabel !== nextProps.xAxisLabel || prevProps.yAxisLabel !== nextProps.yAxisLabel || prevProps.yAxisUnit !== nextProps.yAxisUnit || prevProps.layout !== nextProps.layout || prevProps.className !== nextProps.className || prevProps.showGrid !== nextProps.showGrid || prevProps.showLegend !== nextProps.showLegend || prevProps.showTooltip !== nextProps.showTooltip || prevProps.responsive !== nextProps.responsive || prevProps.aspect !== nextProps.aspect) {
|
|
20139
20370
|
return false;
|
|
20140
20371
|
}
|
|
@@ -20182,11 +20413,11 @@ var LineChartComponent = ({
|
|
|
20182
20413
|
aspect = 2,
|
|
20183
20414
|
...restOfChartProps
|
|
20184
20415
|
}) => {
|
|
20185
|
-
const containerRef =
|
|
20186
|
-
const [containerReady, setContainerReady] =
|
|
20416
|
+
const containerRef = React21__default.useRef(null);
|
|
20417
|
+
const [containerReady, setContainerReady] = React21__default.useState(false);
|
|
20187
20418
|
const themeConfig = useThemeConfig();
|
|
20188
20419
|
const { formatNumber } = useFormatNumber();
|
|
20189
|
-
|
|
20420
|
+
React21__default.useEffect(() => {
|
|
20190
20421
|
const checkContainerDimensions = () => {
|
|
20191
20422
|
if (containerRef.current) {
|
|
20192
20423
|
const rect = containerRef.current.getBoundingClientRect();
|
|
@@ -20285,7 +20516,7 @@ var LineChartComponent = ({
|
|
|
20285
20516
|
}
|
|
20286
20517
|
return /* @__PURE__ */ jsx("div", { className: clsx("w-full", className), children: chartContent });
|
|
20287
20518
|
};
|
|
20288
|
-
var LineChart =
|
|
20519
|
+
var LineChart = React21__default.memo(LineChartComponent, (prevProps, nextProps) => {
|
|
20289
20520
|
if (prevProps.xAxisDataKey !== nextProps.xAxisDataKey || prevProps.xAxisLabel !== nextProps.xAxisLabel || prevProps.yAxisLabel !== nextProps.yAxisLabel || prevProps.yAxisUnit !== nextProps.yAxisUnit || prevProps.className !== nextProps.className || prevProps.showGrid !== nextProps.showGrid || prevProps.showLegend !== nextProps.showLegend || prevProps.showTooltip !== nextProps.showTooltip || prevProps.responsive !== nextProps.responsive || prevProps.aspect !== nextProps.aspect || JSON.stringify(prevProps.yAxisDomain) !== JSON.stringify(nextProps.yAxisDomain)) {
|
|
20290
20521
|
return false;
|
|
20291
20522
|
}
|
|
@@ -20362,7 +20593,7 @@ var OutputProgressChartComponent = ({
|
|
|
20362
20593
|
] }) })
|
|
20363
20594
|
] }) });
|
|
20364
20595
|
};
|
|
20365
|
-
var OutputProgressChart =
|
|
20596
|
+
var OutputProgressChart = React21__default.memo(OutputProgressChartComponent);
|
|
20366
20597
|
OutputProgressChart.displayName = "OutputProgressChart";
|
|
20367
20598
|
var LargeOutputProgressChart = ({
|
|
20368
20599
|
currentOutput,
|
|
@@ -20478,7 +20709,7 @@ var CycleTimeChartComponent = ({
|
|
|
20478
20709
|
}
|
|
20479
20710
|
) }) });
|
|
20480
20711
|
};
|
|
20481
|
-
var CycleTimeChart =
|
|
20712
|
+
var CycleTimeChart = React21__default.memo(CycleTimeChartComponent, (prevProps, nextProps) => {
|
|
20482
20713
|
if (prevProps.className !== nextProps.className) {
|
|
20483
20714
|
return false;
|
|
20484
20715
|
}
|
|
@@ -20504,8 +20735,8 @@ var CycleTimeOverTimeChart = ({
|
|
|
20504
20735
|
className = ""
|
|
20505
20736
|
}) => {
|
|
20506
20737
|
const MAX_DATA_POINTS = 40;
|
|
20507
|
-
const containerRef =
|
|
20508
|
-
const [containerReady, setContainerReady] =
|
|
20738
|
+
const containerRef = React21__default.useRef(null);
|
|
20739
|
+
const [containerReady, setContainerReady] = React21__default.useState(false);
|
|
20509
20740
|
const getHourFromTimeString = (timeStr) => {
|
|
20510
20741
|
const [hours, minutes] = timeStr.split(":");
|
|
20511
20742
|
return parseInt(hours);
|
|
@@ -20516,10 +20747,10 @@ var CycleTimeOverTimeChart = ({
|
|
|
20516
20747
|
};
|
|
20517
20748
|
const displayData = getDisplayData(data);
|
|
20518
20749
|
const DURATION = displayData.length;
|
|
20519
|
-
const [animatedData, setAnimatedData] =
|
|
20520
|
-
const prevDataRef =
|
|
20521
|
-
const animationFrameRef =
|
|
20522
|
-
const animateToNewData =
|
|
20750
|
+
const [animatedData, setAnimatedData] = React21__default.useState(Array(DURATION).fill(0));
|
|
20751
|
+
const prevDataRef = React21__default.useRef(Array(DURATION).fill(0));
|
|
20752
|
+
const animationFrameRef = React21__default.useRef(null);
|
|
20753
|
+
const animateToNewData = React21__default.useCallback((targetData) => {
|
|
20523
20754
|
const startData = [...prevDataRef.current];
|
|
20524
20755
|
const startTime = performance.now();
|
|
20525
20756
|
const duration = 1200;
|
|
@@ -20549,7 +20780,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
20549
20780
|
}
|
|
20550
20781
|
animationFrameRef.current = requestAnimationFrame(animate);
|
|
20551
20782
|
}, []);
|
|
20552
|
-
|
|
20783
|
+
React21__default.useEffect(() => {
|
|
20553
20784
|
if (JSON.stringify(data) !== JSON.stringify(prevDataRef.current)) {
|
|
20554
20785
|
const processedData = getDisplayData(data);
|
|
20555
20786
|
animateToNewData(processedData);
|
|
@@ -20560,7 +20791,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
20560
20791
|
}
|
|
20561
20792
|
};
|
|
20562
20793
|
}, [data, animateToNewData]);
|
|
20563
|
-
|
|
20794
|
+
React21__default.useEffect(() => {
|
|
20564
20795
|
const checkContainerDimensions = () => {
|
|
20565
20796
|
if (containerRef.current) {
|
|
20566
20797
|
const rect = containerRef.current.getBoundingClientRect();
|
|
@@ -20803,7 +21034,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
20803
21034
|
}
|
|
20804
21035
|
);
|
|
20805
21036
|
};
|
|
20806
|
-
var Card =
|
|
21037
|
+
var Card = React21.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
20807
21038
|
"div",
|
|
20808
21039
|
{
|
|
20809
21040
|
ref,
|
|
@@ -20815,7 +21046,7 @@ var Card = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
|
20815
21046
|
}
|
|
20816
21047
|
));
|
|
20817
21048
|
Card.displayName = "Card";
|
|
20818
|
-
var CardHeader =
|
|
21049
|
+
var CardHeader = React21.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
20819
21050
|
"div",
|
|
20820
21051
|
{
|
|
20821
21052
|
ref,
|
|
@@ -20824,7 +21055,7 @@ var CardHeader = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
20824
21055
|
}
|
|
20825
21056
|
));
|
|
20826
21057
|
CardHeader.displayName = "CardHeader";
|
|
20827
|
-
var CardTitle =
|
|
21058
|
+
var CardTitle = React21.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
20828
21059
|
"h3",
|
|
20829
21060
|
{
|
|
20830
21061
|
ref,
|
|
@@ -20836,7 +21067,7 @@ var CardTitle = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE_
|
|
|
20836
21067
|
}
|
|
20837
21068
|
));
|
|
20838
21069
|
CardTitle.displayName = "CardTitle";
|
|
20839
|
-
var CardDescription =
|
|
21070
|
+
var CardDescription = React21.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
20840
21071
|
"p",
|
|
20841
21072
|
{
|
|
20842
21073
|
ref,
|
|
@@ -20845,9 +21076,9 @@ var CardDescription = React20.forwardRef(({ className, ...props }, ref) => /* @_
|
|
|
20845
21076
|
}
|
|
20846
21077
|
));
|
|
20847
21078
|
CardDescription.displayName = "CardDescription";
|
|
20848
|
-
var CardContent =
|
|
21079
|
+
var CardContent = React21.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-6 pt-0", className), ...props }));
|
|
20849
21080
|
CardContent.displayName = "CardContent";
|
|
20850
|
-
var CardFooter =
|
|
21081
|
+
var CardFooter = React21.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
20851
21082
|
"div",
|
|
20852
21083
|
{
|
|
20853
21084
|
ref,
|
|
@@ -20923,7 +21154,7 @@ var buttonVariants = cva(
|
|
|
20923
21154
|
}
|
|
20924
21155
|
}
|
|
20925
21156
|
);
|
|
20926
|
-
var Button =
|
|
21157
|
+
var Button = React21.forwardRef(
|
|
20927
21158
|
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
20928
21159
|
const Comp = asChild ? Slot : "button";
|
|
20929
21160
|
return /* @__PURE__ */ jsx(
|
|
@@ -20946,8 +21177,8 @@ var HourlyOutputChartComponent = ({
|
|
|
20946
21177
|
idleTimeHourly,
|
|
20947
21178
|
className = ""
|
|
20948
21179
|
}) => {
|
|
20949
|
-
const containerRef =
|
|
20950
|
-
const [containerReady, setContainerReady] =
|
|
21180
|
+
const containerRef = React21__default.useRef(null);
|
|
21181
|
+
const [containerReady, setContainerReady] = React21__default.useState(false);
|
|
20951
21182
|
const getTimeFromTimeString = (timeStr) => {
|
|
20952
21183
|
const [hours, minutes] = timeStr.split(":");
|
|
20953
21184
|
const hour = parseInt(hours);
|
|
@@ -20956,7 +21187,7 @@ var HourlyOutputChartComponent = ({
|
|
|
20956
21187
|
return { hour, minute, decimalHour };
|
|
20957
21188
|
};
|
|
20958
21189
|
const shiftStartTime = getTimeFromTimeString(shiftStart);
|
|
20959
|
-
const { shiftDuration, shiftEndTime, hasPartialLastHour } =
|
|
21190
|
+
const { shiftDuration, shiftEndTime, hasPartialLastHour } = React21__default.useMemo(() => {
|
|
20960
21191
|
console.log("[HourlyOutputChart] Calculating shift duration with:", {
|
|
20961
21192
|
shiftStart,
|
|
20962
21193
|
shiftEnd,
|
|
@@ -20991,12 +21222,12 @@ var HourlyOutputChartComponent = ({
|
|
|
20991
21222
|
}, [shiftEnd, shiftStartTime.decimalHour]);
|
|
20992
21223
|
const SHIFT_DURATION = shiftDuration;
|
|
20993
21224
|
shiftEndTime ? shiftEndTime.hour : (shiftStartTime.hour + SHIFT_DURATION) % 24;
|
|
20994
|
-
const [animatedData, setAnimatedData] =
|
|
21225
|
+
const [animatedData, setAnimatedData] = React21__default.useState(
|
|
20995
21226
|
() => Array(SHIFT_DURATION).fill(0)
|
|
20996
21227
|
);
|
|
20997
|
-
const prevDataRef =
|
|
20998
|
-
const animationFrameRef =
|
|
20999
|
-
|
|
21228
|
+
const prevDataRef = React21__default.useRef(Array(SHIFT_DURATION).fill(0));
|
|
21229
|
+
const animationFrameRef = React21__default.useRef(null);
|
|
21230
|
+
React21__default.useEffect(() => {
|
|
21000
21231
|
setAnimatedData((prev) => {
|
|
21001
21232
|
if (prev.length !== SHIFT_DURATION) {
|
|
21002
21233
|
return Array(SHIFT_DURATION).fill(0);
|
|
@@ -21005,14 +21236,14 @@ var HourlyOutputChartComponent = ({
|
|
|
21005
21236
|
});
|
|
21006
21237
|
prevDataRef.current = Array(SHIFT_DURATION).fill(0);
|
|
21007
21238
|
}, [SHIFT_DURATION]);
|
|
21008
|
-
const [idleBarState, setIdleBarState] =
|
|
21239
|
+
const [idleBarState, setIdleBarState] = React21__default.useState({
|
|
21009
21240
|
visible: showIdleTime,
|
|
21010
21241
|
key: 0,
|
|
21011
21242
|
shouldAnimate: false
|
|
21012
21243
|
});
|
|
21013
|
-
const prevShowIdleTimeRef =
|
|
21014
|
-
const stateUpdateTimeoutRef =
|
|
21015
|
-
|
|
21244
|
+
const prevShowIdleTimeRef = React21__default.useRef(showIdleTime);
|
|
21245
|
+
const stateUpdateTimeoutRef = React21__default.useRef(null);
|
|
21246
|
+
React21__default.useEffect(() => {
|
|
21016
21247
|
if (stateUpdateTimeoutRef.current) {
|
|
21017
21248
|
clearTimeout(stateUpdateTimeoutRef.current);
|
|
21018
21249
|
}
|
|
@@ -21037,7 +21268,7 @@ var HourlyOutputChartComponent = ({
|
|
|
21037
21268
|
}
|
|
21038
21269
|
};
|
|
21039
21270
|
}, [showIdleTime]);
|
|
21040
|
-
const animateToNewData =
|
|
21271
|
+
const animateToNewData = React21__default.useCallback((targetData) => {
|
|
21041
21272
|
const startData = [...prevDataRef.current];
|
|
21042
21273
|
const startTime = performance.now();
|
|
21043
21274
|
const duration = 1200;
|
|
@@ -21067,7 +21298,7 @@ var HourlyOutputChartComponent = ({
|
|
|
21067
21298
|
}
|
|
21068
21299
|
animationFrameRef.current = requestAnimationFrame(animate);
|
|
21069
21300
|
}, []);
|
|
21070
|
-
|
|
21301
|
+
React21__default.useEffect(() => {
|
|
21071
21302
|
if (JSON.stringify(data) !== JSON.stringify(prevDataRef.current)) {
|
|
21072
21303
|
const shiftData = data.slice(0, SHIFT_DURATION);
|
|
21073
21304
|
animateToNewData(shiftData);
|
|
@@ -21078,7 +21309,7 @@ var HourlyOutputChartComponent = ({
|
|
|
21078
21309
|
}
|
|
21079
21310
|
};
|
|
21080
21311
|
}, [data, animateToNewData]);
|
|
21081
|
-
|
|
21312
|
+
React21__default.useEffect(() => {
|
|
21082
21313
|
const checkContainerDimensions = () => {
|
|
21083
21314
|
if (containerRef.current) {
|
|
21084
21315
|
const rect = containerRef.current.getBoundingClientRect();
|
|
@@ -21100,7 +21331,7 @@ var HourlyOutputChartComponent = ({
|
|
|
21100
21331
|
clearTimeout(fallbackTimeout);
|
|
21101
21332
|
};
|
|
21102
21333
|
}, []);
|
|
21103
|
-
const formatHour =
|
|
21334
|
+
const formatHour = React21__default.useCallback((hourIndex) => {
|
|
21104
21335
|
const isLastHour = hourIndex === SHIFT_DURATION - 1;
|
|
21105
21336
|
const startDecimalHour = shiftStartTime.decimalHour + hourIndex;
|
|
21106
21337
|
const startHour = Math.floor(startDecimalHour) % 24;
|
|
@@ -21124,7 +21355,7 @@ var HourlyOutputChartComponent = ({
|
|
|
21124
21355
|
};
|
|
21125
21356
|
return `${formatTime3(startHour, startMinute)}-${formatTime3(endHour, endMinute)}`;
|
|
21126
21357
|
}, [shiftStartTime.decimalHour, SHIFT_DURATION, shiftEndTime]);
|
|
21127
|
-
const formatTimeRange =
|
|
21358
|
+
const formatTimeRange = React21__default.useCallback((hourIndex) => {
|
|
21128
21359
|
const isLastHour = hourIndex === SHIFT_DURATION - 1;
|
|
21129
21360
|
const startDecimalHour = shiftStartTime.decimalHour + hourIndex;
|
|
21130
21361
|
const startHour = Math.floor(startDecimalHour) % 24;
|
|
@@ -21145,7 +21376,7 @@ var HourlyOutputChartComponent = ({
|
|
|
21145
21376
|
};
|
|
21146
21377
|
return `${formatTime3(startHour, startMinute)} - ${formatTime3(endHour, endMinute)}`;
|
|
21147
21378
|
}, [shiftStartTime.decimalHour, SHIFT_DURATION, shiftEndTime]);
|
|
21148
|
-
const chartData =
|
|
21379
|
+
const chartData = React21__default.useMemo(() => {
|
|
21149
21380
|
return Array.from({ length: SHIFT_DURATION }, (_, i) => {
|
|
21150
21381
|
const actualHour = (shiftStartTime.hour + i) % 24;
|
|
21151
21382
|
const startMinute = shiftStartTime.minute;
|
|
@@ -21214,7 +21445,7 @@ var HourlyOutputChartComponent = ({
|
|
|
21214
21445
|
};
|
|
21215
21446
|
});
|
|
21216
21447
|
}, [animatedData, data, pphThreshold, idleTimeHourly, shiftStartTime.hour, shiftStartTime.minute, shiftEndTime, formatHour, formatTimeRange, SHIFT_DURATION]);
|
|
21217
|
-
const IdleBar =
|
|
21448
|
+
const IdleBar = React21__default.useMemo(() => {
|
|
21218
21449
|
if (!idleBarState.visible) return null;
|
|
21219
21450
|
return /* @__PURE__ */ jsx(
|
|
21220
21451
|
Bar,
|
|
@@ -21539,7 +21770,7 @@ var HourlyOutputChartComponent = ({
|
|
|
21539
21770
|
}
|
|
21540
21771
|
);
|
|
21541
21772
|
};
|
|
21542
|
-
var HourlyOutputChart =
|
|
21773
|
+
var HourlyOutputChart = React21__default.memo(HourlyOutputChartComponent, (prevProps, nextProps) => {
|
|
21543
21774
|
if (prevProps.pphThreshold !== nextProps.pphThreshold || prevProps.shiftStart !== nextProps.shiftStart || prevProps.showIdleTime !== nextProps.showIdleTime || prevProps.className !== nextProps.className) {
|
|
21544
21775
|
return false;
|
|
21545
21776
|
}
|
|
@@ -21575,7 +21806,7 @@ function getTrendArrowAndColor(trend) {
|
|
|
21575
21806
|
return { arrow: "\u2192", color: "text-gray-400" };
|
|
21576
21807
|
}
|
|
21577
21808
|
}
|
|
21578
|
-
var VideoCard =
|
|
21809
|
+
var VideoCard = React21__default.memo(({
|
|
21579
21810
|
workspace,
|
|
21580
21811
|
hlsUrl,
|
|
21581
21812
|
shouldPlay,
|
|
@@ -21724,7 +21955,7 @@ var VideoCard = React20__default.memo(({
|
|
|
21724
21955
|
});
|
|
21725
21956
|
VideoCard.displayName = "VideoCard";
|
|
21726
21957
|
var DEFAULT_HLS_URL = "https://192.168.5.9:8443/cam1.m3u8";
|
|
21727
|
-
var VideoGridView =
|
|
21958
|
+
var VideoGridView = React21__default.memo(({
|
|
21728
21959
|
workspaces,
|
|
21729
21960
|
selectedLine,
|
|
21730
21961
|
className = "",
|
|
@@ -22639,7 +22870,7 @@ var EmptyStateMessage = ({
|
|
|
22639
22870
|
iconClassName
|
|
22640
22871
|
}) => {
|
|
22641
22872
|
let IconContent = null;
|
|
22642
|
-
if (
|
|
22873
|
+
if (React21__default.isValidElement(iconType)) {
|
|
22643
22874
|
IconContent = iconType;
|
|
22644
22875
|
} else if (typeof iconType === "string") {
|
|
22645
22876
|
const MappedIcon = IconMap[iconType];
|
|
@@ -23458,7 +23689,8 @@ var ShiftDisplay_default = ShiftDisplay;
|
|
|
23458
23689
|
var TimeDisplay = ({ className, variant = "default" }) => {
|
|
23459
23690
|
const { dateTimeConfig } = useDashboardConfig();
|
|
23460
23691
|
const [time2, setTime] = useState("");
|
|
23461
|
-
const
|
|
23692
|
+
const dbTimezone = useAppTimezone();
|
|
23693
|
+
const timezoneToDisplay = dbTimezone || dateTimeConfig?.defaultTimezone || "UTC";
|
|
23462
23694
|
const localeToUse = dateTimeConfig?.defaultLocale || "en-US";
|
|
23463
23695
|
const timeSuffix = "";
|
|
23464
23696
|
useEffect(() => {
|
|
@@ -23522,6 +23754,17 @@ var ISTTimer = memo(() => {
|
|
|
23522
23754
|
});
|
|
23523
23755
|
ISTTimer.displayName = "ISTTimer";
|
|
23524
23756
|
var ISTTimer_default = ISTTimer;
|
|
23757
|
+
var TimeDisplay3 = TimeDisplay_default;
|
|
23758
|
+
var Timer = memo(() => {
|
|
23759
|
+
return /* @__PURE__ */ jsx(
|
|
23760
|
+
TimeDisplay3,
|
|
23761
|
+
{
|
|
23762
|
+
variant: "minimal"
|
|
23763
|
+
}
|
|
23764
|
+
);
|
|
23765
|
+
});
|
|
23766
|
+
Timer.displayName = "Timer";
|
|
23767
|
+
var Timer_default = Timer;
|
|
23525
23768
|
var TicketHistory = ({ companyId }) => {
|
|
23526
23769
|
const { tickets, loading, error } = useTicketHistory(companyId);
|
|
23527
23770
|
const [expandedTickets, setExpandedTickets] = useState(/* @__PURE__ */ new Set());
|
|
@@ -26619,8 +26862,9 @@ var LiveTimer = () => {
|
|
|
26619
26862
|
}, 1e3);
|
|
26620
26863
|
return () => clearInterval(timer);
|
|
26621
26864
|
}, []);
|
|
26622
|
-
const
|
|
26623
|
-
|
|
26865
|
+
const timezone = useAppTimezone();
|
|
26866
|
+
const formatter = new Intl.DateTimeFormat("en-US", {
|
|
26867
|
+
timeZone: timezone,
|
|
26624
26868
|
hour: "2-digit",
|
|
26625
26869
|
minute: "2-digit",
|
|
26626
26870
|
second: "2-digit",
|
|
@@ -26654,7 +26898,7 @@ function Skeleton({ className, ...props }) {
|
|
|
26654
26898
|
var Select = SelectPrimitive.Root;
|
|
26655
26899
|
var SelectGroup = SelectPrimitive.Group;
|
|
26656
26900
|
var SelectValue = SelectPrimitive.Value;
|
|
26657
|
-
var SelectTrigger =
|
|
26901
|
+
var SelectTrigger = React21.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
26658
26902
|
SelectPrimitive.Trigger,
|
|
26659
26903
|
{
|
|
26660
26904
|
ref,
|
|
@@ -26670,7 +26914,7 @@ var SelectTrigger = React20.forwardRef(({ className, children, ...props }, ref)
|
|
|
26670
26914
|
}
|
|
26671
26915
|
));
|
|
26672
26916
|
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
|
26673
|
-
var SelectScrollUpButton =
|
|
26917
|
+
var SelectScrollUpButton = React21.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
26674
26918
|
SelectPrimitive.ScrollUpButton,
|
|
26675
26919
|
{
|
|
26676
26920
|
ref,
|
|
@@ -26680,7 +26924,7 @@ var SelectScrollUpButton = React20.forwardRef(({ className, ...props }, ref) =>
|
|
|
26680
26924
|
}
|
|
26681
26925
|
));
|
|
26682
26926
|
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
|
|
26683
|
-
var SelectScrollDownButton =
|
|
26927
|
+
var SelectScrollDownButton = React21.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
26684
26928
|
SelectPrimitive.ScrollDownButton,
|
|
26685
26929
|
{
|
|
26686
26930
|
ref,
|
|
@@ -26690,7 +26934,7 @@ var SelectScrollDownButton = React20.forwardRef(({ className, ...props }, ref) =
|
|
|
26690
26934
|
}
|
|
26691
26935
|
));
|
|
26692
26936
|
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
|
|
26693
|
-
var SelectContent =
|
|
26937
|
+
var SelectContent = React21.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
|
|
26694
26938
|
SelectPrimitive.Content,
|
|
26695
26939
|
{
|
|
26696
26940
|
ref,
|
|
@@ -26718,7 +26962,7 @@ var SelectContent = React20.forwardRef(({ className, children, position = "poppe
|
|
|
26718
26962
|
}
|
|
26719
26963
|
) }));
|
|
26720
26964
|
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
|
26721
|
-
var SelectLabel =
|
|
26965
|
+
var SelectLabel = React21.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
26722
26966
|
SelectPrimitive.Label,
|
|
26723
26967
|
{
|
|
26724
26968
|
ref,
|
|
@@ -26727,7 +26971,7 @@ var SelectLabel = React20.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
26727
26971
|
}
|
|
26728
26972
|
));
|
|
26729
26973
|
SelectLabel.displayName = SelectPrimitive.Label.displayName;
|
|
26730
|
-
var SelectItem =
|
|
26974
|
+
var SelectItem = React21.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
26731
26975
|
SelectPrimitive.Item,
|
|
26732
26976
|
{
|
|
26733
26977
|
ref,
|
|
@@ -26743,7 +26987,7 @@ var SelectItem = React20.forwardRef(({ className, children, ...props }, ref) =>
|
|
|
26743
26987
|
}
|
|
26744
26988
|
));
|
|
26745
26989
|
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
|
26746
|
-
var SelectSeparator =
|
|
26990
|
+
var SelectSeparator = React21.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
26747
26991
|
SelectPrimitive.Separator,
|
|
26748
26992
|
{
|
|
26749
26993
|
ref,
|
|
@@ -27036,7 +27280,7 @@ if (typeof document !== "undefined") {
|
|
|
27036
27280
|
document.head.appendChild(style);
|
|
27037
27281
|
}
|
|
27038
27282
|
}
|
|
27039
|
-
var VideoPlayer =
|
|
27283
|
+
var VideoPlayer = React21__default.forwardRef(({
|
|
27040
27284
|
src,
|
|
27041
27285
|
poster,
|
|
27042
27286
|
autoplay = false,
|
|
@@ -27046,15 +27290,19 @@ var VideoPlayer = React20__default.forwardRef(({
|
|
|
27046
27290
|
playsInline = true,
|
|
27047
27291
|
className = "",
|
|
27048
27292
|
options = {},
|
|
27293
|
+
externalLoadingControl = false,
|
|
27294
|
+
onLoadingChange,
|
|
27049
27295
|
onReady,
|
|
27050
27296
|
onPlay,
|
|
27051
27297
|
onPause,
|
|
27298
|
+
onPlaying,
|
|
27052
27299
|
onTimeUpdate,
|
|
27053
27300
|
onDurationChange,
|
|
27054
27301
|
onEnded,
|
|
27055
27302
|
onError,
|
|
27056
27303
|
onLoadStart,
|
|
27057
27304
|
onLoadedMetadata,
|
|
27305
|
+
onLoadedData,
|
|
27058
27306
|
onSeeking,
|
|
27059
27307
|
onSeeked
|
|
27060
27308
|
}, ref) => {
|
|
@@ -27176,6 +27424,7 @@ var VideoPlayer = React20__default.forwardRef(({
|
|
|
27176
27424
|
});
|
|
27177
27425
|
player.on("play", () => onPlay?.(player));
|
|
27178
27426
|
player.on("pause", () => onPause?.(player));
|
|
27427
|
+
player.on("playing", () => onPlaying?.(player));
|
|
27179
27428
|
player.on("timeupdate", () => {
|
|
27180
27429
|
const currentTime2 = player.currentTime() || 0;
|
|
27181
27430
|
onTimeUpdate?.(player, currentTime2);
|
|
@@ -27187,16 +27436,21 @@ var VideoPlayer = React20__default.forwardRef(({
|
|
|
27187
27436
|
player.on("ended", () => onEnded?.(player));
|
|
27188
27437
|
player.on("loadstart", () => {
|
|
27189
27438
|
setIsLoading(true);
|
|
27439
|
+
onLoadingChange?.(true);
|
|
27190
27440
|
onLoadStart?.(player);
|
|
27191
27441
|
});
|
|
27192
27442
|
player.on("loadeddata", () => {
|
|
27193
27443
|
setIsLoading(false);
|
|
27444
|
+
onLoadingChange?.(false);
|
|
27445
|
+
onLoadedData?.(player);
|
|
27194
27446
|
});
|
|
27195
27447
|
player.on("waiting", () => {
|
|
27196
27448
|
setIsLoading(true);
|
|
27449
|
+
onLoadingChange?.(true);
|
|
27197
27450
|
});
|
|
27198
27451
|
player.on("playing", () => {
|
|
27199
27452
|
setIsLoading(false);
|
|
27453
|
+
onLoadingChange?.(false);
|
|
27200
27454
|
});
|
|
27201
27455
|
player.on("loadedmetadata", () => {
|
|
27202
27456
|
onLoadedMetadata?.(player);
|
|
@@ -27321,7 +27575,7 @@ var VideoPlayer = React20__default.forwardRef(({
|
|
|
27321
27575
|
setIsReady(false);
|
|
27322
27576
|
}
|
|
27323
27577
|
}, []);
|
|
27324
|
-
|
|
27578
|
+
React21__default.useImperativeHandle(ref, () => ({
|
|
27325
27579
|
player: playerRef.current,
|
|
27326
27580
|
play,
|
|
27327
27581
|
pause,
|
|
@@ -27342,7 +27596,7 @@ var VideoPlayer = React20__default.forwardRef(({
|
|
|
27342
27596
|
"data-vjs-player": true
|
|
27343
27597
|
}
|
|
27344
27598
|
),
|
|
27345
|
-
isLoading && /* @__PURE__ */ jsx("div", { className: "video-player-loading", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) })
|
|
27599
|
+
isLoading && !externalLoadingControl && /* @__PURE__ */ jsx("div", { className: "video-player-loading", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) })
|
|
27346
27600
|
] });
|
|
27347
27601
|
});
|
|
27348
27602
|
VideoPlayer.displayName = "VideoPlayer";
|
|
@@ -27524,7 +27778,10 @@ var CroppedVideoPlayer = forwardRef(({
|
|
|
27524
27778
|
onEnded: handleVideoEnded,
|
|
27525
27779
|
onSeeking: handleSeeking,
|
|
27526
27780
|
onSeeked: handleSeeked,
|
|
27527
|
-
onLoadedMetadata: handleLoadedMetadata
|
|
27781
|
+
onLoadedMetadata: handleLoadedMetadata,
|
|
27782
|
+
onLoadedData: videoProps.onLoadedData,
|
|
27783
|
+
onPlaying: videoProps.onPlaying,
|
|
27784
|
+
onLoadingChange: videoProps.onLoadingChange
|
|
27528
27785
|
}
|
|
27529
27786
|
) }),
|
|
27530
27787
|
/* @__PURE__ */ jsx(
|
|
@@ -28101,6 +28358,7 @@ var FileManagerFilters = ({
|
|
|
28101
28358
|
}) => {
|
|
28102
28359
|
const [expandedNodes, setExpandedNodes] = useState(/* @__PURE__ */ new Set());
|
|
28103
28360
|
const [searchTerm, setSearchTerm] = useState("");
|
|
28361
|
+
const timezone = useAppTimezone();
|
|
28104
28362
|
const [clipMetadata, setClipMetadata] = useState({});
|
|
28105
28363
|
const [loadingCategories, setLoadingCategories] = useState(/* @__PURE__ */ new Set());
|
|
28106
28364
|
const [categoryPages, setCategoryPages] = useState({});
|
|
@@ -28156,8 +28414,8 @@ var FileManagerFilters = ({
|
|
|
28156
28414
|
}, [workspaceId, date, shift]);
|
|
28157
28415
|
const getAuthToken3 = async () => {
|
|
28158
28416
|
try {
|
|
28159
|
-
const { createClient:
|
|
28160
|
-
const supabase =
|
|
28417
|
+
const { createClient: createClient5 } = await import('@supabase/supabase-js');
|
|
28418
|
+
const supabase = createClient5(
|
|
28161
28419
|
process.env.NEXT_PUBLIC_SUPABASE_URL || "",
|
|
28162
28420
|
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || ""
|
|
28163
28421
|
);
|
|
@@ -28266,23 +28524,27 @@ var FileManagerFilters = ({
|
|
|
28266
28524
|
}
|
|
28267
28525
|
if (categoryCount > 0 && shouldShowCategory(category.id)) {
|
|
28268
28526
|
const colorClasses = getColorClasses(category.color);
|
|
28269
|
-
const clipNodes = filteredClips.map((clip) => {
|
|
28527
|
+
const clipNodes = filteredClips.map((clip, index) => {
|
|
28270
28528
|
const timeString = new Date(clip.clip_timestamp).toLocaleTimeString("en-US", {
|
|
28271
28529
|
hour12: false,
|
|
28272
28530
|
hour: "2-digit",
|
|
28273
28531
|
minute: "2-digit",
|
|
28274
|
-
second: "2-digit"
|
|
28532
|
+
second: "2-digit",
|
|
28533
|
+
timeZone: timezone
|
|
28534
|
+
// Use database timezone for display
|
|
28275
28535
|
});
|
|
28276
28536
|
return {
|
|
28277
28537
|
id: clip.id,
|
|
28278
|
-
label: `${timeString} - ${clip.description}${clip.duration ? ` (${clip.duration.toFixed(1)}s)` : ""}`,
|
|
28538
|
+
label: `${timeString} - ${clip.description}${clip.duration && category.id !== "idle_time" ? ` (${clip.duration.toFixed(1)}s)` : ""}`,
|
|
28279
28539
|
type: "video",
|
|
28280
28540
|
icon: getSeverityIcon(clip.severity),
|
|
28281
28541
|
timestamp: clip.clip_timestamp,
|
|
28282
28542
|
severity: clip.severity,
|
|
28283
28543
|
clipId: clip.clipId,
|
|
28284
28544
|
// Store stable UUID for navigation
|
|
28285
|
-
categoryId: category.id
|
|
28545
|
+
categoryId: category.id,
|
|
28546
|
+
clipPosition: index + 1
|
|
28547
|
+
// Store 1-based position
|
|
28286
28548
|
};
|
|
28287
28549
|
});
|
|
28288
28550
|
tree.push({
|
|
@@ -28398,8 +28660,8 @@ var FileManagerFilters = ({
|
|
|
28398
28660
|
onFilterChange(node.id);
|
|
28399
28661
|
} else if (node.type === "video") {
|
|
28400
28662
|
if (onClipSelect && node.categoryId !== void 0 && node.clipId !== void 0) {
|
|
28401
|
-
console.log(`[FileManager] Selecting clip: category=${node.categoryId}, clipId=${node.clipId}`);
|
|
28402
|
-
onClipSelect(node.categoryId, node.clipId);
|
|
28663
|
+
console.log(`[FileManager] Selecting clip: category=${node.categoryId}, clipId=${node.clipId}, position=${node.clipPosition}`);
|
|
28664
|
+
onClipSelect(node.categoryId, node.clipId, node.clipPosition);
|
|
28403
28665
|
} else {
|
|
28404
28666
|
const videoIndex = videos.findIndex((v) => v.id === node.id);
|
|
28405
28667
|
if (videoIndex !== -1) {
|
|
@@ -28931,6 +29193,7 @@ var BottlenecksContent = ({
|
|
|
28931
29193
|
className
|
|
28932
29194
|
}) => {
|
|
28933
29195
|
const dashboardConfig = useDashboardConfig();
|
|
29196
|
+
const timezone = useAppTimezone();
|
|
28934
29197
|
const effectiveShift = useMemo(() => {
|
|
28935
29198
|
if (shift !== void 0 && shift !== null) {
|
|
28936
29199
|
const shiftStr = shift.toString();
|
|
@@ -28942,13 +29205,14 @@ var BottlenecksContent = ({
|
|
|
28942
29205
|
return "0";
|
|
28943
29206
|
} else {
|
|
28944
29207
|
const currentShift = getCurrentShift(
|
|
28945
|
-
|
|
29208
|
+
timezone,
|
|
29209
|
+
// Use dynamic timezone instead of hardcoded default
|
|
28946
29210
|
dashboardConfig.shiftConfig
|
|
28947
29211
|
);
|
|
28948
|
-
console.log(`[BottlenecksContent] Using current operational shift: ${currentShift.shiftId}`);
|
|
29212
|
+
console.log(`[BottlenecksContent] Using current operational shift: ${currentShift.shiftId} with timezone: ${timezone}`);
|
|
28949
29213
|
return currentShift.shiftId.toString();
|
|
28950
29214
|
}
|
|
28951
|
-
}, [shift, date, dashboardConfig]);
|
|
29215
|
+
}, [shift, date, timezone, dashboardConfig]);
|
|
28952
29216
|
const { crop: workspaceCrop} = useWorkspaceCrop(workspaceId);
|
|
28953
29217
|
const videoRef = useRef(null);
|
|
28954
29218
|
const [initialFilter, setInitialFilter] = useState("");
|
|
@@ -28961,6 +29225,11 @@ var BottlenecksContent = ({
|
|
|
28961
29225
|
const [duration, setDuration] = useState(0);
|
|
28962
29226
|
const [currentIndex, setCurrentIndex] = useState(0);
|
|
28963
29227
|
const [currentClipId, setCurrentClipId] = useState(null);
|
|
29228
|
+
const [isTransitioning, setIsTransitioning] = useState(false);
|
|
29229
|
+
const [pendingVideo, setPendingVideo] = useState(null);
|
|
29230
|
+
const [isVideoBuffering, setIsVideoBuffering] = useState(false);
|
|
29231
|
+
const [isInitialLoading, setIsInitialLoading] = useState(false);
|
|
29232
|
+
const loadingTimeoutRef = useRef(null);
|
|
28964
29233
|
const [activeFilter, setActiveFilter] = useState(initialFilter);
|
|
28965
29234
|
const previousFilterRef = useRef("");
|
|
28966
29235
|
const [allVideos, setAllVideos] = useState([]);
|
|
@@ -28970,7 +29239,11 @@ var BottlenecksContent = ({
|
|
|
28970
29239
|
const [isNavigating, setIsNavigating] = useState(false);
|
|
28971
29240
|
const [error, setError] = useState(null);
|
|
28972
29241
|
const [clipCounts, setClipCounts] = useState({});
|
|
28973
|
-
const [
|
|
29242
|
+
const [categoryMetadata, setCategoryMetadata] = useState([]);
|
|
29243
|
+
const [currentMetadataIndex, setCurrentMetadataIndex] = useState(0);
|
|
29244
|
+
const [metadataCache, setMetadataCache] = useState({});
|
|
29245
|
+
const categoryMetadataRef = useRef([]);
|
|
29246
|
+
const currentMetadataIndexRef = useRef(0);
|
|
28974
29247
|
const {
|
|
28975
29248
|
newClipsNotification,
|
|
28976
29249
|
hasNewClips,
|
|
@@ -28978,7 +29251,7 @@ var BottlenecksContent = ({
|
|
|
28978
29251
|
clearNotification
|
|
28979
29252
|
} = useClipsRealtimeUpdates({
|
|
28980
29253
|
workspaceId,
|
|
28981
|
-
date: date || getOperationalDate(),
|
|
29254
|
+
date: date || getOperationalDate(timezone),
|
|
28982
29255
|
shiftId: effectiveShift,
|
|
28983
29256
|
enabled: true,
|
|
28984
29257
|
// Supabase implementation
|
|
@@ -29015,7 +29288,7 @@ var BottlenecksContent = ({
|
|
|
29015
29288
|
counts: dynamicCounts
|
|
29016
29289
|
} = useClipTypesWithCounts(
|
|
29017
29290
|
workspaceId,
|
|
29018
|
-
date || getOperationalDate(),
|
|
29291
|
+
date || getOperationalDate(timezone),
|
|
29019
29292
|
effectiveShift
|
|
29020
29293
|
// Use same shift as video loading for consistency
|
|
29021
29294
|
);
|
|
@@ -29026,7 +29299,7 @@ var BottlenecksContent = ({
|
|
|
29026
29299
|
clipTypesError,
|
|
29027
29300
|
dynamicCounts,
|
|
29028
29301
|
workspaceId,
|
|
29029
|
-
date: date || getOperationalDate(),
|
|
29302
|
+
date: date || getOperationalDate(timezone),
|
|
29030
29303
|
shift: shift || "0"
|
|
29031
29304
|
});
|
|
29032
29305
|
useEffect(() => {
|
|
@@ -29052,7 +29325,7 @@ var BottlenecksContent = ({
|
|
|
29052
29325
|
}
|
|
29053
29326
|
fetchInProgressRef.current.add(operationKey);
|
|
29054
29327
|
try {
|
|
29055
|
-
const operationalDate = date || getOperationalDate();
|
|
29328
|
+
const operationalDate = date || getOperationalDate(timezone);
|
|
29056
29329
|
const shiftStr = effectiveShift;
|
|
29057
29330
|
console.log(`[BottlenecksContent] Fetching clip counts directly with params:`, {
|
|
29058
29331
|
workspaceId,
|
|
@@ -29098,7 +29371,7 @@ var BottlenecksContent = ({
|
|
|
29098
29371
|
setError(null);
|
|
29099
29372
|
}
|
|
29100
29373
|
try {
|
|
29101
|
-
const operationalDate = date || getOperationalDate();
|
|
29374
|
+
const operationalDate = date || getOperationalDate(timezone);
|
|
29102
29375
|
const shiftStr = effectiveShift;
|
|
29103
29376
|
console.log(`[BottlenecksContent] Loading first video for category: ${targetCategory}`);
|
|
29104
29377
|
try {
|
|
@@ -29122,7 +29395,6 @@ var BottlenecksContent = ({
|
|
|
29122
29395
|
setHasInitialLoad(true);
|
|
29123
29396
|
loadingCategoryRef.current = null;
|
|
29124
29397
|
setIsCategoryLoading(false);
|
|
29125
|
-
setCategoryPosition(1);
|
|
29126
29398
|
return;
|
|
29127
29399
|
}
|
|
29128
29400
|
} catch (directError) {
|
|
@@ -29148,7 +29420,6 @@ var BottlenecksContent = ({
|
|
|
29148
29420
|
return prev;
|
|
29149
29421
|
});
|
|
29150
29422
|
setIsCategoryLoading(false);
|
|
29151
|
-
setCategoryPosition(1);
|
|
29152
29423
|
return;
|
|
29153
29424
|
}
|
|
29154
29425
|
} catch (indexError) {
|
|
@@ -29201,10 +29472,16 @@ var BottlenecksContent = ({
|
|
|
29201
29472
|
setIsCategoryLoading(true);
|
|
29202
29473
|
setError(null);
|
|
29203
29474
|
setCurrentIndex(0);
|
|
29204
|
-
setCategoryPosition(1);
|
|
29205
29475
|
setIsNavigating(false);
|
|
29206
29476
|
loadingCategoryRef.current = null;
|
|
29477
|
+
setCategoryMetadata([]);
|
|
29478
|
+
setCurrentMetadataIndex(0);
|
|
29479
|
+
categoryMetadataRef.current = [];
|
|
29480
|
+
currentMetadataIndexRef.current = 0;
|
|
29207
29481
|
previousFilterRef.current = activeFilter;
|
|
29482
|
+
if (activeFilter !== "all") {
|
|
29483
|
+
loadCategoryMetadata(activeFilter, true);
|
|
29484
|
+
}
|
|
29208
29485
|
const filtered = allVideos.filter((video) => {
|
|
29209
29486
|
if (activeFilter === "all") return true;
|
|
29210
29487
|
return video.type === activeFilter;
|
|
@@ -29238,14 +29515,11 @@ var BottlenecksContent = ({
|
|
|
29238
29515
|
}
|
|
29239
29516
|
}, []);
|
|
29240
29517
|
const getCategoryCount = useCallback((categoryId) => {
|
|
29241
|
-
if (
|
|
29242
|
-
|
|
29243
|
-
return allVideos.length;
|
|
29244
|
-
}
|
|
29245
|
-
return 0;
|
|
29518
|
+
if (activeFilter === categoryId && categoryMetadata.length > 0) {
|
|
29519
|
+
return categoryMetadata.length;
|
|
29246
29520
|
}
|
|
29247
29521
|
return mergedCounts[categoryId] || 0;
|
|
29248
|
-
}, [
|
|
29522
|
+
}, [activeFilter, categoryMetadata, mergedCounts]);
|
|
29249
29523
|
const filteredVideos = useMemo(() => {
|
|
29250
29524
|
if (!allVideos) return [];
|
|
29251
29525
|
let filtered = [];
|
|
@@ -29268,29 +29542,61 @@ var BottlenecksContent = ({
|
|
|
29268
29542
|
setError(null);
|
|
29269
29543
|
}
|
|
29270
29544
|
}, [isNavigating, currentIndex, filteredVideos.length]);
|
|
29271
|
-
const
|
|
29272
|
-
|
|
29273
|
-
|
|
29274
|
-
|
|
29275
|
-
|
|
29276
|
-
|
|
29277
|
-
|
|
29545
|
+
const clearLoadingState = useCallback(() => {
|
|
29546
|
+
setIsTransitioning(false);
|
|
29547
|
+
setIsNavigating(false);
|
|
29548
|
+
if (loadingTimeoutRef.current) {
|
|
29549
|
+
clearTimeout(loadingTimeoutRef.current);
|
|
29550
|
+
loadingTimeoutRef.current = null;
|
|
29551
|
+
}
|
|
29552
|
+
}, []);
|
|
29553
|
+
const loadCategoryMetadata = useCallback(async (categoryId, autoLoadFirstVideo = false) => {
|
|
29554
|
+
if (!workspaceId) {
|
|
29555
|
+
return;
|
|
29556
|
+
}
|
|
29557
|
+
const cacheKey = `${categoryId}-${date || getOperationalDate(timezone)}-${effectiveShift}`;
|
|
29558
|
+
if (metadataCache[cacheKey]) {
|
|
29559
|
+
console.log(`[BottlenecksContent] Using cached metadata for ${categoryId}`);
|
|
29560
|
+
setCategoryMetadata(metadataCache[cacheKey]);
|
|
29561
|
+
categoryMetadataRef.current = metadataCache[cacheKey];
|
|
29562
|
+
if (autoLoadFirstVideo && metadataCache[cacheKey].length > 0 && s3ClipsService) {
|
|
29563
|
+
const firstClipMeta = metadataCache[cacheKey][0];
|
|
29564
|
+
try {
|
|
29565
|
+
const video = await s3ClipsService.getClipById(firstClipMeta.clipId);
|
|
29566
|
+
if (video && isMountedRef.current) {
|
|
29567
|
+
setCurrentClipId(firstClipMeta.clipId);
|
|
29568
|
+
setAllVideos([video]);
|
|
29569
|
+
setCurrentIndex(0);
|
|
29570
|
+
setCurrentMetadataIndex(0);
|
|
29571
|
+
currentMetadataIndexRef.current = 0;
|
|
29572
|
+
setIsCategoryLoading(false);
|
|
29573
|
+
console.log(`[BottlenecksContent] Auto-loaded first video from cache: ${video.id} (1/${metadataCache[cacheKey].length})`);
|
|
29574
|
+
}
|
|
29575
|
+
} catch (error2) {
|
|
29576
|
+
console.error(`[BottlenecksContent] Error loading first video from cache:`, error2);
|
|
29577
|
+
setIsCategoryLoading(false);
|
|
29578
|
+
clearLoadingState();
|
|
29579
|
+
}
|
|
29580
|
+
}
|
|
29581
|
+
return;
|
|
29278
29582
|
}
|
|
29279
29583
|
try {
|
|
29584
|
+
console.log(`[BottlenecksContent] Loading metadata for category: ${categoryId}`);
|
|
29585
|
+
const { createClient: createClient5 } = await import('@supabase/supabase-js');
|
|
29586
|
+
const supabase = createClient5(
|
|
29587
|
+
process.env.NEXT_PUBLIC_SUPABASE_URL || "",
|
|
29588
|
+
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || ""
|
|
29589
|
+
);
|
|
29590
|
+
const { data: { session } } = await supabase.auth.getSession();
|
|
29591
|
+
const authToken = session?.access_token;
|
|
29592
|
+
if (!authToken) {
|
|
29593
|
+
console.error("Authentication required for metadata loading");
|
|
29594
|
+
return;
|
|
29595
|
+
}
|
|
29596
|
+
let response;
|
|
29280
29597
|
if (isPercentileCategory(categoryId)) {
|
|
29281
|
-
console.log(`[BottlenecksContent] Loading percentile category: ${categoryId}`);
|
|
29282
29598
|
const percentileType = categoryId === "fast-cycles" ? "fast-cycles" : categoryId === "slow-cycles" ? "slow-cycles" : "idle-times";
|
|
29283
|
-
|
|
29284
|
-
const supabase = createClient4(
|
|
29285
|
-
process.env.NEXT_PUBLIC_SUPABASE_URL || "",
|
|
29286
|
-
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || ""
|
|
29287
|
-
);
|
|
29288
|
-
const { data: { session } } = await supabase.auth.getSession();
|
|
29289
|
-
const authToken = session?.access_token;
|
|
29290
|
-
if (!authToken) {
|
|
29291
|
-
throw new Error("Authentication required");
|
|
29292
|
-
}
|
|
29293
|
-
const response = await fetch("/api/clips/supabase", {
|
|
29599
|
+
response = await fetch("/api/clips/supabase", {
|
|
29294
29600
|
method: "POST",
|
|
29295
29601
|
headers: {
|
|
29296
29602
|
"Content-Type": "application/json",
|
|
@@ -29300,53 +29606,125 @@ var BottlenecksContent = ({
|
|
|
29300
29606
|
action: "percentile-clips",
|
|
29301
29607
|
percentileAction: percentileType,
|
|
29302
29608
|
workspaceId,
|
|
29303
|
-
startDate: `${date || getOperationalDate()}T00:00:00Z`,
|
|
29304
|
-
endDate: `${date || getOperationalDate()}T23:59:59Z`,
|
|
29609
|
+
startDate: `${date || getOperationalDate(timezone)}T00:00:00Z`,
|
|
29610
|
+
endDate: `${date || getOperationalDate(timezone)}T23:59:59Z`,
|
|
29305
29611
|
percentile: 10,
|
|
29306
29612
|
shiftId: effectiveShift,
|
|
29307
29613
|
limit: 100
|
|
29308
29614
|
})
|
|
29309
29615
|
});
|
|
29310
|
-
|
|
29311
|
-
|
|
29312
|
-
|
|
29616
|
+
} else {
|
|
29617
|
+
response = await fetch("/api/clips/supabase", {
|
|
29618
|
+
method: "POST",
|
|
29619
|
+
headers: {
|
|
29620
|
+
"Content-Type": "application/json",
|
|
29621
|
+
"Authorization": `Bearer ${authToken}`
|
|
29622
|
+
},
|
|
29623
|
+
body: JSON.stringify({
|
|
29624
|
+
action: "clip-metadata",
|
|
29625
|
+
workspaceId,
|
|
29626
|
+
date: date || getOperationalDate(timezone),
|
|
29627
|
+
shift: effectiveShift,
|
|
29628
|
+
category: categoryId,
|
|
29629
|
+
page: 1,
|
|
29630
|
+
limit: 1e3
|
|
29631
|
+
})
|
|
29632
|
+
});
|
|
29633
|
+
}
|
|
29634
|
+
if (!response.ok) {
|
|
29635
|
+
throw new Error(`Metadata API error: ${response.status}`);
|
|
29636
|
+
}
|
|
29637
|
+
const categoryData = await response.json();
|
|
29638
|
+
if (categoryData.clips && isMountedRef.current) {
|
|
29639
|
+
let metadataClips;
|
|
29640
|
+
if (isPercentileCategory(categoryId)) {
|
|
29641
|
+
metadataClips = categoryData.clips.map((clip, index) => ({
|
|
29642
|
+
id: clip.id,
|
|
29643
|
+
clipId: clip.id,
|
|
29644
|
+
clip_timestamp: clip.timestamp || clip.creation_timestamp,
|
|
29645
|
+
description: clip.description,
|
|
29646
|
+
severity: clip.severity,
|
|
29647
|
+
category: categoryId,
|
|
29648
|
+
duration: clip.cycle_time_seconds,
|
|
29649
|
+
index
|
|
29650
|
+
}));
|
|
29651
|
+
} else {
|
|
29652
|
+
metadataClips = categoryData.clips;
|
|
29313
29653
|
}
|
|
29314
|
-
|
|
29315
|
-
|
|
29316
|
-
|
|
29317
|
-
|
|
29318
|
-
|
|
29319
|
-
|
|
29320
|
-
|
|
29321
|
-
|
|
29322
|
-
|
|
29654
|
+
setMetadataCache((prev) => ({
|
|
29655
|
+
...prev,
|
|
29656
|
+
[cacheKey]: metadataClips
|
|
29657
|
+
}));
|
|
29658
|
+
setCategoryMetadata(metadataClips);
|
|
29659
|
+
categoryMetadataRef.current = metadataClips;
|
|
29660
|
+
console.log(`[BottlenecksContent] Loaded metadata for ${categoryId}: ${metadataClips.length} clips`);
|
|
29661
|
+
if (autoLoadFirstVideo && metadataClips.length > 0 && s3ClipsService) {
|
|
29662
|
+
const firstClipMeta = metadataClips[0];
|
|
29663
|
+
try {
|
|
29664
|
+
const video = await s3ClipsService.getClipById(firstClipMeta.clipId);
|
|
29665
|
+
if (video && isMountedRef.current) {
|
|
29666
|
+
setCurrentClipId(firstClipMeta.clipId);
|
|
29667
|
+
setAllVideos([video]);
|
|
29668
|
+
setCurrentIndex(0);
|
|
29669
|
+
setCurrentMetadataIndex(0);
|
|
29670
|
+
currentMetadataIndexRef.current = 0;
|
|
29671
|
+
setIsCategoryLoading(false);
|
|
29672
|
+
console.log(`[BottlenecksContent] Auto-loaded first video: ${video.id} (1/${metadataClips.length})`);
|
|
29673
|
+
}
|
|
29674
|
+
} catch (error2) {
|
|
29675
|
+
console.error(`[BottlenecksContent] Error loading first video:`, error2);
|
|
29676
|
+
setIsCategoryLoading(false);
|
|
29323
29677
|
}
|
|
29324
29678
|
}
|
|
29325
|
-
}
|
|
29326
|
-
|
|
29327
|
-
|
|
29328
|
-
|
|
29329
|
-
|
|
29330
|
-
|
|
29331
|
-
|
|
29332
|
-
|
|
29333
|
-
|
|
29679
|
+
}
|
|
29680
|
+
} catch (error2) {
|
|
29681
|
+
console.error(`[BottlenecksContent] Error loading category metadata:`, error2);
|
|
29682
|
+
}
|
|
29683
|
+
}, [workspaceId, date, effectiveShift, isPercentileCategory, metadataCache, s3ClipsService]);
|
|
29684
|
+
const loadAndPlayClipById = useCallback(async (clipId, categoryId, position) => {
|
|
29685
|
+
if (!workspaceId || !s3ClipsService || !isMountedRef.current) return;
|
|
29686
|
+
console.log(`[BottlenecksContent] Loading clip by ID: ${clipId}, category=${categoryId}, position=${position}`);
|
|
29687
|
+
setIsTransitioning(true);
|
|
29688
|
+
setIsInitialLoading(true);
|
|
29689
|
+
setError(null);
|
|
29690
|
+
loadingTimeoutRef.current = setTimeout(() => {
|
|
29691
|
+
console.warn("[BottlenecksContent] Loading timeout - clearing stuck loading state");
|
|
29692
|
+
clearLoadingState();
|
|
29693
|
+
}, 1e3);
|
|
29694
|
+
if (activeFilterRef.current !== categoryId) {
|
|
29695
|
+
updateActiveFilter(categoryId);
|
|
29696
|
+
}
|
|
29697
|
+
try {
|
|
29698
|
+
await loadCategoryMetadata(categoryId, false);
|
|
29699
|
+
const metadataArray = categoryMetadataRef.current;
|
|
29700
|
+
if (metadataArray.length > 0) {
|
|
29701
|
+
const clickedClipIndex = metadataArray.findIndex((clip) => clip.clipId === clipId);
|
|
29702
|
+
if (clickedClipIndex !== -1) {
|
|
29703
|
+
setCurrentMetadataIndex(clickedClipIndex);
|
|
29704
|
+
currentMetadataIndexRef.current = clickedClipIndex;
|
|
29705
|
+
const video = await s3ClipsService.getClipById(clipId);
|
|
29706
|
+
if (video) {
|
|
29707
|
+
setPendingVideo(video);
|
|
29708
|
+
setCurrentClipId(clipId);
|
|
29709
|
+
setAllVideos([video]);
|
|
29710
|
+
setCurrentIndex(0);
|
|
29711
|
+
console.log(`[BottlenecksContent] Loaded clip ${clipId} (${clickedClipIndex + 1}/${metadataArray.length})`);
|
|
29712
|
+
}
|
|
29334
29713
|
}
|
|
29335
29714
|
}
|
|
29336
|
-
setIsNavigating(false);
|
|
29337
29715
|
} catch (error2) {
|
|
29338
29716
|
console.error(`[BottlenecksContent] Error loading clip by ID (${clipId}):`, error2);
|
|
29339
29717
|
if (isMountedRef.current) {
|
|
29340
29718
|
setError("Failed to load selected clip. Please try again.");
|
|
29341
|
-
|
|
29719
|
+
clearLoadingState();
|
|
29342
29720
|
}
|
|
29343
29721
|
}
|
|
29344
|
-
}, [workspaceId, s3ClipsService, date, effectiveShift, updateActiveFilter]);
|
|
29722
|
+
}, [workspaceId, s3ClipsService, date, effectiveShift, updateActiveFilter, clearLoadingState]);
|
|
29345
29723
|
useCallback(async (categoryId, clipIndex) => {
|
|
29346
29724
|
console.warn("[BottlenecksContent] loadAndPlayClip is deprecated, use loadAndPlayClipById instead");
|
|
29347
29725
|
if (!workspaceId || !s3ClipsService || !isMountedRef.current) return;
|
|
29348
29726
|
try {
|
|
29349
|
-
const operationalDate = date || getOperationalDate();
|
|
29727
|
+
const operationalDate = date || getOperationalDate(timezone);
|
|
29350
29728
|
const shiftStr = effectiveShift;
|
|
29351
29729
|
const video = await s3ClipsService.getClipByIndex(
|
|
29352
29730
|
workspaceId,
|
|
@@ -29367,105 +29745,79 @@ var BottlenecksContent = ({
|
|
|
29367
29745
|
const handleNext = useCallback(async () => {
|
|
29368
29746
|
if (!isMountedRef.current) return;
|
|
29369
29747
|
const currentFilter = activeFilterRef.current;
|
|
29370
|
-
|
|
29371
|
-
|
|
29748
|
+
setIsTransitioning(true);
|
|
29749
|
+
setIsInitialLoading(true);
|
|
29372
29750
|
setError(null);
|
|
29373
29751
|
try {
|
|
29374
|
-
|
|
29375
|
-
|
|
29376
|
-
|
|
29377
|
-
|
|
29378
|
-
|
|
29379
|
-
|
|
29380
|
-
|
|
29381
|
-
|
|
29382
|
-
|
|
29383
|
-
}
|
|
29384
|
-
|
|
29385
|
-
|
|
29386
|
-
|
|
29387
|
-
|
|
29388
|
-
|
|
29389
|
-
setIsNavigating(false);
|
|
29390
|
-
return;
|
|
29391
|
-
}
|
|
29392
|
-
const neighbors = await s3ClipsService.getNeighboringClips(
|
|
29393
|
-
workspaceId,
|
|
29394
|
-
date || getOperationalDate(),
|
|
29395
|
-
effectiveShift,
|
|
29396
|
-
currentFilter,
|
|
29397
|
-
currentClipId
|
|
29398
|
-
);
|
|
29399
|
-
if (neighbors.next) {
|
|
29400
|
-
console.log(`[handleNext] Found next clip: ${neighbors.next.id}`);
|
|
29401
|
-
setCurrentClipId(neighbors.next.id || null);
|
|
29402
|
-
setAllVideos([neighbors.next]);
|
|
29752
|
+
const currentMetaIndex = currentMetadataIndexRef.current;
|
|
29753
|
+
const metadataArray = categoryMetadataRef.current;
|
|
29754
|
+
console.log(`[handleNext] Unified navigation: ${currentFilter}, metadata index: ${currentMetaIndex}/${metadataArray.length}`);
|
|
29755
|
+
if (currentMetaIndex < metadataArray.length - 1) {
|
|
29756
|
+
const nextMetadataIndex = currentMetaIndex + 1;
|
|
29757
|
+
const nextClipMeta = metadataArray[nextMetadataIndex];
|
|
29758
|
+
console.log(`[handleNext] Loading next clip: ${nextClipMeta.clipId} at metadata index ${nextMetadataIndex}`);
|
|
29759
|
+
if (!s3ClipsService) {
|
|
29760
|
+
throw new Error("S3 clips service not available");
|
|
29761
|
+
}
|
|
29762
|
+
const nextVideo = await s3ClipsService.getClipById(nextClipMeta.clipId);
|
|
29763
|
+
if (nextVideo) {
|
|
29764
|
+
setPendingVideo(nextVideo);
|
|
29765
|
+
setCurrentClipId(nextClipMeta.clipId);
|
|
29766
|
+
setAllVideos([nextVideo]);
|
|
29403
29767
|
setCurrentIndex(0);
|
|
29404
|
-
|
|
29405
|
-
|
|
29406
|
-
|
|
29768
|
+
setCurrentMetadataIndex(nextMetadataIndex);
|
|
29769
|
+
currentMetadataIndexRef.current = nextMetadataIndex;
|
|
29770
|
+
console.log(`[handleNext] Successfully loaded next clip: ${nextVideo.id} (${nextMetadataIndex + 1}/${metadataArray.length})`);
|
|
29407
29771
|
} else {
|
|
29408
|
-
console.
|
|
29409
|
-
|
|
29772
|
+
console.error(`[handleNext] Failed to load next video for clip ID: ${nextClipMeta.clipId}`);
|
|
29773
|
+
clearLoadingState();
|
|
29410
29774
|
}
|
|
29775
|
+
} else {
|
|
29776
|
+
console.log(`[handleNext] Already at last clip in category`);
|
|
29777
|
+
clearLoadingState();
|
|
29411
29778
|
}
|
|
29412
29779
|
} catch (error2) {
|
|
29413
29780
|
console.error(`[handleNext] Error navigating:`, error2);
|
|
29414
29781
|
setError("Failed to navigate to next clip");
|
|
29415
|
-
|
|
29782
|
+
clearLoadingState();
|
|
29416
29783
|
}
|
|
29417
|
-
}, [
|
|
29784
|
+
}, [clearLoadingState, s3ClipsService]);
|
|
29418
29785
|
const handlePrevious = useCallback(async () => {
|
|
29419
29786
|
if (!isMountedRef.current) return;
|
|
29420
29787
|
const currentFilter = activeFilterRef.current;
|
|
29421
|
-
|
|
29422
|
-
|
|
29788
|
+
setIsTransitioning(true);
|
|
29789
|
+
setIsInitialLoading(true);
|
|
29423
29790
|
setError(null);
|
|
29424
29791
|
try {
|
|
29425
|
-
|
|
29426
|
-
|
|
29427
|
-
|
|
29428
|
-
|
|
29429
|
-
|
|
29430
|
-
|
|
29431
|
-
|
|
29432
|
-
|
|
29433
|
-
|
|
29434
|
-
|
|
29435
|
-
|
|
29436
|
-
|
|
29437
|
-
|
|
29438
|
-
|
|
29439
|
-
if (!currentClipId || !s3ClipsService) {
|
|
29440
|
-
setIsNavigating(false);
|
|
29441
|
-
return;
|
|
29442
|
-
}
|
|
29443
|
-
const neighbors = await s3ClipsService.getNeighboringClips(
|
|
29444
|
-
workspaceId,
|
|
29445
|
-
date || getOperationalDate(),
|
|
29446
|
-
effectiveShift,
|
|
29447
|
-
currentFilter,
|
|
29448
|
-
currentClipId
|
|
29449
|
-
);
|
|
29450
|
-
if (neighbors.previous) {
|
|
29451
|
-
console.log(`[handlePrevious] Found previous clip: ${neighbors.previous.id}`);
|
|
29452
|
-
setCurrentClipId(neighbors.previous.id || null);
|
|
29453
|
-
setAllVideos([neighbors.previous]);
|
|
29792
|
+
const currentMetaIndex = currentMetadataIndexRef.current;
|
|
29793
|
+
const metadataArray = categoryMetadataRef.current;
|
|
29794
|
+
console.log(`[handlePrevious] Unified navigation: ${currentFilter}, metadata index: ${currentMetaIndex}/${metadataArray.length}`);
|
|
29795
|
+
if (currentMetaIndex > 0) {
|
|
29796
|
+
const prevMetadataIndex = currentMetaIndex - 1;
|
|
29797
|
+
const prevClipMeta = metadataArray[prevMetadataIndex];
|
|
29798
|
+
if (!s3ClipsService) {
|
|
29799
|
+
throw new Error("S3 clips service not available");
|
|
29800
|
+
}
|
|
29801
|
+
const prevVideo = await s3ClipsService.getClipById(prevClipMeta.clipId);
|
|
29802
|
+
if (prevVideo) {
|
|
29803
|
+
setPendingVideo(prevVideo);
|
|
29804
|
+
setCurrentClipId(prevClipMeta.clipId);
|
|
29805
|
+
setAllVideos([prevVideo]);
|
|
29454
29806
|
setCurrentIndex(0);
|
|
29455
|
-
|
|
29456
|
-
|
|
29457
|
-
|
|
29458
|
-
} else {
|
|
29459
|
-
console.log(`[handlePrevious] No previous clip available`);
|
|
29460
|
-
setIsNavigating(false);
|
|
29807
|
+
setCurrentMetadataIndex(prevMetadataIndex);
|
|
29808
|
+
currentMetadataIndexRef.current = prevMetadataIndex;
|
|
29809
|
+
console.log(`[handlePrevious] Loaded previous clip: ${prevVideo.id} (${prevMetadataIndex + 1}/${metadataArray.length})`);
|
|
29461
29810
|
}
|
|
29811
|
+
} else {
|
|
29812
|
+
console.log(`[handlePrevious] Already at first clip in category`);
|
|
29813
|
+
clearLoadingState();
|
|
29462
29814
|
}
|
|
29463
29815
|
} catch (error2) {
|
|
29464
29816
|
console.error(`[handlePrevious] Error navigating:`, error2);
|
|
29465
29817
|
setError("Failed to navigate to previous clip");
|
|
29466
|
-
|
|
29818
|
+
clearLoadingState();
|
|
29467
29819
|
}
|
|
29468
|
-
}, [
|
|
29820
|
+
}, [clearLoadingState, s3ClipsService]);
|
|
29469
29821
|
const currentVideo = useMemo(() => {
|
|
29470
29822
|
if (!filteredVideos || filteredVideos.length === 0 || currentIndex >= filteredVideos.length) {
|
|
29471
29823
|
return null;
|
|
@@ -29473,7 +29825,7 @@ var BottlenecksContent = ({
|
|
|
29473
29825
|
return filteredVideos[currentIndex];
|
|
29474
29826
|
}, [filteredVideos, currentIndex]);
|
|
29475
29827
|
const handleVideoReady = useCallback((player) => {
|
|
29476
|
-
console.log("Video.js player ready");
|
|
29828
|
+
console.log("Video.js player ready - NOT clearing loading (wait for playing event)");
|
|
29477
29829
|
videoRetryCountRef.current = 0;
|
|
29478
29830
|
if (error?.includes("Retrying")) {
|
|
29479
29831
|
setError(null);
|
|
@@ -29481,6 +29833,7 @@ var BottlenecksContent = ({
|
|
|
29481
29833
|
}, [error]);
|
|
29482
29834
|
const handleVideoPlay = useCallback(async (player) => {
|
|
29483
29835
|
setIsPlaying(true);
|
|
29836
|
+
setIsInitialLoading(false);
|
|
29484
29837
|
if (currentVideo && !currentVideo.creation_timestamp && s3ClipsService) {
|
|
29485
29838
|
try {
|
|
29486
29839
|
const originalUri = currentVideo.originalUri || currentVideo.src;
|
|
@@ -29510,6 +29863,17 @@ var BottlenecksContent = ({
|
|
|
29510
29863
|
const handleDurationChange = useCallback((player, duration2) => {
|
|
29511
29864
|
setDuration(duration2);
|
|
29512
29865
|
}, []);
|
|
29866
|
+
const handleLoadedData = useCallback((player) => {
|
|
29867
|
+
console.log("Video data loaded - NOT clearing loading (wait for playing event)");
|
|
29868
|
+
}, []);
|
|
29869
|
+
const handleVideoPlaying = useCallback((player) => {
|
|
29870
|
+
console.log("Video playing - hiding transition overlay (most reliable)");
|
|
29871
|
+
clearLoadingState();
|
|
29872
|
+
}, [clearLoadingState]);
|
|
29873
|
+
const handleVideoLoadingChange = useCallback((isLoading2) => {
|
|
29874
|
+
console.log(`[BottlenecksContent] Video loading state changed: ${isLoading2}`);
|
|
29875
|
+
setIsVideoBuffering(isLoading2);
|
|
29876
|
+
}, []);
|
|
29513
29877
|
const handleVideoEnded = useCallback((player) => {
|
|
29514
29878
|
handleNext();
|
|
29515
29879
|
}, [handleNext]);
|
|
@@ -29546,6 +29910,10 @@ var BottlenecksContent = ({
|
|
|
29546
29910
|
isMountedRef.current = false;
|
|
29547
29911
|
loadingCategoryRef.current = null;
|
|
29548
29912
|
fetchInProgressRef.current.clear();
|
|
29913
|
+
if (loadingTimeoutRef.current) {
|
|
29914
|
+
clearTimeout(loadingTimeoutRef.current);
|
|
29915
|
+
loadingTimeoutRef.current = null;
|
|
29916
|
+
}
|
|
29549
29917
|
setIsCategoryLoading(false);
|
|
29550
29918
|
setIsNavigating(false);
|
|
29551
29919
|
};
|
|
@@ -29555,6 +29923,14 @@ var BottlenecksContent = ({
|
|
|
29555
29923
|
setError(null);
|
|
29556
29924
|
}
|
|
29557
29925
|
}, [currentIndex, filteredVideos]);
|
|
29926
|
+
useEffect(() => {
|
|
29927
|
+
if (!isTransitioning && pendingVideo) {
|
|
29928
|
+
const timer = setTimeout(() => {
|
|
29929
|
+
setPendingVideo(null);
|
|
29930
|
+
}, 200);
|
|
29931
|
+
return () => clearTimeout(timer);
|
|
29932
|
+
}
|
|
29933
|
+
}, [isTransitioning, pendingVideo]);
|
|
29558
29934
|
useEffect(() => {
|
|
29559
29935
|
const handleKeyDown = (e) => {
|
|
29560
29936
|
if (e.key === "ArrowLeft") {
|
|
@@ -29655,173 +30031,169 @@ var BottlenecksContent = ({
|
|
|
29655
30031
|
}
|
|
29656
30032
|
const activeCategory = categoriesToShow.find((cat) => cat.type === activeFilter);
|
|
29657
30033
|
if (activeCategory) {
|
|
29658
|
-
return `${activeCategory.label} (${
|
|
30034
|
+
return `${activeCategory.label} (${getCategoryCount(activeCategory.type)})`;
|
|
29659
30035
|
}
|
|
29660
|
-
return `${activeFilter.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase())} (${
|
|
30036
|
+
return `${activeFilter.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase())} (${getCategoryCount(activeFilter)})`;
|
|
29661
30037
|
})() }),
|
|
29662
30038
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-2", children: [
|
|
29663
30039
|
/* @__PURE__ */ jsx(
|
|
29664
30040
|
"button",
|
|
29665
30041
|
{
|
|
29666
30042
|
onClick: handlePrevious,
|
|
29667
|
-
disabled:
|
|
29668
|
-
className: `p-2 rounded-full transition-colors ${
|
|
30043
|
+
disabled: currentMetadataIndex <= 0 || categoryMetadata.length === 0,
|
|
30044
|
+
className: `p-2 rounded-full transition-colors ${currentMetadataIndex <= 0 || categoryMetadata.length === 0 ? "text-gray-300 cursor-not-allowed" : "text-gray-600 hover:bg-gray-100"}`,
|
|
29669
30045
|
"aria-label": "Previous video",
|
|
29670
30046
|
children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-5 w-5" })
|
|
29671
30047
|
}
|
|
29672
30048
|
),
|
|
29673
30049
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-1", children: [
|
|
29674
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm px-2 py-1 bg-blue-50 text-blue-700 rounded-full font-medium tabular-nums", children:
|
|
30050
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm px-2 py-1 bg-blue-50 text-blue-700 rounded-full font-medium tabular-nums", children: categoryMetadata.length > 0 ? `${currentMetadataIndex + 1} / ${categoryMetadata.length}` : "0 / 0" }),
|
|
29675
30051
|
error && /* @__PURE__ */ jsx("span", { className: "text-xs text-red-600 font-medium", children: error })
|
|
29676
30052
|
] }),
|
|
29677
30053
|
/* @__PURE__ */ jsx(
|
|
29678
30054
|
"button",
|
|
29679
30055
|
{
|
|
29680
30056
|
onClick: handleNext,
|
|
29681
|
-
disabled:
|
|
29682
|
-
className: `p-2 rounded-full transition-colors ${
|
|
30057
|
+
disabled: currentMetadataIndex >= categoryMetadata.length - 1 || categoryMetadata.length === 0,
|
|
30058
|
+
className: `p-2 rounded-full transition-colors ${currentMetadataIndex >= categoryMetadata.length - 1 || categoryMetadata.length === 0 ? "text-gray-300 cursor-not-allowed" : "text-gray-600 hover:bg-gray-100"}`,
|
|
29683
30059
|
"aria-label": "Next video",
|
|
29684
30060
|
children: /* @__PURE__ */ jsx(ChevronRight, { className: "h-5 w-5" })
|
|
29685
30061
|
}
|
|
29686
30062
|
)
|
|
29687
30063
|
] })
|
|
29688
30064
|
] }) }),
|
|
29689
|
-
/*
|
|
29690
|
-
|
|
29691
|
-
/*
|
|
29692
|
-
|
|
29693
|
-
|
|
29694
|
-
|
|
29695
|
-
|
|
29696
|
-
|
|
29697
|
-
|
|
29698
|
-
|
|
29699
|
-
|
|
29700
|
-
|
|
29701
|
-
|
|
29702
|
-
|
|
29703
|
-
|
|
29704
|
-
|
|
29705
|
-
|
|
29706
|
-
|
|
29707
|
-
|
|
29708
|
-
|
|
29709
|
-
|
|
29710
|
-
|
|
29711
|
-
|
|
29712
|
-
|
|
29713
|
-
|
|
29714
|
-
|
|
29715
|
-
|
|
29716
|
-
|
|
29717
|
-
|
|
29718
|
-
|
|
29719
|
-
|
|
29720
|
-
|
|
29721
|
-
|
|
29722
|
-
|
|
29723
|
-
|
|
29724
|
-
|
|
29725
|
-
|
|
29726
|
-
|
|
29727
|
-
|
|
30065
|
+
/* Show video if we have filtered videos and current video, or show loading */
|
|
30066
|
+
filteredVideos.length > 0 && currentVideo ? /* @__PURE__ */ jsx("div", { className: "p-4 h-[calc(100%-4rem)]", children: /* @__PURE__ */ jsx("div", { className: "relative h-full group", children: /* @__PURE__ */ jsxs("div", { className: "relative w-full h-full overflow-hidden rounded-md shadow-inner bg-gray-900", children: [
|
|
30067
|
+
/* @__PURE__ */ jsx(
|
|
30068
|
+
CroppedVideoPlayer,
|
|
30069
|
+
{
|
|
30070
|
+
ref: videoRef,
|
|
30071
|
+
src: currentVideo.src,
|
|
30072
|
+
className: "w-full h-full",
|
|
30073
|
+
crop: workspaceCrop?.crop || null,
|
|
30074
|
+
autoplay: true,
|
|
30075
|
+
playsInline: true,
|
|
30076
|
+
loop: false,
|
|
30077
|
+
externalLoadingControl: true,
|
|
30078
|
+
onReady: handleVideoReady,
|
|
30079
|
+
onPlay: handleVideoPlay,
|
|
30080
|
+
onPause: handleVideoPause,
|
|
30081
|
+
onTimeUpdate: handleTimeUpdate,
|
|
30082
|
+
onDurationChange: handleDurationChange,
|
|
30083
|
+
onEnded: handleVideoEnded,
|
|
30084
|
+
onError: handleVideoError,
|
|
30085
|
+
onLoadedData: handleLoadedData,
|
|
30086
|
+
onPlaying: handleVideoPlaying,
|
|
30087
|
+
onLoadingChange: handleVideoLoadingChange,
|
|
30088
|
+
options: {
|
|
30089
|
+
// Ensure full height is always visible - no cropping
|
|
30090
|
+
fluid: false,
|
|
30091
|
+
responsive: false,
|
|
30092
|
+
fill: false
|
|
30093
|
+
}
|
|
30094
|
+
}
|
|
30095
|
+
),
|
|
30096
|
+
(isTransitioning || isVideoBuffering && isInitialLoading) && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-30 flex items-center justify-center bg-black", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }),
|
|
30097
|
+
!isTransitioning && isVideoBuffering && !isInitialLoading && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-30 flex items-center justify-center bg-black/60", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }),
|
|
30098
|
+
/* @__PURE__ */ jsx(
|
|
30099
|
+
"div",
|
|
30100
|
+
{
|
|
30101
|
+
className: "absolute inset-0 z-10 cursor-pointer",
|
|
30102
|
+
onClick: togglePlayback
|
|
30103
|
+
}
|
|
30104
|
+
),
|
|
30105
|
+
error && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-black/80 text-white p-4", children: /* @__PURE__ */ jsxs("div", { className: "text-center max-w-md", children: [
|
|
30106
|
+
/* @__PURE__ */ jsx("svg", { className: "w-16 h-16 mx-auto mb-4 text-red-400", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.732-.833-2.5 0L4.268 16.5c-.77.833.192 2.5 1.732 2.5z" }) }),
|
|
30107
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold mb-2", children: "Video Stream Error" }),
|
|
30108
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-gray-300 mb-4", children: "The video stream appears to be corrupted or unavailable. This may be due to:" }),
|
|
30109
|
+
/* @__PURE__ */ jsxs("ul", { className: "text-sm text-gray-300 text-left space-y-1 mb-4", children: [
|
|
30110
|
+
/* @__PURE__ */ jsx("li", { children: "\u2022 Incomplete video encoding" }),
|
|
30111
|
+
/* @__PURE__ */ jsx("li", { children: "\u2022 Network connectivity issues" }),
|
|
30112
|
+
/* @__PURE__ */ jsx("li", { children: "\u2022 Server processing errors" })
|
|
30113
|
+
] }),
|
|
30114
|
+
/* @__PURE__ */ jsx(
|
|
30115
|
+
"button",
|
|
30116
|
+
{
|
|
30117
|
+
onClick: () => {
|
|
30118
|
+
setError(null);
|
|
30119
|
+
if (videoRef.current) {
|
|
30120
|
+
videoRef.current.dispose();
|
|
29728
30121
|
}
|
|
29729
|
-
|
|
29730
|
-
|
|
29731
|
-
|
|
29732
|
-
|
|
29733
|
-
|
|
29734
|
-
|
|
29735
|
-
|
|
29736
|
-
|
|
29737
|
-
|
|
29738
|
-
|
|
29739
|
-
|
|
29740
|
-
|
|
29741
|
-
|
|
29742
|
-
|
|
29743
|
-
|
|
29744
|
-
|
|
29745
|
-
|
|
29746
|
-
|
|
29747
|
-
|
|
29748
|
-
|
|
29749
|
-
|
|
29750
|
-
|
|
29751
|
-
|
|
29752
|
-
|
|
29753
|
-
|
|
29754
|
-
|
|
29755
|
-
|
|
29756
|
-
|
|
29757
|
-
|
|
29758
|
-
|
|
29759
|
-
|
|
29760
|
-
|
|
29761
|
-
|
|
29762
|
-
|
|
29763
|
-
|
|
29764
|
-
|
|
29765
|
-
|
|
29766
|
-
|
|
29767
|
-
|
|
29768
|
-
|
|
29769
|
-
|
|
29770
|
-
|
|
29771
|
-
|
|
29772
|
-
|
|
29773
|
-
|
|
29774
|
-
|
|
29775
|
-
|
|
29776
|
-
|
|
29777
|
-
|
|
29778
|
-
|
|
29779
|
-
|
|
29780
|
-
|
|
29781
|
-
|
|
29782
|
-
|
|
29783
|
-
|
|
29784
|
-
|
|
29785
|
-
|
|
29786
|
-
|
|
29787
|
-
|
|
29788
|
-
|
|
29789
|
-
|
|
29790
|
-
|
|
29791
|
-
|
|
29792
|
-
|
|
29793
|
-
|
|
29794
|
-
|
|
29795
|
-
|
|
29796
|
-
|
|
29797
|
-
|
|
29798
|
-
|
|
29799
|
-
|
|
29800
|
-
|
|
29801
|
-
|
|
29802
|
-
|
|
29803
|
-
|
|
29804
|
-
}
|
|
29805
|
-
)
|
|
29806
|
-
] }) })
|
|
29807
|
-
] }) }) }) : (
|
|
29808
|
-
/* Priority 5: Show "no clips found" only if we have counts and there are truly no clips for workspace */
|
|
29809
|
-
hasInitialLoad && Object.keys(mergedCounts).length > 0 && Object.values(mergedCounts).every((count) => count === 0) ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-[calc(100%-4rem)]", children: /* @__PURE__ */ jsxs("div", { className: "text-center p-8", children: [
|
|
29810
|
-
/* @__PURE__ */ jsx("svg", { className: "w-16 h-16 text-gray-300 mx-auto mb-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z" }) }),
|
|
29811
|
-
/* @__PURE__ */ jsx("h3", { className: "text-xl font-medium text-gray-700 mb-2", children: "No Clips Found" }),
|
|
29812
|
-
/* @__PURE__ */ jsx("p", { className: "text-gray-500", children: "There were no video clips found for this workspace today." })
|
|
29813
|
-
] }) }) : (
|
|
29814
|
-
/* Priority 6: Show "no matching clips" only if we have data loaded and specifically no clips for this filter */
|
|
29815
|
-
hasInitialLoad && (mergedCounts[activeFilter] || 0) === 0 ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-[calc(100%-4rem)]", children: /* @__PURE__ */ jsxs("div", { className: "text-center p-8", children: [
|
|
29816
|
-
/* @__PURE__ */ jsx("svg", { className: "w-16 h-16 text-gray-300 mx-auto mb-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z" }) }),
|
|
29817
|
-
/* @__PURE__ */ jsx("h3", { className: "text-xl font-medium text-gray-700 mb-2", children: "No Matching Clips" }),
|
|
29818
|
-
/* @__PURE__ */ jsx("p", { className: "text-gray-500", children: "There are no clips matching the selected filter." })
|
|
29819
|
-
] }) }) : (
|
|
29820
|
-
/* Priority 7: Default loading state for any other case */
|
|
29821
|
-
/* @__PURE__ */ jsx("div", { className: "p-4 h-[calc(100%-4rem)]", children: /* @__PURE__ */ jsx("div", { className: "relative h-full", children: /* @__PURE__ */ jsx("div", { className: "relative w-full h-full overflow-hidden rounded-md shadow-inner bg-gray-900 flex items-center justify-center", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading..." }) }) }) })
|
|
29822
|
-
)
|
|
29823
|
-
)
|
|
29824
|
-
)
|
|
30122
|
+
},
|
|
30123
|
+
className: "px-4 py-2 bg-blue-600 hover:bg-blue-700 rounded text-sm font-medium",
|
|
30124
|
+
children: "Retry"
|
|
30125
|
+
}
|
|
30126
|
+
)
|
|
30127
|
+
] }) }),
|
|
30128
|
+
(currentVideo.type === "cycle_completion" || currentVideo.type === "bottleneck" && currentVideo.description.toLowerCase().includes("cycle time")) && currentVideo.cycle_time_seconds || currentVideo.type === "idle_time" || currentVideo.type === "low_value" ? /* @__PURE__ */ jsx("div", { className: "absolute top-3 left-3 z-10 bg-black/60 backdrop-blur-sm px-3 py-1.5 rounded-lg text-white shadow-lg text-xs", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
30129
|
+
/* @__PURE__ */ jsx("div", { className: `flex-shrink-0 h-2.5 w-2.5 rounded-full ${currentVideo.type === "low_value" || currentVideo.type === "idle_time" ? "bg-purple-400" : isPercentileCategory(activeFilterRef.current) ? activeFilterRef.current === "fast-cycles" ? "bg-green-600" : activeFilterRef.current === "slow-cycles" ? "bg-red-700" : "bg-orange-500" : currentVideo.type === "cycle_completion" ? "bg-blue-600" : "bg-gray-500"} mr-2 animate-pulse` }),
|
|
30130
|
+
(currentVideo.type === "cycle_completion" || currentVideo.type === "bottleneck" && currentVideo.description.toLowerCase().includes("cycle time")) && currentVideo.cycle_time_seconds ? /* @__PURE__ */ jsxs("span", { className: "opacity-90 font-mono bg-black/30 px-2 py-0.5 rounded", children: [
|
|
30131
|
+
"Cycle time: ",
|
|
30132
|
+
currentVideo.cycle_time_seconds.toFixed(1),
|
|
30133
|
+
"s"
|
|
30134
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
30135
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium mr-2", children: getClipTypeLabel(currentVideo) }),
|
|
30136
|
+
/* @__PURE__ */ jsx("span", { className: "opacity-80 hidden sm:inline", children: currentVideo.description })
|
|
30137
|
+
] })
|
|
30138
|
+
] }) }) : (
|
|
30139
|
+
/* Right side display for other video types */
|
|
30140
|
+
/* @__PURE__ */ jsx("div", { className: "absolute top-3 right-3 z-10 bg-black/60 backdrop-blur-sm px-3 py-1.5 rounded-lg text-white shadow-lg text-xs", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
30141
|
+
/* @__PURE__ */ jsx("div", { className: `flex-shrink-0 h-2.5 w-2.5 rounded-full ${getSeverityColor(currentVideo.severity)} mr-2 animate-pulse` }),
|
|
30142
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium mr-2", children: getClipTypeLabel(currentVideo) }),
|
|
30143
|
+
/* @__PURE__ */ jsx("span", { className: "opacity-80 hidden sm:inline", children: currentVideo.description })
|
|
30144
|
+
] }) })
|
|
30145
|
+
),
|
|
30146
|
+
/* @__PURE__ */ jsx("div", { className: "absolute bottom-0 left-0 right-0 p-3 bg-gradient-to-t from-black/70 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300 z-10", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-white", children: [
|
|
30147
|
+
/* @__PURE__ */ jsx(
|
|
30148
|
+
"button",
|
|
30149
|
+
{
|
|
30150
|
+
onClick: togglePlayback,
|
|
30151
|
+
className: "p-1.5 hover:bg-white/20 rounded-full focus:outline-none focus:ring-2 focus:ring-white/50",
|
|
30152
|
+
"aria-label": isPlaying ? "Pause" : "Play",
|
|
30153
|
+
children: isPlaying ? /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zM7 8a1 1 0 00-1 1v2a1 1 0 102 0V9a1 1 0 00-1-1zm5 0a1 1 0 00-1 1v2a1 1 0 102 0V9a1 1 0 00-1-1z", clipRule: "evenodd" }) }) : /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zM9.555 7.168A1 1 0 008 8.118l-.001 3.764a1 1 0 001.555.832l3.196-1.882a1 1 0 000-1.664l-3.196-1.882z", clipRule: "evenodd" }) })
|
|
30154
|
+
}
|
|
30155
|
+
),
|
|
30156
|
+
/* @__PURE__ */ jsxs("span", { className: "text-xs font-mono px-2", children: [
|
|
30157
|
+
formatTime2(currentTime),
|
|
30158
|
+
" / ",
|
|
30159
|
+
formatTime2(duration)
|
|
30160
|
+
] }),
|
|
30161
|
+
/* @__PURE__ */ jsx(
|
|
30162
|
+
"input",
|
|
30163
|
+
{
|
|
30164
|
+
type: "range",
|
|
30165
|
+
min: "0",
|
|
30166
|
+
max: duration || 0,
|
|
30167
|
+
value: currentTime,
|
|
30168
|
+
onChange: (e) => {
|
|
30169
|
+
if (videoRef.current) {
|
|
30170
|
+
videoRef.current.currentTime(Number(e.target.value));
|
|
30171
|
+
}
|
|
30172
|
+
},
|
|
30173
|
+
className: "flex-grow mx-3 h-2.5 bg-white/30 rounded-full appearance-none cursor-pointer focus:outline-none focus:ring-2 focus:ring-white/50 touch-manipulation",
|
|
30174
|
+
style: {
|
|
30175
|
+
WebkitAppearance: "none",
|
|
30176
|
+
appearance: "none"
|
|
30177
|
+
},
|
|
30178
|
+
"aria-label": "Seek slider"
|
|
30179
|
+
}
|
|
30180
|
+
)
|
|
30181
|
+
] }) })
|
|
30182
|
+
] }) }) }) : (
|
|
30183
|
+
/* Priority 5: Show "no clips found" only if we have counts and there are truly no clips for workspace */
|
|
30184
|
+
hasInitialLoad && Object.keys(mergedCounts).length > 0 && Object.values(mergedCounts).every((count) => count === 0) ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-[calc(100%-4rem)]", children: /* @__PURE__ */ jsxs("div", { className: "text-center p-8", children: [
|
|
30185
|
+
/* @__PURE__ */ jsx("svg", { className: "w-16 h-16 text-gray-300 mx-auto mb-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z" }) }),
|
|
30186
|
+
/* @__PURE__ */ jsx("h3", { className: "text-xl font-medium text-gray-700 mb-2", children: "No Clips Found" }),
|
|
30187
|
+
/* @__PURE__ */ jsx("p", { className: "text-gray-500", children: "There were no video clips found for this workspace today." })
|
|
30188
|
+
] }) }) : (
|
|
30189
|
+
/* Priority 6: Show "no matching clips" only if we have data loaded and specifically no clips for this filter */
|
|
30190
|
+
hasInitialLoad && (mergedCounts[activeFilter] || 0) === 0 ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-[calc(100%-4rem)]", children: /* @__PURE__ */ jsxs("div", { className: "text-center p-8", children: [
|
|
30191
|
+
/* @__PURE__ */ jsx("svg", { className: "w-16 h-16 text-gray-300 mx-auto mb-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z" }) }),
|
|
30192
|
+
/* @__PURE__ */ jsx("h3", { className: "text-xl font-medium text-gray-700 mb-2", children: "No Matching Clips" }),
|
|
30193
|
+
/* @__PURE__ */ jsx("p", { className: "text-gray-500", children: "There are no clips matching the selected filter." })
|
|
30194
|
+
] }) }) : (
|
|
30195
|
+
/* Priority 7: Default loading state for any other case */
|
|
30196
|
+
/* @__PURE__ */ jsx("div", { className: "p-4 h-[calc(100%-4rem)]", children: /* @__PURE__ */ jsx("div", { className: "relative h-full", children: /* @__PURE__ */ jsx("div", { className: "relative w-full h-full overflow-hidden rounded-md shadow-inner bg-gray-900 flex items-center justify-center", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading..." }) }) }) })
|
|
29825
30197
|
)
|
|
29826
30198
|
)
|
|
29827
30199
|
)
|
|
@@ -29839,7 +30211,7 @@ var BottlenecksContent = ({
|
|
|
29839
30211
|
currentVideoId: currentVideo?.id,
|
|
29840
30212
|
counts: mergedCounts,
|
|
29841
30213
|
workspaceId,
|
|
29842
|
-
date: date || getOperationalDate(),
|
|
30214
|
+
date: date || getOperationalDate(timezone),
|
|
29843
30215
|
shift: effectiveShift,
|
|
29844
30216
|
onFilterChange: (filterId) => {
|
|
29845
30217
|
updateActiveFilter(filterId);
|
|
@@ -29864,9 +30236,9 @@ var BottlenecksContent = ({
|
|
|
29864
30236
|
}
|
|
29865
30237
|
}
|
|
29866
30238
|
},
|
|
29867
|
-
onClipSelect: (categoryId, clipId) => {
|
|
29868
|
-
console.log(`[BottlenecksContent] Clip selected: ${categoryId}, clipId ${clipId}`);
|
|
29869
|
-
loadAndPlayClipById(clipId, categoryId);
|
|
30239
|
+
onClipSelect: (categoryId, clipId, position) => {
|
|
30240
|
+
console.log(`[BottlenecksContent] Clip selected: ${categoryId}, clipId ${clipId}, position=${position}`);
|
|
30241
|
+
loadAndPlayClipById(clipId, categoryId, position);
|
|
29870
30242
|
const category = categoriesToShow.find((cat) => cat.type === categoryId);
|
|
29871
30243
|
if (category) {
|
|
29872
30244
|
trackCoreEvent(`${category.label} Clip Selected`, {
|
|
@@ -29993,7 +30365,7 @@ var arePropsEqual = (prevProps, nextProps) => {
|
|
|
29993
30365
|
return prevProps.data.efficiency === nextProps.data.efficiency && prevProps.data.trend_score === nextProps.data.trend_score && prevProps.data.workspace_id === nextProps.data.workspace_id && prevProps.data.workspace_name === nextProps.data.workspace_name && prevProps.isBottleneck === nextProps.isBottleneck && prevProps.isLowEfficiency === nextProps.isLowEfficiency && prevProps.isVeryLowEfficiency === nextProps.isVeryLowEfficiency && // Position doesn't need deep equality check as it's generally static
|
|
29994
30366
|
prevProps.position.id === nextProps.position.id;
|
|
29995
30367
|
};
|
|
29996
|
-
var WorkspaceGridItem =
|
|
30368
|
+
var WorkspaceGridItem = React21__default.memo(({
|
|
29997
30369
|
data,
|
|
29998
30370
|
position,
|
|
29999
30371
|
isBottleneck = false,
|
|
@@ -30086,7 +30458,7 @@ var WorkspaceGridItem = React20__default.memo(({
|
|
|
30086
30458
|
);
|
|
30087
30459
|
}, arePropsEqual);
|
|
30088
30460
|
WorkspaceGridItem.displayName = "WorkspaceGridItem";
|
|
30089
|
-
var WorkspaceGrid =
|
|
30461
|
+
var WorkspaceGrid = React21__default.memo(({
|
|
30090
30462
|
workspaces,
|
|
30091
30463
|
isPdfMode = false,
|
|
30092
30464
|
customWorkspacePositions,
|
|
@@ -30280,7 +30652,7 @@ var KPICard = ({
|
|
|
30280
30652
|
}) => {
|
|
30281
30653
|
useThemeConfig();
|
|
30282
30654
|
const { formatNumber } = useFormatNumber();
|
|
30283
|
-
const trendInfo =
|
|
30655
|
+
const trendInfo = React21__default.useMemo(() => {
|
|
30284
30656
|
let trendValue = trend || "neutral";
|
|
30285
30657
|
if (change !== void 0 && trend === void 0) {
|
|
30286
30658
|
trendValue = change > 0 ? "up" : change < 0 ? "down" : "neutral";
|
|
@@ -30303,7 +30675,7 @@ var KPICard = ({
|
|
|
30303
30675
|
const shouldShowTrend = !(change === 0 && trend === void 0);
|
|
30304
30676
|
return { trendValue, Icon: Icon2, colorClass, shouldShowTrend };
|
|
30305
30677
|
}, [trend, change]);
|
|
30306
|
-
const formattedValue =
|
|
30678
|
+
const formattedValue = React21__default.useMemo(() => {
|
|
30307
30679
|
if (title === "Quality Compliance" && typeof value === "number") {
|
|
30308
30680
|
return value.toFixed(1);
|
|
30309
30681
|
}
|
|
@@ -30317,7 +30689,7 @@ var KPICard = ({
|
|
|
30317
30689
|
}
|
|
30318
30690
|
return value;
|
|
30319
30691
|
}, [value, title]);
|
|
30320
|
-
const formattedChange =
|
|
30692
|
+
const formattedChange = React21__default.useMemo(() => {
|
|
30321
30693
|
if (change === void 0 || change === 0) return null;
|
|
30322
30694
|
const absChange = Math.abs(change);
|
|
30323
30695
|
return formatNumber(absChange, { minimumFractionDigits: 0, maximumFractionDigits: 1 });
|
|
@@ -31066,11 +31438,11 @@ var HealthStatusGrid = ({
|
|
|
31066
31438
|
filteredWorkspaces.length === 0 && /* @__PURE__ */ jsx("div", { className: "text-center py-12", children: /* @__PURE__ */ jsx("p", { className: "text-gray-500 dark:text-gray-400", children: searchTerm || statusFilter !== "all" ? "No workspaces found matching your filters." : "No workspaces available." }) })
|
|
31067
31439
|
] });
|
|
31068
31440
|
};
|
|
31069
|
-
var
|
|
31441
|
+
var Timer2 = Timer_default;
|
|
31070
31442
|
var DashboardHeader = memo(({ lineTitle, className = "", headerControls }) => {
|
|
31071
31443
|
const dashboardConfig = useDashboardConfig();
|
|
31444
|
+
const timezone = useAppTimezone();
|
|
31072
31445
|
const getShiftName = () => {
|
|
31073
|
-
const timezone = dashboardConfig.dateTimeConfig?.defaultTimezone || "Asia/Kolkata";
|
|
31074
31446
|
const currentShift = getCurrentShift(timezone, dashboardConfig.shiftConfig);
|
|
31075
31447
|
return currentShift.shiftId === 0 ? "Day" : "Night";
|
|
31076
31448
|
};
|
|
@@ -31089,10 +31461,7 @@ var DashboardHeader = memo(({ lineTitle, className = "", headerControls }) => {
|
|
|
31089
31461
|
/* @__PURE__ */ jsx("div", { className: "h-1.5 w-1.5 sm:h-1.5 sm:w-1.5 md:h-2 md:w-2 rounded-full bg-green-500 animate-pulse ring-1 sm:ring-2 ring-green-500/30 ring-offset-1 flex-shrink-0" })
|
|
31090
31462
|
] }),
|
|
31091
31463
|
/* @__PURE__ */ jsxs("div", { className: "mt-0.5 sm:mt-2 inline-flex flex-wrap items-center gap-1.5 sm:gap-3", children: [
|
|
31092
|
-
/* @__PURE__ */
|
|
31093
|
-
/* @__PURE__ */ jsx(ISTTimer2, {}),
|
|
31094
|
-
" IST"
|
|
31095
|
-
] }),
|
|
31464
|
+
/* @__PURE__ */ jsx("div", { className: "text-[10px] sm:text-xs md:text-sm font-medium text-gray-500 sm:text-gray-600 whitespace-nowrap", children: /* @__PURE__ */ jsx(Timer2, {}) }),
|
|
31096
31465
|
/* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-0.5 sm:gap-1", children: [
|
|
31097
31466
|
/* @__PURE__ */ jsx("div", { className: "text-gray-500 sm:text-gray-600 scale-90 sm:scale-100", children: getShiftIcon() }),
|
|
31098
31467
|
/* @__PURE__ */ jsxs("span", { className: "text-[10px] sm:text-xs md:text-sm font-medium text-gray-500 sm:text-gray-600 whitespace-nowrap", children: [
|
|
@@ -31487,7 +31856,7 @@ var Breadcrumbs = ({ items }) => {
|
|
|
31487
31856
|
}
|
|
31488
31857
|
}
|
|
31489
31858
|
};
|
|
31490
|
-
return /* @__PURE__ */ jsx("nav", { "aria-label": "Breadcrumb", className: "mb-1 flex items-center space-x-1 text-xs font-medium text-gray-500 dark:text-gray-400", children: items.map((item, index) => /* @__PURE__ */ jsxs(
|
|
31859
|
+
return /* @__PURE__ */ jsx("nav", { "aria-label": "Breadcrumb", className: "mb-1 flex items-center space-x-1 text-xs font-medium text-gray-500 dark:text-gray-400", children: items.map((item, index) => /* @__PURE__ */ jsxs(React21__default.Fragment, { children: [
|
|
31491
31860
|
index > 0 && /* @__PURE__ */ jsx(ChevronRight, { className: "h-3 w-3 text-gray-400 dark:text-gray-500" }),
|
|
31492
31861
|
/* @__PURE__ */ jsxs(
|
|
31493
31862
|
"span",
|
|
@@ -33944,7 +34313,7 @@ var ThreadSidebar = ({
|
|
|
33944
34313
|
] });
|
|
33945
34314
|
};
|
|
33946
34315
|
var axelProfilePng = "/axel-profile.png";
|
|
33947
|
-
var ProfilePicture =
|
|
34316
|
+
var ProfilePicture = React21__default.memo(({ alt = "Axel", className = "w-8 h-8 sm:w-10 sm:h-10 md:w-12 md:h-12" }) => {
|
|
33948
34317
|
return /* @__PURE__ */ jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsx("div", { className: `${className} rounded-xl overflow-hidden shadow-sm`, children: /* @__PURE__ */ jsx(
|
|
33949
34318
|
"img",
|
|
33950
34319
|
{
|
|
@@ -35928,7 +36297,6 @@ function DebugAuthView() {
|
|
|
35928
36297
|
return /* @__PURE__ */ jsx(DebugAuth, {});
|
|
35929
36298
|
}
|
|
35930
36299
|
var DebugAuthView_default = DebugAuthView;
|
|
35931
|
-
var DEFAULT_TIMEZONE = "Asia/Kolkata";
|
|
35932
36300
|
var DEFAULT_SHIFT_CONFIG2 = {
|
|
35933
36301
|
dayShift: { id: 0, startTime: "06:00" },
|
|
35934
36302
|
nightShift: { id: 1, startTime: "18:00" }
|
|
@@ -35939,10 +36307,12 @@ var FactoryView = ({
|
|
|
35939
36307
|
lineIds,
|
|
35940
36308
|
lineNames = {},
|
|
35941
36309
|
factoryName = "Plant 1",
|
|
35942
|
-
timezone
|
|
36310
|
+
timezone: propTimezone,
|
|
35943
36311
|
shiftConfig = DEFAULT_SHIFT_CONFIG2,
|
|
35944
36312
|
productIds = {}
|
|
35945
36313
|
}) => {
|
|
36314
|
+
const contextTimezone = useAppTimezone();
|
|
36315
|
+
const timezone = propTimezone || contextTimezone;
|
|
35946
36316
|
const effectiveLineIds = useMemo(() => {
|
|
35947
36317
|
if (lineIds && lineIds.length > 0) {
|
|
35948
36318
|
return lineIds;
|
|
@@ -36003,7 +36373,7 @@ var FactoryView = ({
|
|
|
36003
36373
|
return;
|
|
36004
36374
|
}
|
|
36005
36375
|
const { shiftId } = getCurrentShift(timezone, shiftConfig);
|
|
36006
|
-
const date = getOperationalDate();
|
|
36376
|
+
const date = getOperationalDate(timezone);
|
|
36007
36377
|
const hourlyDataPromises = effectiveLineIds.map(
|
|
36008
36378
|
(lineId) => supabase.from("line_hourly_metrics").select("hour, efficiency").eq("line_id", lineId).eq("shift_id", shiftId).eq("date", date).order("hour", { ascending: false }).limit(5)
|
|
36009
36379
|
);
|
|
@@ -36485,6 +36855,7 @@ function HomeView({
|
|
|
36485
36855
|
const [displayNamesInitialized, setDisplayNamesInitialized] = useState(false);
|
|
36486
36856
|
const [hasInitialDataLoaded, setHasInitialDataLoaded] = useState(false);
|
|
36487
36857
|
const dashboardConfig = useDashboardConfig();
|
|
36858
|
+
const timezone = useAppTimezone();
|
|
36488
36859
|
useEffect(() => {
|
|
36489
36860
|
const initDisplayNames = async () => {
|
|
36490
36861
|
try {
|
|
@@ -36549,7 +36920,7 @@ function HomeView({
|
|
|
36549
36920
|
useEffect(() => {
|
|
36550
36921
|
if (!dashboardConfig?.s3Config) return;
|
|
36551
36922
|
if (!workspaceMetrics || workspaceMetrics.length === 0) return;
|
|
36552
|
-
getOperationalDate(dashboardConfig.dateTimeConfig?.defaultTimezone);
|
|
36923
|
+
getOperationalDate(timezone || dashboardConfig.dateTimeConfig?.defaultTimezone || "UTC");
|
|
36553
36924
|
console.log(`[HomeView] Starting optimized prefetch for ${workspaceMetrics.length} workspaces`);
|
|
36554
36925
|
workspaceMetrics.map((ws) => ws.workspace_uuid).filter(Boolean);
|
|
36555
36926
|
}, [dashboardConfig, workspaceMetrics]);
|
|
@@ -36653,7 +37024,7 @@ function HomeView({
|
|
|
36653
37024
|
animate: { opacity: 1, scale: 1 },
|
|
36654
37025
|
transition: { duration: 0.3 },
|
|
36655
37026
|
className: "h-full",
|
|
36656
|
-
children:
|
|
37027
|
+
children: React21__default.createElement(WorkspaceGrid, {
|
|
36657
37028
|
workspaces: memoizedWorkspaceMetrics,
|
|
36658
37029
|
lineNames,
|
|
36659
37030
|
factoryView: factoryViewId,
|
|
@@ -36679,7 +37050,7 @@ function HomeView({
|
|
|
36679
37050
|
animate: { opacity: 1, scale: 1 },
|
|
36680
37051
|
transition: { duration: 0.3 },
|
|
36681
37052
|
className: "h-full",
|
|
36682
|
-
children:
|
|
37053
|
+
children: React21__default.createElement(WorkspaceGrid, {
|
|
36683
37054
|
workspaces: [],
|
|
36684
37055
|
// Show empty grid while loading
|
|
36685
37056
|
lineNames,
|
|
@@ -36706,7 +37077,7 @@ function HomeView({
|
|
|
36706
37077
|
}
|
|
36707
37078
|
);
|
|
36708
37079
|
}
|
|
36709
|
-
var AuthenticatedHomeView = withAuth(
|
|
37080
|
+
var AuthenticatedHomeView = withAuth(React21__default.memo(HomeView));
|
|
36710
37081
|
var HomeView_default = HomeView;
|
|
36711
37082
|
function withWorkspaceDisplayNames(Component3, options = {}) {
|
|
36712
37083
|
const {
|
|
@@ -37089,6 +37460,7 @@ var KPIDetailView = ({
|
|
|
37089
37460
|
backLinkUrl,
|
|
37090
37461
|
onBackClick
|
|
37091
37462
|
}) => {
|
|
37463
|
+
const timezone = useAppTimezone();
|
|
37092
37464
|
const [activeTab, setActiveTab] = useState("overview");
|
|
37093
37465
|
const [currentMonth, setCurrentMonth] = useState(() => {
|
|
37094
37466
|
if (urlMonth && typeof urlMonth === "string") {
|
|
@@ -37125,7 +37497,7 @@ var KPIDetailView = ({
|
|
|
37125
37497
|
}, [urlShift]);
|
|
37126
37498
|
const supabase = useSupabase();
|
|
37127
37499
|
const dashboardConfig = useDashboardConfig();
|
|
37128
|
-
const configuredTimezone = dashboardConfig.dateTimeConfig?.defaultTimezone || "
|
|
37500
|
+
const configuredTimezone = timezone || dashboardConfig.dateTimeConfig?.defaultTimezone || "UTC";
|
|
37129
37501
|
useMemo(() => getCurrentTimeInZone(configuredTimezone), [configuredTimezone]);
|
|
37130
37502
|
const supervisorEnabled = dashboardConfig?.supervisorConfig?.enabled || false;
|
|
37131
37503
|
useEffect(() => {
|
|
@@ -37151,18 +37523,22 @@ var KPIDetailView = ({
|
|
|
37151
37523
|
}
|
|
37152
37524
|
}, [getShiftName]);
|
|
37153
37525
|
const getDaysDifference2 = useCallback((date) => {
|
|
37154
|
-
const today = /* @__PURE__ */ new Date();
|
|
37155
37526
|
const compareDate = new Date(date);
|
|
37156
|
-
const
|
|
37527
|
+
const shiftStartTime = dashboardConfig.shiftConfig?.dayShift?.startTime || "06:00";
|
|
37528
|
+
const operationalTodayString = getOperationalDate(configuredTimezone, /* @__PURE__ */ new Date(), shiftStartTime);
|
|
37529
|
+
const operationalTodayDate = new Date(operationalTodayString);
|
|
37157
37530
|
const compareDateInZone = new Date(compareDate.toLocaleString("en-US", { timeZone: configuredTimezone }));
|
|
37158
|
-
|
|
37531
|
+
operationalTodayDate.setHours(0, 0, 0, 0);
|
|
37159
37532
|
compareDateInZone.setHours(0, 0, 0, 0);
|
|
37160
|
-
const diffTime =
|
|
37161
|
-
const diffDays = Math.
|
|
37533
|
+
const diffTime = compareDateInZone.getTime() - operationalTodayDate.getTime();
|
|
37534
|
+
const diffDays = Math.round(diffTime / (1e3 * 60 * 60 * 24));
|
|
37162
37535
|
if (diffDays === 0) return "Today";
|
|
37163
|
-
if (diffDays === 1) return "Yesterday";
|
|
37164
|
-
|
|
37165
|
-
|
|
37536
|
+
if (diffDays === -1) return "Yesterday";
|
|
37537
|
+
if (diffDays === 1) return "Tomorrow";
|
|
37538
|
+
if (diffDays < -1) return `${Math.abs(diffDays)} days ago`;
|
|
37539
|
+
if (diffDays > 1) return `${diffDays} days ahead`;
|
|
37540
|
+
return "Today";
|
|
37541
|
+
}, [configuredTimezone, dashboardConfig.shiftConfig]);
|
|
37166
37542
|
const {
|
|
37167
37543
|
metrics: metrics2,
|
|
37168
37544
|
lineDetails,
|
|
@@ -37277,7 +37653,7 @@ var KPIDetailView = ({
|
|
|
37277
37653
|
factory_id: lineDetails.factory_id,
|
|
37278
37654
|
factory_name: lineDetails.factory.factory_name,
|
|
37279
37655
|
shift_id: metrics2.shift_id ?? 0,
|
|
37280
|
-
date: metrics2.date || getOperationalDate(),
|
|
37656
|
+
date: metrics2.date || getOperationalDate(timezone || "UTC"),
|
|
37281
37657
|
metrics: {
|
|
37282
37658
|
avg_efficiency: metrics2.avg_efficiency ?? 0,
|
|
37283
37659
|
avg_cycle_time: metrics2.avg_cycle_time ?? 0,
|
|
@@ -37824,7 +38200,7 @@ var KPIDetailViewWithDisplayNames = withSelectedLineDisplayNames(KPIDetailView);
|
|
|
37824
38200
|
var KPIDetailView_default = KPIDetailViewWithDisplayNames;
|
|
37825
38201
|
var LineCard = ({ line, onClick, supervisorEnabled = false }) => {
|
|
37826
38202
|
const { kpis, isLoading, error } = useLineKPIs({ lineId: line.id });
|
|
37827
|
-
const isOnTrack =
|
|
38203
|
+
const isOnTrack = React21__default.useMemo(() => {
|
|
37828
38204
|
if (!kpis) return null;
|
|
37829
38205
|
return kpis.efficiency.value > 90;
|
|
37830
38206
|
}, [kpis]);
|
|
@@ -37932,7 +38308,8 @@ var KPIsOverviewView = ({
|
|
|
37932
38308
|
const dateTimeConfig = useDateTimeConfig();
|
|
37933
38309
|
const shiftConfig = useShiftConfig();
|
|
37934
38310
|
const supervisorEnabled = dashboardConfig?.supervisorConfig?.enabled || false;
|
|
37935
|
-
const
|
|
38311
|
+
const dbTimezone = useAppTimezone();
|
|
38312
|
+
const configuredTimezone = dbTimezone || dateTimeConfig.defaultTimezone || "UTC";
|
|
37936
38313
|
useEffect(() => {
|
|
37937
38314
|
const fetchLines = async () => {
|
|
37938
38315
|
try {
|
|
@@ -39627,7 +40004,7 @@ var ShiftsView = ({
|
|
|
39627
40004
|
] })
|
|
39628
40005
|
] });
|
|
39629
40006
|
};
|
|
39630
|
-
var AuthenticatedShiftsView = withAuth(
|
|
40007
|
+
var AuthenticatedShiftsView = withAuth(React21__default.memo(ShiftsView));
|
|
39631
40008
|
var ShiftsView_default = ShiftsView;
|
|
39632
40009
|
|
|
39633
40010
|
// src/lib/constants/actions.ts
|
|
@@ -40843,6 +41220,7 @@ var TargetsView = ({
|
|
|
40843
41220
|
userId,
|
|
40844
41221
|
onSaveChanges
|
|
40845
41222
|
}) => {
|
|
41223
|
+
const timezone = useAppTimezone();
|
|
40846
41224
|
const initialLineWorkspaces = useMemo(() => {
|
|
40847
41225
|
return lineIds.reduce((acc, lineId) => ({
|
|
40848
41226
|
...acc,
|
|
@@ -41061,7 +41439,7 @@ var TargetsView = ({
|
|
|
41061
41439
|
updatedLineWorkspaces[result.lineId].factoryId = result.factoryId;
|
|
41062
41440
|
}
|
|
41063
41441
|
});
|
|
41064
|
-
const currentDate = getOperationalDate();
|
|
41442
|
+
const currentDate = getOperationalDate(timezone);
|
|
41065
41443
|
for (const lineId of lineIds) {
|
|
41066
41444
|
if (!updatedLineWorkspaces[lineId]?.factoryId) {
|
|
41067
41445
|
console.warn(`Skipping workspace fetch for line ${lineId} - no factory ID`);
|
|
@@ -41142,7 +41520,7 @@ var TargetsView = ({
|
|
|
41142
41520
|
}, [lineIds, companyId, loadOperatingHours]);
|
|
41143
41521
|
const fetchAllShiftsData = useCallback(async (currentWorkspaces) => {
|
|
41144
41522
|
if (!supabase) return;
|
|
41145
|
-
const currentDate = getOperationalDate();
|
|
41523
|
+
const currentDate = getOperationalDate(timezone);
|
|
41146
41524
|
const newAllShiftsData = {
|
|
41147
41525
|
0: JSON.parse(JSON.stringify(currentWorkspaces)),
|
|
41148
41526
|
// Deep clone for day shift
|
|
@@ -41381,7 +41759,7 @@ var TargetsView = ({
|
|
|
41381
41759
|
return;
|
|
41382
41760
|
}
|
|
41383
41761
|
const currentFactoryId = lineDataToSave.factoryId;
|
|
41384
|
-
const currentDate = getOperationalDate();
|
|
41762
|
+
const currentDate = getOperationalDate(timezone);
|
|
41385
41763
|
console.log(`[handleSaveLine] currentDate: ${currentDate}, selectedShift: ${selectedShift}`);
|
|
41386
41764
|
const workspaceThresholdUpdates = lineDataToSave.workspaces.map((ws) => ({
|
|
41387
41765
|
line_id: lineId,
|
|
@@ -41543,37 +41921,43 @@ var TargetsView = ({
|
|
|
41543
41921
|
};
|
|
41544
41922
|
var TargetsViewWithDisplayNames = withAllWorkspaceDisplayNames(TargetsView);
|
|
41545
41923
|
var TargetsView_default = TargetsViewWithDisplayNames;
|
|
41546
|
-
var AuthenticatedTargetsView = withAuth(
|
|
41924
|
+
var AuthenticatedTargetsView = withAuth(React21__default.memo(TargetsViewWithDisplayNames));
|
|
41547
41925
|
|
|
41548
41926
|
// src/views/workspace-detail-view.utils.ts
|
|
41549
|
-
var
|
|
41927
|
+
var formatDateInTimezone = (date = /* @__PURE__ */ new Date(), timezone, options) => {
|
|
41550
41928
|
const defaultOptions = {
|
|
41551
41929
|
day: "numeric",
|
|
41552
41930
|
month: "long",
|
|
41553
41931
|
year: "numeric",
|
|
41554
|
-
timeZone:
|
|
41932
|
+
timeZone: timezone
|
|
41555
41933
|
};
|
|
41556
|
-
const formatter = new Intl.DateTimeFormat("en-
|
|
41934
|
+
const formatter = new Intl.DateTimeFormat("en-US", {
|
|
41557
41935
|
...defaultOptions,
|
|
41558
41936
|
...options
|
|
41559
41937
|
});
|
|
41560
41938
|
return formatter.format(date);
|
|
41561
41939
|
};
|
|
41940
|
+
var formatISTDate2 = (date = /* @__PURE__ */ new Date(), options) => {
|
|
41941
|
+
return formatDateInTimezone(date, "Asia/Kolkata", options);
|
|
41942
|
+
};
|
|
41562
41943
|
var formatWorkspaceName3 = (name, lineId) => {
|
|
41563
41944
|
return getWorkspaceDisplayName(name, lineId);
|
|
41564
41945
|
};
|
|
41565
|
-
var getDaysDifference = (date) => {
|
|
41566
|
-
const today = /* @__PURE__ */ new Date();
|
|
41946
|
+
var getDaysDifference = (date, timezone = "UTC", shiftStartTime = "06:00") => {
|
|
41567
41947
|
const compareDate = new Date(date);
|
|
41568
|
-
const
|
|
41569
|
-
const
|
|
41570
|
-
|
|
41571
|
-
|
|
41572
|
-
|
|
41573
|
-
const
|
|
41948
|
+
const operationalTodayString = getOperationalDate(timezone, /* @__PURE__ */ new Date(), shiftStartTime);
|
|
41949
|
+
const operationalTodayDate = new Date(operationalTodayString);
|
|
41950
|
+
const compareDateInTz = new Date(compareDate.toLocaleString("en-US", { timeZone: timezone }));
|
|
41951
|
+
operationalTodayDate.setHours(0, 0, 0, 0);
|
|
41952
|
+
compareDateInTz.setHours(0, 0, 0, 0);
|
|
41953
|
+
const diffTime = compareDateInTz.getTime() - operationalTodayDate.getTime();
|
|
41954
|
+
const diffDays = Math.round(diffTime / (1e3 * 60 * 60 * 24));
|
|
41574
41955
|
if (diffDays === 0) return "Today";
|
|
41575
|
-
if (diffDays === 1) return "Yesterday";
|
|
41576
|
-
|
|
41956
|
+
if (diffDays === -1) return "Yesterday";
|
|
41957
|
+
if (diffDays === 1) return "Tomorrow";
|
|
41958
|
+
if (diffDays < -1) return `${Math.abs(diffDays)} days ago`;
|
|
41959
|
+
if (diffDays > 1) return `${diffDays} days ahead`;
|
|
41960
|
+
return "Today";
|
|
41577
41961
|
};
|
|
41578
41962
|
var getInitialTab = (sourceType, defaultTab, fromMonthly, urlDate) => {
|
|
41579
41963
|
if (sourceType === "lineMonthlyHistory") {
|
|
@@ -41621,7 +42005,8 @@ var WorkspaceDetailView = ({
|
|
|
41621
42005
|
const [previousView, setPreviousView] = useState("dashboard");
|
|
41622
42006
|
const [monthlyData, setMonthlyData] = useState([]);
|
|
41623
42007
|
const [monthlyDataLoading, setMonthlyDataLoading] = useState(false);
|
|
41624
|
-
const
|
|
42008
|
+
const timezone = useAppTimezone();
|
|
42009
|
+
const today = new Date((/* @__PURE__ */ new Date()).toLocaleString("en-US", { timeZone: timezone }));
|
|
41625
42010
|
const [selectedMonth, setSelectedMonth] = useState(today.getMonth());
|
|
41626
42011
|
const [selectedYear, setSelectedYear] = useState(today.getFullYear());
|
|
41627
42012
|
const [selectedShift, setSelectedShift] = useState("day");
|
|
@@ -41678,7 +42063,7 @@ var WorkspaceDetailView = ({
|
|
|
41678
42063
|
error: liveError
|
|
41679
42064
|
} = useWorkspaceDetailedMetrics(
|
|
41680
42065
|
workspaceId || "",
|
|
41681
|
-
getOperationalDate(),
|
|
42066
|
+
getOperationalDate(timezone),
|
|
41682
42067
|
void 0
|
|
41683
42068
|
);
|
|
41684
42069
|
const workspace = isHistoricView ? historicMetrics : liveMetrics;
|
|
@@ -41777,7 +42162,7 @@ var WorkspaceDetailView = ({
|
|
|
41777
42162
|
}, [isClipsEnabled, activeTab]);
|
|
41778
42163
|
useEffect(() => {
|
|
41779
42164
|
if (liveMetrics && !date && !shift) {
|
|
41780
|
-
const currentDate = getOperationalDate();
|
|
42165
|
+
const currentDate = getOperationalDate(timezone);
|
|
41781
42166
|
if (liveMetrics.date !== currentDate) {
|
|
41782
42167
|
setUsingFallbackData(true);
|
|
41783
42168
|
if (activeTab !== "monthly_history") {
|
|
@@ -41795,10 +42180,10 @@ var WorkspaceDetailView = ({
|
|
|
41795
42180
|
return date;
|
|
41796
42181
|
} catch (e) {
|
|
41797
42182
|
console.error("Error parsing historic date:", e);
|
|
41798
|
-
return getOperationalDate();
|
|
42183
|
+
return getOperationalDate(timezone);
|
|
41799
42184
|
}
|
|
41800
42185
|
}
|
|
41801
|
-
return getOperationalDate();
|
|
42186
|
+
return getOperationalDate(timezone);
|
|
41802
42187
|
}, [isHistoricView, date]);
|
|
41803
42188
|
const handleMonthlyDataLoaded = useCallback((data) => {
|
|
41804
42189
|
console.log("[handleMonthlyDataLoaded] Received data:", {
|
|
@@ -42045,7 +42430,7 @@ var WorkspaceDetailView = ({
|
|
|
42045
42430
|
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children: getShiftIcon(workspace.shift_type) }),
|
|
42046
42431
|
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-700", children: workspace.shift_type })
|
|
42047
42432
|
] }),
|
|
42048
|
-
!date && !shift && !usingFallbackData ? /* @__PURE__ */ jsx("div", { className: "inline-flex items-center px-2.5 py-1 bg-green-100 rounded-full", children: /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-green-700", children: /* @__PURE__ */ jsx(LiveTimer, {}) }) }) : date ? /* @__PURE__ */ jsx("div", { className: "inline-flex items-center px-2.5 py-1 bg-blue-100 rounded-full", children: /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-blue-700", children: getDaysDifference(workspace.date) }) }) : usingFallbackData ? /* @__PURE__ */ jsx("div", { className: "inline-flex items-center px-2.5 py-1 bg-amber-100 rounded-full", children: /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-amber-700", children: getDaysDifference(workspace.date) }) }) : null
|
|
42433
|
+
!date && !shift && !usingFallbackData ? /* @__PURE__ */ jsx("div", { className: "inline-flex items-center px-2.5 py-1 bg-green-100 rounded-full", children: /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-green-700", children: /* @__PURE__ */ jsx(LiveTimer, {}) }) }) : date ? /* @__PURE__ */ jsx("div", { className: "inline-flex items-center px-2.5 py-1 bg-blue-100 rounded-full", children: /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-blue-700", children: getDaysDifference(workspace.date, timezone, dashboardConfig?.shiftConfig?.dayShift?.startTime || "06:00") }) }) : usingFallbackData ? /* @__PURE__ */ jsx("div", { className: "inline-flex items-center px-2.5 py-1 bg-amber-100 rounded-full", children: /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-amber-700", children: getDaysDifference(workspace.date, timezone, dashboardConfig?.shiftConfig?.dayShift?.startTime || "06:00") }) }) : null
|
|
42049
42434
|
] }),
|
|
42050
42435
|
/* @__PURE__ */ jsx("div", { className: "hidden sm:block mt-3 bg-blue-50 px-3 py-2 rounded-lg", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-center gap-3 md:gap-4", children: [
|
|
42051
42436
|
!date && !shift && !usingFallbackData && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -42055,13 +42440,13 @@ var WorkspaceDetailView = ({
|
|
|
42055
42440
|
/* @__PURE__ */ jsx("span", { className: "text-sm md:text-base font-medium text-blue-600", children: formatISTDate2(new Date(workspace.date)) }),
|
|
42056
42441
|
/* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-blue-300" }),
|
|
42057
42442
|
date && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
42058
|
-
/* @__PURE__ */ jsx("span", { className: "px-2 py-1 text-xs font-medium bg-blue-200 text-blue-800 rounded-md", children: getDaysDifference(workspace.date) }),
|
|
42443
|
+
/* @__PURE__ */ jsx("span", { className: "px-2 py-1 text-xs font-medium bg-blue-200 text-blue-800 rounded-md", children: getDaysDifference(workspace.date, timezone, dashboardConfig?.shiftConfig?.dayShift?.startTime || "06:00") }),
|
|
42059
42444
|
/* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-blue-300" })
|
|
42060
42445
|
] }),
|
|
42061
42446
|
!date && !shift && usingFallbackData && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
42062
42447
|
/* @__PURE__ */ jsxs("span", { className: "px-2 py-1 text-xs font-medium bg-amber-100 text-amber-700 rounded-md", children: [
|
|
42063
42448
|
"Latest available data (",
|
|
42064
|
-
getDaysDifference(workspace.date),
|
|
42449
|
+
getDaysDifference(workspace.date, timezone, dashboardConfig?.shiftConfig?.dayShift?.startTime || "06:00"),
|
|
42065
42450
|
")"
|
|
42066
42451
|
] }),
|
|
42067
42452
|
/* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-blue-300" })
|
|
@@ -42624,7 +43009,8 @@ var WorkspaceHealthView = ({
|
|
|
42624
43009
|
}) => {
|
|
42625
43010
|
const router = useRouter();
|
|
42626
43011
|
const [groupBy, setGroupBy] = useState("line");
|
|
42627
|
-
const
|
|
43012
|
+
const timezone = useAppTimezone();
|
|
43013
|
+
const operationalDate = getOperationalDate(timezone || "UTC");
|
|
42628
43014
|
const currentHour = (/* @__PURE__ */ new Date()).getHours();
|
|
42629
43015
|
const isNightShift = currentHour >= 18 || currentHour < 6;
|
|
42630
43016
|
const shiftType = isNightShift ? "Night" : "Day";
|
|
@@ -43101,7 +43487,7 @@ var S3Service = class {
|
|
|
43101
43487
|
/**
|
|
43102
43488
|
* List S3 clips for a specific workspace and date
|
|
43103
43489
|
*/
|
|
43104
|
-
async listS3Clips(workspaceId, date
|
|
43490
|
+
async listS3Clips(workspaceId, date) {
|
|
43105
43491
|
const prefix = `sop_violations/${workspaceId}/${date}/`;
|
|
43106
43492
|
if (this.isSimulated()) {
|
|
43107
43493
|
console.log("Running in simulated mode - generating mock data for:", prefix);
|
|
@@ -43260,7 +43646,7 @@ var S3Service = class {
|
|
|
43260
43646
|
/**
|
|
43261
43647
|
* Get all clips for a workspace on a specific date
|
|
43262
43648
|
*/
|
|
43263
|
-
async getWorkspaceClips(workspaceId, date
|
|
43649
|
+
async getWorkspaceClips(workspaceId, date) {
|
|
43264
43650
|
try {
|
|
43265
43651
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
43266
43652
|
throw new Error("Invalid date format. Use YYYY-MM-DD.");
|
|
@@ -43688,4 +44074,4 @@ function shuffleArray(array) {
|
|
|
43688
44074
|
return shuffled;
|
|
43689
44075
|
}
|
|
43690
44076
|
|
|
43691
|
-
export { ACTION_NAMES, AIAgentView_default as AIAgentView, AdvancedFilterDialog, AdvancedFilterPanel, AudioService, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedShiftsView, AuthenticatedTargetsView, AuthenticatedWorkspaceHealthView, BackButton, BackButtonMinimal, BarChart, BaseHistoryCalendar, BottlenecksContent, BreakNotificationPopup, CachePrefetchStatus, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, ClipFilterProvider, CompactWorkspaceHealthCard, CongratulationsOverlay, CroppedVideoPlayer, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_THEME_CONFIG, DEFAULT_VIDEO_CONFIG, DEFAULT_WORKSPACE_CONFIG, DEFAULT_WORKSPACE_POSITIONS, DashboardHeader, DashboardLayout, DashboardOverridesProvider, DashboardProvider, DateDisplay_default as DateDisplay, DateTimeDisplay, DebugAuth, DebugAuthView_default as DebugAuthView, DetailedHealthStatus, EmptyStateMessage, EncouragementOverlay, FactoryView_default as FactoryView, FileManagerFilters, FilterDialogTrigger, FirstTimeLoginDebug, FirstTimeLoginHandler, GaugeChart, GridComponentsPlaceholder, HamburgerButton, Header, HealthStatusGrid, HealthStatusIndicator, HelpView_default as HelpView, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, ISTTimer_default as ISTTimer, InlineEditableText, InteractiveOnboardingTour, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LINE_2_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView, Legend6 as Legend, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LinesService, LiveTimer, LoadingInline, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSkeleton, LoadingState, LoginPage, LoginView_default as LoginView, MainLayout, MetricCard_default as MetricCard, MinimalOnboardingPopup, NewClipsNotification, NoWorkspaceData, OnboardingDemo, OnboardingTour, OptifyeAgentClient, OptifyeLogoLoader_default as OptifyeLogoLoader, OutputProgressChart, PageHeader, PieChart4 as PieChart, PrefetchConfigurationError, PrefetchError, PrefetchEvents, PrefetchStatus, PrefetchTimeoutError, ProfileView_default as ProfileView, RegistryProvider, S3ClipsSupabaseService as S3ClipsService, S3Service, SKUManagementView, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SimpleOnboardingPopup, SingleVideoStream_default as SingleVideoStream, Skeleton, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, SupervisorDropdown_default as SupervisorDropdown, SupervisorManagementView_default as SupervisorManagementView, SupervisorService, TargetWorkspaceGrid, TargetsView_default as TargetsView, ThreadSidebar, TicketHistory_default as TicketHistory, TicketHistoryService, TimeDisplay_default as TimeDisplay, TimePickerDropdown, UserService, VideoCard, VideoGridView, VideoPlayer, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHealthCard, WorkspaceHealthView_default as WorkspaceHealthView, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMetricCardsImpl, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyHistory, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, apiUtils, authCoreService, authOTPService, authRateLimitService, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearWorkspaceDisplayNamesCache, cn, createLinesService, createStreamProxyHandler, createSupabaseClient, createSupervisorService, createThrottledReload, createUserService, dashboardService, deleteThread, forceRefreshWorkspaceDisplayNames, formatDateInZone, formatDateTimeInZone, formatISTDate, formatIdleTime, formatTimeInZone, fromUrlFriendlyName, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAnonClient, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getConfiguredLineIds, getCoreSessionRecordingProperties, getCoreSessionReplayUrl, getCurrentShift, getCurrentTimeInZone, getDashboardHeaderTimeInZone, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultLineId, getDefaultTabForWorkspace, getLineDisplayName, getManufacturingInsights, getMetricsTablePrefix, getOperationalDate, getS3SignedUrl, getS3VideoSrc, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUserThreads, getUserThreadsPaginated, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, identifyCoreUser, initializeCoreMixpanel, isLegacyConfiguration, isPrefetchError, isTransitionPeriod, isUrlPermanentlyFailed, isValidFactoryViewConfiguration, isValidLineInfoPayload, isValidPrefetchParams, isValidPrefetchStatus, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, linesService, mergeWithDefaultConfig, migrateLegacyConfiguration, optifyeAgentClient, parseS3Uri, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetFailedUrl, resetSubscriptionManager, s3VideoPreloader, shuffleArray, simulateApiDelay, skuService, startCoreSessionRecording, stopCoreSessionRecording, storeWorkspaceMapping, streamProxyConfig, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, updateThreadTitle, useAccessControl, useActiveBreaks, useAllWorkspaceMetrics, useAnalyticsConfig, useAudioService, useAuth, useAuthConfig, useCanSaveTargets, useClipFilter, useClipTypes, useClipTypesWithCounts, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useHourEndTimer, useHourlyTargetAchievements, useHourlyTargetMisses, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineWorkspaceMetrics, useMessages, useMetrics, useNavigation, useOverrides, usePageOverride, usePrefetchClipCounts, useRealtimeLineMetrics, useRegistry, useSKUs, useShiftConfig, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useTargets, useTheme, useThemeConfig, useThreads, useTicketHistory, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceHealth, useWorkspaceHealthById, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, userService, videoPrefetchManager, videoPreloader, whatsappService, withAccessControl, withAuth, withRegistry, workspaceHealthService, workspaceService };
|
|
44077
|
+
export { ACTION_NAMES, AIAgentView_default as AIAgentView, AdvancedFilterDialog, AdvancedFilterPanel, AudioService, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedShiftsView, AuthenticatedTargetsView, AuthenticatedWorkspaceHealthView, BackButton, BackButtonMinimal, BarChart, BaseHistoryCalendar, BottlenecksContent, BreakNotificationPopup, CachePrefetchStatus, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, ClipFilterProvider, CompactWorkspaceHealthCard, CongratulationsOverlay, CroppedVideoPlayer, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_THEME_CONFIG, DEFAULT_VIDEO_CONFIG, DEFAULT_WORKSPACE_CONFIG, DEFAULT_WORKSPACE_POSITIONS, DashboardHeader, DashboardLayout, DashboardOverridesProvider, DashboardProvider, DateDisplay_default as DateDisplay, DateTimeDisplay, DebugAuth, DebugAuthView_default as DebugAuthView, DetailedHealthStatus, EmptyStateMessage, EncouragementOverlay, FactoryView_default as FactoryView, FileManagerFilters, FilterDialogTrigger, FirstTimeLoginDebug, FirstTimeLoginHandler, GaugeChart, GridComponentsPlaceholder, HamburgerButton, Header, HealthStatusGrid, HealthStatusIndicator, HelpView_default as HelpView, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, ISTTimer_default as ISTTimer, InlineEditableText, InteractiveOnboardingTour, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LINE_2_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView, Legend6 as Legend, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LinesService, LiveTimer, LoadingInline, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSkeleton, LoadingState, LoginPage, LoginView_default as LoginView, MainLayout, MetricCard_default as MetricCard, MinimalOnboardingPopup, NewClipsNotification, NoWorkspaceData, OnboardingDemo, OnboardingTour, OptifyeAgentClient, OptifyeLogoLoader_default as OptifyeLogoLoader, OutputProgressChart, PageHeader, PieChart4 as PieChart, PrefetchConfigurationError, PrefetchError, PrefetchEvents, PrefetchStatus, PrefetchTimeoutError, ProfileView_default as ProfileView, RegistryProvider, S3ClipsSupabaseService as S3ClipsService, S3Service, SKUManagementView, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SimpleOnboardingPopup, SingleVideoStream_default as SingleVideoStream, Skeleton, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, SupervisorDropdown_default as SupervisorDropdown, SupervisorManagementView_default as SupervisorManagementView, SupervisorService, TargetWorkspaceGrid, TargetsView_default as TargetsView, ThreadSidebar, TicketHistory_default as TicketHistory, TicketHistoryService, TimeDisplay_default as TimeDisplay, TimePickerDropdown, Timer_default as Timer, TimezoneProvider, TimezoneService, UserService, VideoCard, VideoGridView, VideoPlayer, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHealthCard, WorkspaceHealthView_default as WorkspaceHealthView, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMetricCardsImpl, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyHistory, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, apiUtils, authCoreService, authOTPService, authRateLimitService, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearWorkspaceDisplayNamesCache, cn, createLinesService, createStreamProxyHandler, createSupabaseClient, createSupervisorService, createThrottledReload, createUserService, dashboardService, deleteThread, forceRefreshWorkspaceDisplayNames, formatDateInZone, formatDateTimeInZone, formatISTDate, formatIdleTime, formatTimeInZone, fromUrlFriendlyName, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAnonClient, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getConfiguredLineIds, getCoreSessionRecordingProperties, getCoreSessionReplayUrl, getCurrentShift, getCurrentTimeInZone, getDashboardHeaderTimeInZone, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultLineId, getDefaultTabForWorkspace, getLineDisplayName, getManufacturingInsights, getMetricsTablePrefix, getOperationalDate, getS3SignedUrl, getS3VideoSrc, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUserThreads, getUserThreadsPaginated, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, identifyCoreUser, initializeCoreMixpanel, isLegacyConfiguration, isPrefetchError, isTransitionPeriod, isUrlPermanentlyFailed, isValidFactoryViewConfiguration, isValidLineInfoPayload, isValidPrefetchParams, isValidPrefetchStatus, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, linesService, mergeWithDefaultConfig, migrateLegacyConfiguration, optifyeAgentClient, parseS3Uri, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetFailedUrl, resetSubscriptionManager, s3VideoPreloader, shuffleArray, simulateApiDelay, skuService, startCoreSessionRecording, stopCoreSessionRecording, storeWorkspaceMapping, streamProxyConfig, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, updateThreadTitle, useAccessControl, useActiveBreaks, useAllWorkspaceMetrics, useAnalyticsConfig, useAppTimezone, useAudioService, useAuth, useAuthConfig, useCanSaveTargets, useClipFilter, useClipTypes, useClipTypesWithCounts, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useHourEndTimer, useHourlyTargetAchievements, useHourlyTargetMisses, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineWorkspaceMetrics, useMessages, useMetrics, useNavigation, useOverrides, usePageOverride, usePrefetchClipCounts, useRealtimeLineMetrics, useRegistry, useSKUs, useShiftConfig, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useTargets, useTheme, useThemeConfig, useThreads, useTicketHistory, useTimezoneContext, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceHealth, useWorkspaceHealthById, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, userService, videoPrefetchManager, videoPreloader, whatsappService, withAccessControl, withAuth, withRegistry, withTimezone, workspaceHealthService, workspaceService };
|