mirror of
https://github.com/Cleanuparr/Cleanuparr.git
synced 2026-10-28 02:38:55 -04:00
added cycle completed notification toggle
This commit is contained in:
1 parent
12fa674246
commit
2717fcabdb
14 files changed
+50
No files matched your search
@@ -59,4 +59,5 @@ export const NEW_FEATURES: NewFeature[] = [
|
||||
{ id: 'seeker-search-specials' },
|
||||
{ id: 'seeker-search-anime' },
|
||||
{ id: 'seeker-reset-cycle' },
|
||||
{ id: 'seeker-cycle-notification' },
|
||||
];
|
||||
@@ -156,6 +156,7 @@ export class DocumentationService {
|
||||
'onSearchItemGrabbed': 'event-configuration',
|
||||
'onForceImported': 'event-configuration',
|
||||
'onErroredStrike': 'event-configuration',
|
||||
'onSeekerCycleCompleted': 'event-configuration',
|
||||
},
|
||||
'notifications/notifiarr': {
|
||||
'apiKey': 'api-key',
|
||||
|
||||
@@ -33,6 +33,7 @@ const TYPE_COLORS: Record<string, string> = {
|
||||
[EventType.DownloadCleaned]: '#22c55e',
|
||||
[EventType.DownloadStopped]: '#6366f1',
|
||||
[EventType.StrikeReset]: '#10b981',
|
||||
[EventType.SeekerCycleCompleted]: '#a855f7',
|
||||
};
|
||||
|
||||
const FALLBACK_COLOR = '#94a3b8';
|
||||
|
||||
+4
@@ -220,6 +220,10 @@
|
||||
<app-toggle label="Errored Strike" [formField]="modalForm.onErroredStrike"
|
||||
hint="Notify when an errored download strike occurs"
|
||||
helpKey="notifications:onErroredStrike" />
|
||||
<app-toggle label="Seeker Cycle Completed" [formField]="modalForm.onSeekerCycleCompleted"
|
||||
hint="Notify when Seeker has searched every eligible item on an instance once"
|
||||
helpKey="notifications:onSeekerCycleCompleted"
|
||||
featureId="seeker-cycle-notification" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+26
@@ -26,6 +26,7 @@ const DEFAULT_EVENTS = {
|
||||
onSearchItemGrabbed: false,
|
||||
onForceImported: false,
|
||||
onErroredStrike: false,
|
||||
onSeekerCycleCompleted: false,
|
||||
};
|
||||
|
||||
const NTFY_PROVIDER: NotificationProviderDto = {
|
||||
@@ -45,6 +46,7 @@ const NTFY_PROVIDER: NotificationProviderDto = {
|
||||
onSearchItemGrabbed: true,
|
||||
onForceImported: false,
|
||||
onErroredStrike: false,
|
||||
onSeekerCycleCompleted: false,
|
||||
},
|
||||
configuration: {
|
||||
serverUrl: 'https://ntfy.example.com',
|
||||
@@ -690,6 +692,30 @@ describe('NotificationProviderModalComponent', () => {
|
||||
expect(onSaved).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('renders the Seeker Cycle Completed toggle and sends its value on save', () => {
|
||||
const { fixture, component, api } = setup({ initialType: NotificationProviderType.Discord });
|
||||
|
||||
const toggle = fixture.nativeElement.querySelector(
|
||||
'.event-flags button[aria-label="Seeker Cycle Completed"]',
|
||||
) as HTMLButtonElement;
|
||||
expect(toggle).not.toBeNull();
|
||||
expect(toggle.getAttribute('aria-checked')).toBe('false');
|
||||
|
||||
toggle.click();
|
||||
fixture.detectChanges();
|
||||
expect(toggle.getAttribute('aria-checked')).toBe('true');
|
||||
expect(component.modalModel().onSeekerCycleCompleted).toBe(true);
|
||||
|
||||
component.modalModel.update((m) => ({ ...m, name: 'Alerts', webhookUrl: 'https://discord.com/hook' }));
|
||||
component.saveProvider();
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(api.create).toHaveBeenCalledWith(
|
||||
NOTIFICATION_PROVIDER_DESCRIPTORS[NotificationProviderType.Discord],
|
||||
expect.objectContaining({ onSeekerCycleCompleted: true }),
|
||||
);
|
||||
});
|
||||
|
||||
it('updates an existing ntfy provider with the loaded configuration', () => {
|
||||
const { fixture, component, api, toast, onSaved } = setup({ editingProvider: NTFY_PROVIDER });
|
||||
|
||||
|
||||
+2
@@ -65,6 +65,7 @@ function createDefaultModalModel(): NotificationProviderFormModel {
|
||||
onFailedImportStrike: false, onStalledStrike: false, onSlowStrike: false, onQueueItemDeleted: false,
|
||||
onDownloadCleaned: false, onDownloadStopped: false, onCategoryChanged: false, onSearchTriggered: false, onSearchItemGrabbed: false, onForceImported: false,
|
||||
onErroredStrike: false,
|
||||
onSeekerCycleCompleted: false,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -358,6 +359,7 @@ export class NotificationProviderModalComponent {
|
||||
model.onSearchItemGrabbed = provider.events.onSearchItemGrabbed;
|
||||
model.onForceImported = provider.events.onForceImported;
|
||||
model.onErroredStrike = provider.events.onErroredStrike;
|
||||
model.onSeekerCycleCompleted = provider.events.onSeekerCycleCompleted;
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
@@ -68,6 +68,9 @@
|
||||
@if (provider.events.onSearchItemGrabbed) {
|
||||
<span class="event-tag">Search Item Grabbed</span>
|
||||
}
|
||||
@if (provider.events.onSeekerCycleCompleted) {
|
||||
<span class="event-tag">Seeker Cycle Completed</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
} @empty {
|
||||
|
||||
@@ -27,6 +27,7 @@ const DISCORD_PROVIDER: NotificationProviderDto = {
|
||||
onSearchItemGrabbed: false,
|
||||
onForceImported: false,
|
||||
onErroredStrike: false,
|
||||
onSeekerCycleCompleted: false,
|
||||
},
|
||||
configuration: { webhookUrl: 'https://discord.com/api/webhooks/abc' },
|
||||
};
|
||||
@@ -48,6 +49,7 @@ const TELEGRAM_PROVIDER: NotificationProviderDto = {
|
||||
onSearchItemGrabbed: false,
|
||||
onForceImported: false,
|
||||
onErroredStrike: false,
|
||||
onSeekerCycleCompleted: false,
|
||||
},
|
||||
configuration: { botToken: 'token', chatId: '-100' },
|
||||
};
|
||||
|
||||
@@ -206,4 +206,5 @@ export enum EventType {
|
||||
StrikeReset = 'StrikeReset',
|
||||
ForceImported = 'ForceImported',
|
||||
DownloadStopped = 'DownloadStopped',
|
||||
SeekerCycleCompleted = 'SeekerCycleCompleted',
|
||||
}
|
||||
@@ -18,6 +18,7 @@ export interface NotificationEventFlags {
|
||||
onSearchItemGrabbed: boolean;
|
||||
onForceImported: boolean;
|
||||
onErroredStrike: boolean;
|
||||
onSeekerCycleCompleted: boolean;
|
||||
}
|
||||
|
||||
export interface NotificationProviderDto {
|
||||
|
||||
@@ -12,6 +12,7 @@ describe('eventTypeSeverity', () => {
|
||||
it.each([
|
||||
[EventType.StrikeReset, 'success'],
|
||||
[EventType.DownloadCleaned, 'success'],
|
||||
[EventType.SeekerCycleCompleted, 'success'],
|
||||
[EventType.FailedImportStrike, 'error'],
|
||||
[EventType.QueueItemDeleted, 'error'],
|
||||
[EventType.StalledStrike, 'warning'],
|
||||
@@ -78,6 +79,7 @@ describe('eventIcon', () => {
|
||||
[EventType.DownloadCleaned, 'tablerDownload'],
|
||||
[EventType.QueueItemDeleted, 'tablerTrash'],
|
||||
[EventType.CategoryChanged, 'tablerTag'],
|
||||
[EventType.SeekerCycleCompleted, 'tablerSearch'],
|
||||
[EventType.DownloadStopped, 'tablerCircle'],
|
||||
])('maps %s to %s', (eventType, expected) => {
|
||||
expect(eventIcon(eventType)).toBe(expected);
|
||||
|
||||
@@ -17,6 +17,7 @@ export function eventTypeSeverity(eventType: string): BadgeSeverity {
|
||||
case EventType.StrikeReset:
|
||||
case EventType.DownloadCleaned:
|
||||
case EventType.ForceImported:
|
||||
case EventType.SeekerCycleCompleted:
|
||||
return 'success';
|
||||
case EventType.FailedImportStrike:
|
||||
case EventType.QueueItemDeleted:
|
||||
@@ -77,6 +78,8 @@ export function eventIcon(eventType: string): string {
|
||||
return 'tablerTrash';
|
||||
case EventType.CategoryChanged:
|
||||
return 'tablerTag';
|
||||
case EventType.SeekerCycleCompleted:
|
||||
return 'tablerSearch';
|
||||
default:
|
||||
return 'tablerCircle';
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ function baseModel(overrides: Partial<NotificationProviderFormModel> = {}): Noti
|
||||
onSearchItemGrabbed: false,
|
||||
onForceImported: false,
|
||||
onErroredStrike: false,
|
||||
onSeekerCycleCompleted: false,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
@@ -72,6 +73,7 @@ const eventFlags = {
|
||||
onSearchItemGrabbed: false,
|
||||
onForceImported: false,
|
||||
onErroredStrike: false,
|
||||
onSeekerCycleCompleted: false,
|
||||
};
|
||||
|
||||
describe('NOTIFICATION_PROVIDER_DESCRIPTORS', () => {
|
||||
|
||||
@@ -88,6 +88,7 @@ function eventFlags(m: NotificationProviderFormModel): NotificationEventFlags {
|
||||
onSearchItemGrabbed: m.onSearchItemGrabbed,
|
||||
onForceImported: m.onForceImported,
|
||||
onErroredStrike: m.onErroredStrike,
|
||||
onSeekerCycleCompleted: m.onSeekerCycleCompleted,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user