mirror of
https://github.com/Cleanuparr/Cleanuparr.git
synced 2025-12-23 22:18:39 -05:00
Fix download client type being sent as number instead of string (#245)
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
public enum DownloadClientTypeName
|
||||
{
|
||||
QBittorrent,
|
||||
qBittorrent,
|
||||
Deluge,
|
||||
Transmission,
|
||||
}
|
||||
@@ -46,7 +46,7 @@ public sealed class DownloadServiceFactory
|
||||
|
||||
return downloadClientConfig.TypeName switch
|
||||
{
|
||||
DownloadClientTypeName.QBittorrent => CreateQBitService(downloadClientConfig),
|
||||
DownloadClientTypeName.qBittorrent => CreateQBitService(downloadClientConfig),
|
||||
DownloadClientTypeName.Deluge => CreateDelugeService(downloadClientConfig),
|
||||
DownloadClientTypeName.Transmission => CreateTransmissionService(downloadClientConfig),
|
||||
_ => throw new NotSupportedException($"Download client type {downloadClientConfig.TypeName} is not supported")
|
||||
|
||||
@@ -84,7 +84,7 @@ export class DocumentationService {
|
||||
'download-client': {
|
||||
'enabled': 'enable-download-client',
|
||||
'name': 'client-name',
|
||||
'type': 'client-type',
|
||||
'typeName': 'client-type',
|
||||
'host': 'client-host',
|
||||
'urlBase': 'url-base-path',
|
||||
'username': 'username',
|
||||
|
||||
@@ -147,21 +147,21 @@
|
||||
<div class="field">
|
||||
<label for="client-type">
|
||||
<i class="pi pi-info-circle field-info-icon"
|
||||
(click)="openFieldDocs('type')"
|
||||
(click)="openFieldDocs('typeName')"
|
||||
pTooltip="Click for documentation"></i>
|
||||
Client Type *
|
||||
</label>
|
||||
<p-select
|
||||
id="client-type"
|
||||
formControlName="type"
|
||||
[options]="clientTypeOptions"
|
||||
formControlName="typeName"
|
||||
[options]="typeNameOptions"
|
||||
optionLabel="label"
|
||||
optionValue="value"
|
||||
placeholder="Select client type"
|
||||
appendTo="body"
|
||||
class="w-full"
|
||||
></p-select>
|
||||
<small *ngIf="hasError(clientForm, 'type', 'required')" class="p-error">Client type is required</small>
|
||||
<small *ngIf="hasError(clientForm, 'typeName', 'required')" class="p-error">Client type is required</small>
|
||||
</div>
|
||||
|
||||
<ng-container>
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Subject, takeUntil } from "rxjs";
|
||||
import { DownloadClientConfigStore } from "./download-client-config.store";
|
||||
import { CanComponentDeactivate } from "../../core/guards";
|
||||
import { ClientConfig, DownloadClientConfig, CreateDownloadClientDto } from "../../shared/models/download-client-config.model";
|
||||
import { DownloadClientType } from "../../shared/models/enums";
|
||||
import { DownloadClientType, DownloadClientTypeName } from "../../shared/models/enums";
|
||||
import { DocumentationService } from "../../core/services/documentation.service";
|
||||
|
||||
// PrimeNG Components
|
||||
@@ -56,11 +56,7 @@ export class DownloadClientSettingsComponent implements OnDestroy, CanComponentD
|
||||
editingClient: ClientConfig | null = null;
|
||||
|
||||
// Download client type options
|
||||
clientTypeOptions = [
|
||||
{ label: "qBittorrent", value: DownloadClientType.QBittorrent },
|
||||
{ label: "Deluge", value: DownloadClientType.Deluge },
|
||||
{ label: "Transmission", value: DownloadClientType.Transmission },
|
||||
];
|
||||
typeNameOptions: { label: string, value: DownloadClientTypeName }[] = [];
|
||||
|
||||
// Clean up subscriptions
|
||||
private destroy$ = new Subject<void>();
|
||||
@@ -89,7 +85,7 @@ export class DownloadClientSettingsComponent implements OnDestroy, CanComponentD
|
||||
// Initialize client form for modal
|
||||
this.clientForm = this.formBuilder.group({
|
||||
name: ['', Validators.required],
|
||||
type: [null, Validators.required],
|
||||
typeName: [null, Validators.required],
|
||||
host: ['', [Validators.required, this.uriValidator.bind(this)]],
|
||||
username: [''],
|
||||
password: [''],
|
||||
@@ -97,11 +93,19 @@ export class DownloadClientSettingsComponent implements OnDestroy, CanComponentD
|
||||
enabled: [true]
|
||||
});
|
||||
|
||||
// Initialize type name options
|
||||
for (const key of Object.keys(DownloadClientTypeName)) {
|
||||
this.typeNameOptions.push({
|
||||
label: key,
|
||||
value: DownloadClientTypeName[key as keyof typeof DownloadClientTypeName]
|
||||
});
|
||||
}
|
||||
|
||||
// Load Download Client config data
|
||||
this.downloadClientStore.loadConfig();
|
||||
|
||||
// Setup client type change handler
|
||||
this.clientForm.get('type')?.valueChanges
|
||||
this.clientForm.get('typeName')?.valueChanges
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe(() => {
|
||||
this.onClientTypeChange();
|
||||
@@ -184,14 +188,9 @@ export class DownloadClientSettingsComponent implements OnDestroy, CanComponentD
|
||||
this.modalMode = 'edit';
|
||||
this.editingClient = client;
|
||||
|
||||
// Map backend type to frontend type
|
||||
const frontendType = client.typeName
|
||||
? this.mapClientTypeFromBackend(client.typeName)
|
||||
: client.type;
|
||||
|
||||
this.clientForm.patchValue({
|
||||
name: client.name,
|
||||
type: frontendType,
|
||||
typeName: client.typeName,
|
||||
host: client.host,
|
||||
username: client.username,
|
||||
password: client.password,
|
||||
@@ -222,28 +221,27 @@ export class DownloadClientSettingsComponent implements OnDestroy, CanComponentD
|
||||
}
|
||||
|
||||
const formValue = this.clientForm.value;
|
||||
const mappedType = this.mapClientTypeForBackend(formValue.type);
|
||||
|
||||
const clientData: CreateDownloadClientDto = {
|
||||
name: formValue.name,
|
||||
typeName: mappedType.typeName,
|
||||
type: mappedType.type,
|
||||
host: formValue.host,
|
||||
username: formValue.username,
|
||||
password: formValue.password,
|
||||
urlBase: formValue.urlBase,
|
||||
enabled: formValue.enabled
|
||||
};
|
||||
|
||||
if (this.modalMode === 'add') {
|
||||
const clientData: CreateDownloadClientDto = {
|
||||
name: formValue.name,
|
||||
type: this.mapTypeNameToType(formValue.typeName),
|
||||
typeName: formValue.typeName,
|
||||
host: formValue.host,
|
||||
username: formValue.username,
|
||||
password: formValue.password,
|
||||
urlBase: formValue.urlBase,
|
||||
enabled: formValue.enabled
|
||||
};
|
||||
|
||||
this.downloadClientStore.createClient(clientData);
|
||||
} else if (this.editingClient) {
|
||||
// For updates, create a proper ClientConfig object
|
||||
const clientConfig: ClientConfig = {
|
||||
id: this.editingClient.id!,
|
||||
id: this.editingClient.id,
|
||||
name: formValue.name,
|
||||
type: formValue.type, // Keep the frontend enum type
|
||||
typeName: mappedType.typeName,
|
||||
type: this.mapTypeNameToType(formValue.typeName),
|
||||
typeName: formValue.typeName,
|
||||
host: formValue.host,
|
||||
username: formValue.username,
|
||||
password: formValue.password,
|
||||
@@ -325,42 +323,24 @@ export class DownloadClientSettingsComponent implements OnDestroy, CanComponentD
|
||||
}
|
||||
|
||||
/**
|
||||
* Map frontend client type to backend TypeName and Type
|
||||
* Map typeName to type category
|
||||
*/
|
||||
private mapClientTypeForBackend(frontendType: DownloadClientType): { typeName: string, type: string } {
|
||||
switch (frontendType) {
|
||||
case DownloadClientType.QBittorrent:
|
||||
return { typeName: 'qBittorrent', type: 'Torrent' };
|
||||
case DownloadClientType.Deluge:
|
||||
return { typeName: 'Deluge', type: 'Torrent' };
|
||||
case DownloadClientType.Transmission:
|
||||
return { typeName: 'Transmission', type: 'Torrent' };
|
||||
private mapTypeNameToType(typeName: DownloadClientTypeName): DownloadClientType {
|
||||
switch (typeName) {
|
||||
case DownloadClientTypeName.qBittorrent:
|
||||
case DownloadClientTypeName.Deluge:
|
||||
case DownloadClientTypeName.Transmission:
|
||||
return DownloadClientType.Torrent;
|
||||
default:
|
||||
return { typeName: 'QBittorrent', type: 'Torrent' };
|
||||
throw new Error(`Unknown client type name: ${typeName}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Map backend TypeName to frontend client type
|
||||
*/
|
||||
private mapClientTypeFromBackend(backendTypeName: string): DownloadClientType {
|
||||
switch (backendTypeName) {
|
||||
case 'QBittorrent':
|
||||
return DownloadClientType.QBittorrent;
|
||||
case 'Deluge':
|
||||
return DownloadClientType.Deluge;
|
||||
case 'Transmission':
|
||||
return DownloadClientType.Transmission;
|
||||
default:
|
||||
return DownloadClientType.QBittorrent;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle client type changes to update validation
|
||||
*/
|
||||
onClientTypeChange(): void {
|
||||
const clientType = this.clientForm.get('type')?.value;
|
||||
const clientTypeName = this.clientForm.get('typeName')?.value;
|
||||
const hostControl = this.clientForm.get('host');
|
||||
const usernameControl = this.clientForm.get('username');
|
||||
const urlBaseControl = this.clientForm.get('urlBase');
|
||||
@@ -373,13 +353,13 @@ export class DownloadClientSettingsComponent implements OnDestroy, CanComponentD
|
||||
]);
|
||||
|
||||
// Clear username value and remove validation for Deluge
|
||||
if (clientType === DownloadClientType.Deluge) {
|
||||
if (clientTypeName === DownloadClientTypeName.Deluge) {
|
||||
usernameControl.setValue('');
|
||||
usernameControl.clearValidators();
|
||||
}
|
||||
|
||||
// Set default URL base for Transmission
|
||||
if (clientType === DownloadClientType.Transmission) {
|
||||
if (clientTypeName === DownloadClientTypeName.Transmission) {
|
||||
urlBaseControl.setValue('transmission');
|
||||
}
|
||||
|
||||
@@ -392,19 +372,15 @@ export class DownloadClientSettingsComponent implements OnDestroy, CanComponentD
|
||||
* Check if username field should be shown (hidden for Deluge)
|
||||
*/
|
||||
shouldShowUsernameField(): boolean {
|
||||
const clientType = this.clientForm.get('type')?.value;
|
||||
return clientType !== DownloadClientType.Deluge;
|
||||
const clientTypeName = this.clientForm.get('typeName')?.value;
|
||||
return clientTypeName !== DownloadClientTypeName.Deluge;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get client type label for display
|
||||
*/
|
||||
getClientTypeLabel(client: ClientConfig): string {
|
||||
const frontendType = client.typeName
|
||||
? this.mapClientTypeFromBackend(client.typeName)
|
||||
: client.type;
|
||||
|
||||
const option = this.clientTypeOptions.find(opt => opt.value === frontendType);
|
||||
const option = this.typeNameOptions.find(opt => opt.value === client.typeName);
|
||||
return option?.label || 'Unknown';
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { DownloadClientType } from './enums';
|
||||
import { DownloadClientType, DownloadClientTypeName } from './enums';
|
||||
|
||||
/**
|
||||
* Represents a download client configuration object
|
||||
@@ -37,7 +37,7 @@ export interface ClientConfig {
|
||||
/**
|
||||
* Type name of download client (backend enum)
|
||||
*/
|
||||
typeName?: string;
|
||||
typeName: DownloadClientTypeName;
|
||||
|
||||
/**
|
||||
* Host address for the download client
|
||||
@@ -73,16 +73,16 @@ export interface CreateDownloadClientDto {
|
||||
* Friendly name for this client
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* Type of download client (backend enum)
|
||||
*/
|
||||
type: DownloadClientType;
|
||||
|
||||
/**
|
||||
* Type name of download client (backend enum)
|
||||
*/
|
||||
typeName: string;
|
||||
|
||||
/**
|
||||
* Type of download client (backend enum)
|
||||
*/
|
||||
type: string;
|
||||
typeName: DownloadClientTypeName;
|
||||
|
||||
/**
|
||||
* Host address for the download client
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
/**
|
||||
* Download client type enum matching backend DownloadClientType
|
||||
*/
|
||||
export enum DownloadClientType {
|
||||
QBittorrent = 0,
|
||||
Deluge = 1,
|
||||
Transmission = 2,
|
||||
Torrent = "Torrent",
|
||||
Usenet = "Usenet",
|
||||
}
|
||||
|
||||
export enum DownloadClientTypeName {
|
||||
qBittorrent = "qBittorrent",
|
||||
Deluge = "Deluge",
|
||||
Transmission = "Transmission",
|
||||
}
|
||||
Reference in New Issue
Block a user