diff --git a/CHANGELOG.md b/CHANGELOG.md index 26589be7..68edab34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- Fixed TypeError on streams table load after container restart: Added robust data validation and type coercion to handle malformed filter options during container startup. The streams table MultiSelect components now safely convert group names to strings and filter out null/undefined values, preventing "right-hand side of 'in' should be an object, got number" errors when the backend hasn't fully initialized. API error handling returns safe defaults. - Fixed XtreamCodes API crash when channels have NULL channel_group: The `player_api.php` endpoint (`xc_get_live_streams`) now gracefully handles channels without an assigned channel_group by dynamically looking up and assigning them to "Default Group" instead of crashing with AttributeError. Additionally, the Channel serializer now auto-assigns new channels to "Default Group" when `channel_group_id` is omitted during creation, preventing future NULL channel_group issues. - Fixed streams table column header overflow: Implemented fixed-height column headers (30px max-height) with pill-style filter display showing first selection plus count (e.g., "Sport +3"). Prevents header expansion when multiple filters are selected, maintaining compact table layout. (Fixes #613) - Fixed VOD logo cleanup button count: The "Cleanup Unused" button now displays the total count of all unused logos across all pages instead of only counting unused logos on the current page. diff --git a/frontend/src/api.js b/frontend/src/api.js index f878c047..6b9f87c4 100644 --- a/frontend/src/api.js +++ b/frontend/src/api.js @@ -783,6 +783,8 @@ export default class API { return response; } catch (e) { errorNotification('Failed to retrieve filter options', e); + // Return safe defaults to prevent crashes during container startup + return { groups: [], m3u_accounts: [] }; } } diff --git a/frontend/src/components/tables/StreamsTable.jsx b/frontend/src/components/tables/StreamsTable.jsx index dcb3284e..ac189b32 100644 --- a/frontend/src/components/tables/StreamsTable.jsx +++ b/frontend/src/components/tables/StreamsTable.jsx @@ -440,13 +440,23 @@ const StreamsTable = ({ onReady }) => { setAllRowIds(ids); // Set filtered options based on current filters - setGroupOptions(filterOptions.groups); - setM3uOptions( - filterOptions.m3u_accounts.map((m3u) => ({ - label: m3u.name, - value: `${m3u.id}`, - })) - ); + // Ensure groupOptions is always an array of valid strings + if (filterOptions && typeof filterOptions === 'object') { + setGroupOptions( + (filterOptions.groups || []) + .filter((group) => group != null && group !== '') + .map((group) => String(group)) + ); + // Ensure m3uOptions is always an array of valid objects + setM3uOptions( + (filterOptions.m3u_accounts || []) + .filter((m3u) => m3u && m3u.id != null && m3u.name) + .map((m3u) => ({ + label: String(m3u.name), + value: String(m3u.id), + })) + ); + } if (initialDataCount === null) { setInitialDataCount(result.count);