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",