Browse Source

Persist tags filter

pull/2838/head
Thomas Kaul 2 years ago
parent
commit
b0e0ca7094
  1. 5
      apps/api/src/app/user/update-user-setting.dto.ts
  2. 1
      apps/client/src/app/components/header/header.component.html
  3. 15
      apps/client/src/app/components/header/header.component.ts
  4. 14
      apps/client/src/app/pages/portfolio/activities/activities-page.component.ts
  5. 1
      libs/common/src/lib/interfaces/user-settings.interface.ts
  6. 11
      libs/ui/src/lib/activities-table-lazy/activities-table-lazy.component.ts
  7. 19
      libs/ui/src/lib/assistant/assistant.component.ts
  8. 16
      libs/ui/src/lib/assistant/assistant.html

5
apps/api/src/app/user/update-user-setting.dto.ts

@ -4,6 +4,7 @@ import type {
ViewMode
} from '@ghostfolio/common/types';
import {
IsArray,
IsBoolean,
IsISO8601,
IsIn,
@ -37,6 +38,10 @@ export class UpdateUserSettingDto {
@IsOptional()
emergencyFund?: number;
@IsArray()
@IsOptional()
'filters.tags'?: string[];
@IsBoolean()
@IsOptional()
isExperimentalFeatures?: boolean;

1
apps/client/src/app/components/header/header.component.html

@ -141,6 +141,7 @@
[user]="user"
(closed)="closeAssistant()"
(dateRangeChanged)="onDateRangeChange($event)"
(selectedTagChanged)="onSelectedTagChanged($event)"
/>
</mat-menu>
</li>

15
apps/client/src/app/components/header/header.component.ts

@ -24,6 +24,7 @@ import { InfoItem, User } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { DateRange } from '@ghostfolio/common/types';
import { AssistantComponent } from '@ghostfolio/ui/assistant/assistant.component';
import { Tag } from '@prisma/client';
import { EMPTY, Subject } from 'rxjs';
import { catchError, takeUntil } from 'rxjs/operators';
@ -173,6 +174,20 @@ export class HeaderComponent implements OnChanges {
this.assistantElement.initialize();
}
public onSelectedTagChanged(tag: Tag) {
this.dataService
.putUserSetting({ 'filters.tags': tag ? [tag.id] : null })
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(() => {
this.userService.remove();
this.userService
.get()
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe();
});
}
public onSignOut() {
this.signOut.next();
}

14
apps/client/src/app/pages/portfolio/activities/activities-page.component.ts

@ -15,7 +15,7 @@ import { ImpersonationStorageService } from '@ghostfolio/client/services/imperso
import { UserService } from '@ghostfolio/client/services/user/user.service';
import { DEFAULT_PAGE_SIZE } from '@ghostfolio/common/config';
import { downloadAsFile } from '@ghostfolio/common/helper';
import { User } from '@ghostfolio/common/interfaces';
import { Filter, User } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { DataSource, Order as OrderModel } from '@prisma/client';
import { format, parseISO } from 'date-fns';
@ -111,6 +111,8 @@ export class ActivitiesPageComponent implements OnDestroy, OnInit {
if (state?.user) {
this.updateUser(state.user);
this.fetchActivities();
this.changeDetectorRef.markForCheck();
}
});
@ -120,8 +122,18 @@ export class ActivitiesPageComponent implements OnDestroy, OnInit {
public fetchActivities() {
if (this.user?.settings?.isExperimentalFeatures === true) {
const filters: Filter[] = [];
if (this.user?.settings?.['filters.tags']) {
filters.push({
id: this.user.settings['filters.tags'][0],
type: 'TAG'
});
}
this.dataService
.fetchActivities({
filters,
skip: this.pageIndex * this.pageSize,
sortColumn: this.sortColumn,
sortDirection: this.sortDirection,

1
libs/common/src/lib/interfaces/user-settings.interface.ts

@ -7,6 +7,7 @@ export interface UserSettings {
colorScheme?: ColorScheme;
dateRange?: DateRange;
emergencyFund?: number;
'filters.tags'?: string[];
isExperimentalFeatures?: boolean;
isRestrictedView?: boolean;
language?: string;

11
libs/ui/src/lib/activities-table-lazy/activities-table-lazy.component.ts

@ -75,7 +75,6 @@ export class ActivitiesTableLazyComponent
public isLoading = true;
public isUUID = isUUID;
public routeQueryParams: Subscription;
public searchKeywords: string[] = [];
public selectedRows = new SelectionModel<Activity>(true, []);
private unsubscribeSubject = new Subject<void>();
@ -182,15 +181,7 @@ export class ActivitiesTableLazyComponent
}
public onExport() {
if (this.searchKeywords.length > 0) {
this.export.emit(
this.dataSource.filteredData.map((activity) => {
return activity.id;
})
);
} else {
this.export.emit();
}
this.export.emit();
}
public onExportDraft(aActivityId: string) {

19
libs/ui/src/lib/assistant/assistant.component.ts

@ -7,6 +7,7 @@ import {
EventEmitter,
HostListener,
Input,
OnChanges,
OnDestroy,
OnInit,
Output,
@ -42,7 +43,7 @@ import { ISearchResultItem, ISearchResults } from './interfaces/interfaces';
styleUrls: ['./assistant.scss'],
templateUrl: './assistant.html'
})
export class AssistantComponent implements OnDestroy, OnInit {
export class AssistantComponent implements OnChanges, OnDestroy, OnInit {
@HostListener('document:keydown', ['$event']) onKeydown(
event: KeyboardEvent
) {
@ -81,6 +82,7 @@ export class AssistantComponent implements OnDestroy, OnInit {
@Output() closed = new EventEmitter<void>();
@Output() dateRangeChanged = new EventEmitter<DateRange>();
@Output() selectedTagChanged = new EventEmitter<Tag>();
@ViewChild('menuTrigger') menuTriggerElement: MatMenuTrigger;
@ViewChild('search', { static: true }) searchElement: ElementRef;
@ -100,6 +102,7 @@ export class AssistantComponent implements OnDestroy, OnInit {
holdings: []
};
public tags: Tag[] = [];
public tagsFormControl = new FormControl<string>(undefined);
private keyManager: FocusKeyManager<AssistantListItemComponent>;
private unsubscribeSubject = new Subject<void>();
@ -159,6 +162,12 @@ export class AssistantComponent implements OnDestroy, OnInit {
});
}
public ngOnChanges() {
this.tagsFormControl.setValue(
this.user?.settings?.['filters.tags']?.[0] ?? null
);
}
public async initialize() {
this.isLoading = true;
this.keyManager = new FocusKeyManager(this.assistantListItems).withWrap();
@ -192,8 +201,12 @@ export class AssistantComponent implements OnDestroy, OnInit {
this.closed.emit();
}
public onSelectTag(tag: Tag) {
console.log(tag);
public onTagChange() {
const selectedTag = this.tags.find(({ id }) => {
return id === this.tagsFormControl.value;
});
this.selectedTagChanged.emit(selectedTag);
this.onCloseAssistant();
}

16
libs/ui/src/lib/assistant/assistant.html

@ -116,13 +116,17 @@
>Tags</span
></ng-template
>
<div>
<mat-radio-group color="primary">
<div class="p-3">
<mat-radio-group
color="primary"
[formControl]="tagsFormControl"
(change)="onTagChange()"
>
<mat-radio-button class="d-flex flex-column" i18n [value]="null"
>No tag</mat-radio-button
>
@for (tag of tags; track tag.id) {
<mat-radio-button
class="d-flex flex-column"
[value]="tag.id"
(click)="onSelectTag(tag)"
<mat-radio-button class="d-flex flex-column" [value]="tag.id"
>{{ tag.name }}</mat-radio-button
>
}

Loading…
Cancel
Save