diff --git a/frontend/src/Indexer/Index/Table/IndexerIndexRow.css b/frontend/src/Indexer/Index/Table/IndexerIndexRow.css index 308b87cc7..04ff1dba4 100644 --- a/frontend/src/Indexer/Index/Table/IndexerIndexRow.css +++ b/frontend/src/Indexer/Index/Table/IndexerIndexRow.css @@ -37,10 +37,11 @@ flex: 0 0 350px; } -.added { +.added, +.vipExpiration { composes: cell; - flex: 0 0 100px; + flex: 0 0 125px; } .tags { diff --git a/frontend/src/Indexer/Index/Table/IndexerIndexRow.css.d.ts b/frontend/src/Indexer/Index/Table/IndexerIndexRow.css.d.ts index 87006f2cd..89c648d39 100644 --- a/frontend/src/Indexer/Index/Table/IndexerIndexRow.css.d.ts +++ b/frontend/src/Indexer/Index/Table/IndexerIndexRow.css.d.ts @@ -14,6 +14,7 @@ interface CssExports { 'sortName': string; 'status': string; 'tags': string; + 'vipExpiration': string; } export const cssExports: CssExports; export default cssExports; diff --git a/frontend/src/Indexer/Index/Table/IndexerIndexRow.tsx b/frontend/src/Indexer/Index/Table/IndexerIndexRow.tsx index 95d75a758..365e14ced 100644 --- a/frontend/src/Indexer/Index/Table/IndexerIndexRow.tsx +++ b/frontend/src/Indexer/Index/Table/IndexerIndexRow.tsx @@ -54,6 +54,9 @@ function IndexerIndexRow(props: IndexerIndexRowProps) { fields.find((field) => field.name === 'baseUrl')?.value ?? (Array.isArray(indexerUrls) ? indexerUrls[0] : undefined); + const vipExpiration = + fields.find((field) => field.name === 'vipExpiration')?.value ?? ''; + const rssUrl = `${window.location.origin}${window.Prowlarr.urlBase}/${id}/api?t=search&extended=1&apikey=${window.Prowlarr.apiKey}`; const [isEditIndexerModalOpen, setIsEditIndexerModalOpen] = useState(false); @@ -187,6 +190,17 @@ function IndexerIndexRow(props: IndexerIndexRowProps) { ); } + if (name === 'vipExpiration') { + return ( + + ); + } + if (name === 'tags') { return ( diff --git a/frontend/src/Indexer/Index/Table/IndexerIndexTableHeader.css b/frontend/src/Indexer/Index/Table/IndexerIndexTableHeader.css index 78de9be14..b9a3454c8 100644 --- a/frontend/src/Indexer/Index/Table/IndexerIndexTableHeader.css +++ b/frontend/src/Indexer/Index/Table/IndexerIndexTableHeader.css @@ -30,10 +30,11 @@ flex: 0 0 350px; } -.added { +.added, +.vipExpiration { composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css'; - flex: 0 0 100px; + flex: 0 0 125px; } .tags { diff --git a/frontend/src/Indexer/Index/Table/IndexerIndexTableHeader.css.d.ts b/frontend/src/Indexer/Index/Table/IndexerIndexTableHeader.css.d.ts index bcdd035a5..af022da85 100644 --- a/frontend/src/Indexer/Index/Table/IndexerIndexTableHeader.css.d.ts +++ b/frontend/src/Indexer/Index/Table/IndexerIndexTableHeader.css.d.ts @@ -11,6 +11,7 @@ interface CssExports { 'sortName': string; 'status': string; 'tags': string; + 'vipExpiration': string; } export const cssExports: CssExports; export default cssExports; diff --git a/frontend/src/Indexer/Info/IndexerInfoModalContent.tsx b/frontend/src/Indexer/Info/IndexerInfoModalContent.tsx index 662cb7934..4ab8621b3 100644 --- a/frontend/src/Indexer/Info/IndexerInfoModalContent.tsx +++ b/frontend/src/Indexer/Info/IndexerInfoModalContent.tsx @@ -60,6 +60,9 @@ function IndexerInfoModalContent(props: IndexerInfoModalContentProps) { fields.find((field) => field.name === 'baseUrl')?.value ?? (Array.isArray(indexerUrls) ? indexerUrls[0] : undefined); + const vipExpiration = + fields.find((field) => field.name === 'vipExpiration')?.value ?? undefined; + const [isEditIndexerModalOpen, setIsEditIndexerModalOpen] = useState(false); const [isDeleteIndexerModalOpen, setIsDeleteIndexerModalOpen] = useState(false); @@ -110,6 +113,13 @@ function IndexerInfoModalContent(props: IndexerInfoModalContentProps) { title={translate('Language')} data={language ?? '-'} /> + {vipExpiration ? ( + + ) : null} {translate('IndexerSite')} diff --git a/frontend/src/Store/Actions/indexerActions.js b/frontend/src/Store/Actions/indexerActions.js index fdc0b8fb1..a30d6a73a 100644 --- a/frontend/src/Store/Actions/indexerActions.js +++ b/frontend/src/Store/Actions/indexerActions.js @@ -58,10 +58,24 @@ export const filters = [ export const filterPredicates = { added: function(item, filterValue, type) { return dateFilterPredicate(item.added, filterValue, type); + }, + + vipExpiration: function(item, filterValue, type) { + const vipExpiration = + item.fields.find((field) => field.name === 'vipExpiration')?.value ?? null; + + return dateFilterPredicate(vipExpiration, filterValue, type); } }; -export const sortPredicates = {}; +export const sortPredicates = { + vipExpiration: function(item) { + const vipExpiration = + item.fields.find((field) => field.name === 'vipExpiration')?.value ?? ''; + + return vipExpiration; + } +}; // // Actions Types diff --git a/frontend/src/Store/Actions/indexerIndexActions.js b/frontend/src/Store/Actions/indexerIndexActions.js index 0d7dc028a..cb0d0b480 100644 --- a/frontend/src/Store/Actions/indexerIndexActions.js +++ b/frontend/src/Store/Actions/indexerIndexActions.js @@ -78,6 +78,12 @@ export const defaultState = { isSortable: true, isVisible: true }, + { + name: 'vipExpiration', + label: translate('VipExpiration'), + isSortable: true, + isVisible: false + }, { name: 'capabilities', label: translate('Categories'), @@ -125,6 +131,12 @@ export const defaultState = { type: filterBuilderTypes.DATE, valueType: filterBuilderValueTypes.DATE }, + { + name: 'vipExpiration', + label: translate('VipExpiration'), + type: filterBuilderTypes.DATE, + valueType: filterBuilderValueTypes.DATE + }, { name: 'priority', label: translate('Priority'), diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index e53067a09..336bd7883 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -472,6 +472,7 @@ "Username": "Username", "Version": "Version", "View": "View", + "VipExpiration": "VIP Expiration", "Warn": "Warn", "Website": "Website", "Wiki": "Wiki",