aboutsummaryrefslogtreecommitdiffstats
path: root/src/app/services/user-settings.service.ts
blob: 2f7e57836b4702ce7cc2ff2ea32901d373a75241 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*
 * Copyright (c) 2022. Deutsche Telekom AG
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * SPDX-License-Identifier: Apache-2.0
 */


import { distinctUntilChanged, map, pluck, switchMap, take } from 'rxjs/operators';
import { PreferencesResponse, PreferencesService } from '../../../openapi/output';
import {
  DashboardAppsModel,
  DashboardModel,
  DashboardTileSettings,
  defaultUserSettings,
  LastUserActionSettings, STATE_KEYS,
  UpdateUserPreferenceModel,
  UserPreferencesModel,
} from '../model/user-preferences.model';
import { BehaviorSubject, Observable, pipe, UnaryFunction } from 'rxjs';
import { mergeWith as _mergeWith, isObject as _isObject } from 'lodash';
import { isString } from '../helpers/helpers';
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class UserSettingsService {
  private userSettings: UserPreferencesModel = defaultUserSettings;
  private preferencesTracker$ = new BehaviorSubject<UserPreferencesModel>(this.userSettings);

  constructor(private preferencesService: PreferencesService) {
    this.getPreferences();
  }

  getPreferences$(): Observable<UserPreferencesModel> {
    return this.preferencesTracker$.asObservable();
  }

  selectDashboard = () =>
    this.getPreferences$().pipe(selectDistinctState<UserPreferencesModel, DashboardModel>(STATE_KEYS.DASHBOARD as keyof UserPreferencesModel));
  selectDashboardApps = () =>
    this.selectDashboard().pipe(selectDistinctState<DashboardModel, DashboardAppsModel>(STATE_KEYS.APPS as keyof DashboardModel));
  selectDashboardAvailableTiles = () =>
    this.selectDashboardApps().pipe(selectDistinctState<DashboardAppsModel, DashboardTileSettings[]>(STATE_KEYS.TILES as keyof DashboardAppsModel));
  selectLastUserAction = () =>
    this.selectDashboardApps().pipe(
      selectDistinctState<DashboardAppsModel, LastUserActionSettings>(STATE_KEYS.USER_ACTIONS as keyof DashboardAppsModel),
    );

  getPreferences(): void {
    this.preferencesService
      .getPreferences()
      .pipe(
        map(preferences => {
          return _mergeWith({}, defaultUserSettings, preferences.properties, (objValue, srcValue) => {
            if (
              (Array.isArray(srcValue) && !srcValue.some(_isObject)) ||
              isString(srcValue) ||
              typeof srcValue === 'boolean' ||
              Number.isInteger(srcValue)
            ) {
              return srcValue;
            }
          }) as UserPreferencesModel;
        }),
      )
      .subscribe(userPreferences => {
        this.preferencesTracker$.next(userPreferences);
      });
  }

  updatePreferences(preferences: UpdateUserPreferenceModel): Observable<PreferencesResponse> {
    return this.getPreferences$().pipe(
      take(1),
      switchMap(data => {
        const properties = _mergeWith({}, data, preferences, (objValue, srcValue) => {
          if (
            Array.isArray(srcValue) ||
            isString(srcValue) ||
            typeof srcValue === 'boolean' ||
            Number.isInteger(srcValue)
          ) {
            return srcValue;
          }
        }) as UserPreferencesModel;
        this.preferencesTracker$.next(properties);
        return this.preferencesService.savePreferences({ properties });
      }),
    );
  }

  removePreferences(): Observable<PreferencesResponse> {
    return this.preferencesService.updatePreferences({ properties: {} });
  }
}

export function selectDistinctState<T, I>(key: keyof T): UnaryFunction<Observable<T>, Observable<I>> {
  // return pipe(map(x => x[key] as I), distinctUntilChanged<I>());
  return pipe(pluck(key), map(value => value as unknown as I), distinctUntilChanged());
  // return pipe(pluck<T, I>(key), distinctUntilChanged<I>());
}