Browse Source

Feature/add data gathering toggle to asset profile details dialog (#4497)

* Add data gathering toggle to asset profile details dialog

* Update changelog
pull/4511/head
Tobias Kugel 1 week ago
committed by GitHub
parent
commit
57748a18ef
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 4
      CHANGELOG.md
  2. 2
      apps/api/src/app/admin/admin.service.ts
  3. 5
      apps/api/src/app/admin/update-asset-profile.dto.ts
  4. 1
      apps/api/src/app/import/import.service.ts
  5. 6
      apps/api/src/app/order/create-order.dto.ts
  6. 1
      apps/api/src/app/portfolio/calculator/portfolio-calculator-test-utils.ts
  7. 18
      apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts
  8. 12
      apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html
  9. 2
      apps/client/src/app/services/admin.service.ts
  10. 1
      libs/common/src/lib/interfaces/enhanced-symbol-profile.interface.ts

4
CHANGELOG.md

@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased ## Unreleased
### Added
- Added support to toggle the data gathering for individual asset profiles in the asset profile details dialog of the admin control panel
### Changed ### Changed
- Improved the check for duplicates in the preview step of the activities import (allow different comments) - Improved the check for duplicates in the preview step of the activities import (allow different comments)

2
apps/api/src/app/admin/admin.service.ts

@ -480,6 +480,7 @@ export class AdminService {
currency, currency,
dataSource: newDataSource, dataSource: newDataSource,
holdings, holdings,
isActive,
name, name,
scraperConfiguration, scraperConfiguration,
sectors, sectors,
@ -557,6 +558,7 @@ export class AdminService {
currency, currency,
dataSource, dataSource,
holdings, holdings,
isActive,
scraperConfiguration, scraperConfiguration,
sectors, sectors,
symbol, symbol,

5
apps/api/src/app/admin/update-asset-profile.dto.ts

@ -3,6 +3,7 @@ import { IsCurrencyCode } from '@ghostfolio/api/validators/is-currency-code';
import { AssetClass, AssetSubClass, DataSource, Prisma } from '@prisma/client'; import { AssetClass, AssetSubClass, DataSource, Prisma } from '@prisma/client';
import { import {
IsArray, IsArray,
IsBoolean,
IsEnum, IsEnum,
IsObject, IsObject,
IsOptional, IsOptional,
@ -35,6 +36,10 @@ export class UpdateAssetProfileDto {
@IsOptional() @IsOptional()
dataSource?: DataSource; dataSource?: DataSource;
@IsBoolean()
@IsOptional()
isActive?: boolean;
@IsOptional() @IsOptional()
@IsString() @IsString()
name?: string; name?: string;

1
apps/api/src/app/import/import.service.ts

@ -555,6 +555,7 @@ export class ImportService {
createdAt: undefined, createdAt: undefined,
holdings: undefined, holdings: undefined,
id: undefined, id: undefined,
isActive: true,
sectors: undefined, sectors: undefined,
updatedAt: undefined updatedAt: undefined
} }

6
apps/api/src/app/order/create-order.dto.ts

@ -27,12 +27,12 @@ export class CreateOrderDto {
@IsString() @IsString()
accountId?: string; accountId?: string;
@IsOptional()
@IsEnum(AssetClass, { each: true }) @IsEnum(AssetClass, { each: true })
@IsOptional()
assetClass?: AssetClass; assetClass?: AssetClass;
@IsOptional()
@IsEnum(AssetSubClass, { each: true }) @IsEnum(AssetSubClass, { each: true })
@IsOptional()
assetSubClass?: AssetSubClass; assetSubClass?: AssetSubClass;
@IsOptional() @IsOptional()
@ -49,8 +49,8 @@ export class CreateOrderDto {
@IsOptional() @IsOptional()
customCurrency?: string; customCurrency?: string;
@IsOptional()
@IsEnum(DataSource, { each: true }) @IsEnum(DataSource, { each: true })
@IsOptional()
dataSource?: DataSource; dataSource?: DataSource;
@IsISO8601() @IsISO8601()

1
apps/api/src/app/portfolio/calculator/portfolio-calculator-test-utils.ts

@ -24,6 +24,7 @@ export const symbolProfileDummyData = {
createdAt: undefined, createdAt: undefined,
holdings: [], holdings: [],
id: undefined, id: undefined,
isActive: true,
sectors: [], sectors: [],
updatedAt: undefined updatedAt: undefined
}; };

18
apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts

@ -34,6 +34,7 @@ import {
ValidationErrors, ValidationErrors,
Validators Validators
} from '@angular/forms'; } from '@angular/forms';
import { MatCheckboxChange } from '@angular/material/checkbox';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { MatSnackBar } from '@angular/material/snack-bar'; import { MatSnackBar } from '@angular/material/snack-bar';
import { import {
@ -88,6 +89,7 @@ export class AssetProfileDialog implements OnDestroy, OnInit {
historicalData: this.formBuilder.group({ historicalData: this.formBuilder.group({
csvString: '' csvString: ''
}), }),
isActive: [true],
name: ['', Validators.required], name: ['', Validators.required],
scraperConfiguration: this.formBuilder.group({ scraperConfiguration: this.formBuilder.group({
defaultMarketPrice: null, defaultMarketPrice: null,
@ -254,6 +256,7 @@ export class AssetProfileDialog implements OnDestroy, OnInit {
historicalData: { historicalData: {
csvString: AssetProfileDialog.HISTORICAL_DATA_TEMPLATE csvString: AssetProfileDialog.HISTORICAL_DATA_TEMPLATE
}, },
isActive: this.assetProfile?.isActive,
name: this.assetProfile.name ?? this.assetProfile.symbol, name: this.assetProfile.name ?? this.assetProfile.symbol,
scraperConfiguration: { scraperConfiguration: {
defaultMarketPrice: defaultMarketPrice:
@ -395,6 +398,7 @@ export class AssetProfileDialog implements OnDestroy, OnInit {
assetSubClass: this.assetProfileForm.get('assetSubClass').value, assetSubClass: this.assetProfileForm.get('assetSubClass').value,
comment: this.assetProfileForm.get('comment').value || null, comment: this.assetProfileForm.get('comment').value || null,
currency: this.assetProfileForm.get('currency').value, currency: this.assetProfileForm.get('currency').value,
isActive: this.assetProfileForm.get('isActive').value,
name: this.assetProfileForm.get('name').value, name: this.assetProfileForm.get('name').value,
url: this.assetProfileForm.get('url').value || null url: this.assetProfileForm.get('url').value || null
}; };
@ -538,6 +542,20 @@ export class AssetProfileDialog implements OnDestroy, OnInit {
}); });
} }
public onToggleIsActive({ checked }: MatCheckboxChange) {
if (checked) {
this.assetProfileForm.get('isActive')?.setValue(true);
} else {
this.assetProfileForm.get('isActive')?.setValue(false);
}
if (checked === this.assetProfile.isActive) {
this.assetProfileForm.get('isActive')?.markAsPristine();
} else {
this.assetProfileForm.get('isActive')?.markAsDirty();
}
}
public onUnsetBenchmark({ dataSource, symbol }: AssetProfileIdentifier) { public onUnsetBenchmark({ dataSource, symbol }: AssetProfileIdentifier) {
this.dataService this.dataService
.deleteBenchmark({ dataSource, symbol }) .deleteBenchmark({ dataSource, symbol })

12
apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html

@ -512,7 +512,17 @@
</form> </form>
</div> </div>
<div class="d-flex justify-content-end" mat-dialog-actions> <div class="d-flex" mat-dialog-actions>
<div class="gf-spacer">
<mat-checkbox
color="primary"
[checked]="assetProfile?.isActive ?? false"
[disabled]="isEditAssetProfileIdentifierMode"
(change)="onToggleIsActive($event)"
>
<ng-container i18n>Data Gathering</ng-container>
</mat-checkbox>
</div>
<button i18n mat-button type="button" (click)="onClose()">Cancel</button> <button i18n mat-button type="button" (click)="onClose()">Cancel</button>
<button <button
color="primary" color="primary"

2
apps/client/src/app/services/admin.service.ts

@ -212,6 +212,7 @@ export class AdminService {
countries, countries,
currency, currency,
dataSource: newDataSource, dataSource: newDataSource,
isActive,
name, name,
scraperConfiguration, scraperConfiguration,
sectors, sectors,
@ -229,6 +230,7 @@ export class AdminService {
countries, countries,
currency, currency,
dataSource: newDataSource, dataSource: newDataSource,
isActive,
name, name,
scraperConfiguration, scraperConfiguration,
sectors, sectors,

1
libs/common/src/lib/interfaces/enhanced-symbol-profile.interface.ts

@ -22,6 +22,7 @@ export interface EnhancedSymbolProfile {
figiShareClass?: string; figiShareClass?: string;
holdings: Holding[]; holdings: Holding[];
id: string; id: string;
isActive: boolean;
isin?: string; isin?: string;
name?: string; name?: string;
scraperConfiguration?: ScraperConfiguration; scraperConfiguration?: ScraperConfiguration;

Loading…
Cancel
Save