mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 17:06:15 -08:00
feat(category-management): show category item counts
This commit is contained in:
1 parent
51ce39e2b4
commit
fb1104f6b7
6 files changed
+54
-17
No files matched your search
+1
@@ -59,6 +59,7 @@
|
||||
>
|
||||
</mat-checkbox>
|
||||
<span class="category-name">{{ category.name }}</span>
|
||||
<span class="item-count">({{ getItemCount(category) }})</span>
|
||||
</div>
|
||||
} @empty {
|
||||
<div class="empty-message">
|
||||
|
||||
+6
@@ -79,6 +79,12 @@
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.item-count {
|
||||
opacity: 0.6;
|
||||
font-size: 12px;
|
||||
color: var(--mat-sys-on-surface-variant);
|
||||
}
|
||||
|
||||
.empty-message {
|
||||
padding: 24px;
|
||||
text-align: center;
|
||||
|
||||
+7
@@ -18,6 +18,7 @@ import { DatabaseService, XCategoryFromDb } from 'services';
|
||||
export interface CategoryManagementDialogData {
|
||||
playlistId: string;
|
||||
contentType: 'live' | 'vod' | 'series';
|
||||
itemCounts: Map<number, number>;
|
||||
}
|
||||
|
||||
interface CategoryWithSelection extends XCategoryFromDb {
|
||||
@@ -104,6 +105,12 @@ export class CategoryManagementDialogComponent implements OnInit {
|
||||
this.searchTerm.set('');
|
||||
}
|
||||
|
||||
getItemCount(category: CategoryWithSelection): number {
|
||||
// content.category_id references categories.id (internal DB id), not xtream_id
|
||||
const categoryId = Number(category.id);
|
||||
return this.data.itemCounts.get(categoryId) ?? 0;
|
||||
}
|
||||
|
||||
private getDbType(): 'live' | 'movies' | 'series' {
|
||||
switch (this.data.contentType) {
|
||||
case 'live':
|
||||
|
||||
@@ -32,7 +32,9 @@ export class CategoryViewComponent {
|
||||
}
|
||||
|
||||
getItemCount(item: XtreamCategory): number {
|
||||
const itemId = Number((item as any).category_id ?? item.id);
|
||||
// content.category_id references categories.id (internal DB id)
|
||||
// For DB format categories, use id; for API format, use category_id
|
||||
const itemId = Number(item.id ?? (item as any).category_id);
|
||||
return this.itemCounts().get(itemId) ?? 0;
|
||||
}
|
||||
}
|
||||
@@ -118,6 +118,7 @@ export class LiveStreamLayoutComponent implements OnInit {
|
||||
data: {
|
||||
playlistId,
|
||||
contentType,
|
||||
itemCounts: this.categoryItemCounts(),
|
||||
},
|
||||
width: '500px',
|
||||
maxHeight: '80vh',
|
||||
|
||||
@@ -50,7 +50,9 @@ export function withSelection() {
|
||||
*/
|
||||
getSelectedCategory: computed(() => {
|
||||
const categoryId = store.selectedCategoryId();
|
||||
if (!categoryId) return null;
|
||||
if (!categoryId) {
|
||||
return { id: 0, name: 'All Items', type: store.selectedContentType() };
|
||||
}
|
||||
|
||||
// Access parent store categories (from withContent)
|
||||
const storeAny = store as any;
|
||||
@@ -98,9 +100,6 @@ export function withSelection() {
|
||||
const startIndex = store.page() * store.limit();
|
||||
const endIndex = startIndex + store.limit();
|
||||
const categoryId = store.selectedCategoryId();
|
||||
|
||||
if (!categoryId) return [];
|
||||
|
||||
const categoryType = store.selectedContentType();
|
||||
|
||||
// Access parent store content (from withContent)
|
||||
@@ -112,9 +111,20 @@ export function withSelection() {
|
||||
? storeAny.vodStreams?.() || []
|
||||
: storeAny.serialStreams?.() || [];
|
||||
|
||||
return content
|
||||
.filter((item: any) => Number(item.category_id) === categoryId)
|
||||
.slice(startIndex, endIndex);
|
||||
let filteredContent = content;
|
||||
if (categoryId) {
|
||||
filteredContent = content.filter((item: any) => Number(item.category_id) === categoryId);
|
||||
} else {
|
||||
// Filter nothing (all items), sort by added
|
||||
// Clone to avoid mutation
|
||||
filteredContent = [...content].sort((a: any, b: any) => {
|
||||
const dateA = parseInt(categoryType === 'series' ? a.last_modified : a.added) || 0;
|
||||
const dateB = parseInt(categoryType === 'series' ? b.last_modified : b.added) || 0;
|
||||
return dateB - dateA;
|
||||
});
|
||||
}
|
||||
|
||||
return filteredContent.slice(startIndex, endIndex);
|
||||
}),
|
||||
|
||||
/**
|
||||
@@ -124,8 +134,6 @@ export function withSelection() {
|
||||
const categoryId = store.selectedCategoryId();
|
||||
const categoryType = store.selectedContentType();
|
||||
|
||||
if (!categoryId) return [];
|
||||
|
||||
// Access parent store content (from withContent)
|
||||
const storeAny = store as any;
|
||||
const content =
|
||||
@@ -135,6 +143,15 @@ export function withSelection() {
|
||||
? storeAny.vodStreams?.() || []
|
||||
: storeAny.serialStreams?.() || [];
|
||||
|
||||
if (!categoryId) {
|
||||
// Return all items sorted by added
|
||||
return [...content].sort((a: any, b: any) => {
|
||||
const dateA = parseInt(categoryType === 'series' ? a.last_modified : a.added) || 0;
|
||||
const dateB = parseInt(categoryType === 'series' ? b.last_modified : b.added) || 0;
|
||||
return dateB - dateA;
|
||||
});
|
||||
}
|
||||
|
||||
return content.filter(
|
||||
(item: any) => Number(item.category_id) === categoryId
|
||||
);
|
||||
@@ -145,8 +162,6 @@ export function withSelection() {
|
||||
*/
|
||||
getTotalPages: computed(() => {
|
||||
const categoryId = store.selectedCategoryId();
|
||||
if (!categoryId) return 0;
|
||||
|
||||
const categoryType = store.selectedContentType();
|
||||
|
||||
// Access parent store content (from withContent)
|
||||
@@ -158,9 +173,14 @@ export function withSelection() {
|
||||
? storeAny.vodStreams?.() || []
|
||||
: storeAny.serialStreams?.() || [];
|
||||
|
||||
const totalItems = content.filter(
|
||||
(item: any) => Number(item.category_id) === categoryId
|
||||
).length;
|
||||
let totalItems = 0;
|
||||
if (categoryId) {
|
||||
totalItems = content.filter(
|
||||
(item: any) => Number(item.category_id) === categoryId
|
||||
).length;
|
||||
} else {
|
||||
totalItems = content.length;
|
||||
}
|
||||
|
||||
return Math.ceil(totalItems / store.limit());
|
||||
}),
|
||||
@@ -230,9 +250,9 @@ export function withSelection() {
|
||||
/**
|
||||
* Set the selected category
|
||||
*/
|
||||
setSelectedCategory(categoryId: number): void {
|
||||
setSelectedCategory(categoryId: number | null): void {
|
||||
patchState(store, {
|
||||
selectedCategoryId: Number(categoryId),
|
||||
selectedCategoryId: categoryId !== null ? Number(categoryId) : null,
|
||||
page: 0,
|
||||
});
|
||||
},
|
||||
|
||||
Reference in new issue
Block a user