Skip to content

Commit f2ed36e

Browse files
Frieda-HentschelDanielHabenichtrestyled-io[bot]restyled-commits
authored
feat(dashboard): Select different Layouts for Bookmarks in Settings (#536)
Previously, the only option were the user-small-cards. Now one can choose between three different Layouts for the bookmarked people on the dashboard. I used the user-small-cards and user-tiny-cards for two of the layouts and created the user-list-card.component for the third option. closes #176 Co-authored-by: DanielHabenicht <daniel-habenicht@outlook.de> Co-authored-by: restyled-io[bot] <32688539+restyled-io[bot]@users.noreply.github.com> Co-authored-by: Restyled.io <commits@restyled.io>
1 parent 1746af7 commit f2ed36e

File tree

16 files changed

+596
-354
lines changed

16 files changed

+596
-354
lines changed

Phonebook.Frontend/src/app/app.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ import { environment } from 'src/environments/environment';
5353
import { FloorplanService } from './services/floorplan.service';
5454
import { SearchComponent } from './shared/components/search/search.component';
5555
import { HttpRedirectToLogin } from 'src/app/shared/interceptors/HttpRedirectToLogin';
56+
import { FormsModule } from '@angular/forms';
5657

5758
declare const require;
5859

@@ -71,6 +72,7 @@ declare const require;
7172
HttpClientModule,
7273
ErrorHandlerModule.forRoot(),
7374
MaterialModule,
75+
FormsModule,
7476
DialogsModule,
7577
ProfilePictureModule,
7678
SettingsModule,

Phonebook.Frontend/src/app/pages/dashboard/dashboard.component.html

Lines changed: 69 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -90,29 +90,77 @@ <h1>
9090
>
9191
</mat-select>
9292
</mat-form-field>
93+
<button
94+
i18n-matTooltip="
95+
DashboardComponent|Layout Change Button Tooltip@@dashboardComponentLayoutChangeTooltip"
96+
matTooltip="Here you can change the layout of your dashboard."
97+
(click)="select.open()"
98+
mat-icon-button
99+
class="changeLayoutButton"
100+
>
101+
<mat-icon>{{ activeLayout$ | async }}</mat-icon>
102+
<mat-select
103+
#select
104+
class="selectLayout"
105+
[ngModel]="activeLayout$ | async"
106+
(ngModelChange)="changeLayout($event)"
107+
>
108+
<mat-option *ngFor="let view of layouts" [value]="view">
109+
<span>{{ getLayoutName(view) }}</span>
110+
</mat-option>
111+
</mat-select>
112+
</button>
93113
</div>
94114
<!-- This is a workaround for https://github.com/angular/material2/issues/13372 -->
95-
<div cdkDropListGroup class="pb-bookmarks-list pb-flex-row">
96-
<div
97-
*ngFor="let person of bookmarkedPersons; index as i"
98-
cdkDropList
99-
[cdkDropListData]="i"
100-
cdkDropListOrientation="horizontal"
101-
class="card-container"
102-
>
103-
<app-user-small-card
104-
[person]="person"
105-
[actionButtonIcon]="'close'"
106-
[actionButtonClasses]="'white'"
107-
(actionButtonClicked)="removeFromBookmarkedPersons(person)"
108-
class="pb-small-card pb-card"
109-
cdkDrag
110-
(cdkDragEntered)="entered($event)"
111-
(cdkDragEnded)="ended($event)"
112-
[cdkDragData]="i"
113-
[cdkDragDisabled]="favoriteSort != ''"
114-
></app-user-small-card>
115-
</div>
115+
<div
116+
cdkDropListGroup
117+
class="pb-flex-row pb-bookmarks-list"
118+
[ngSwitch]="activeLayout$ | async"
119+
>
120+
<ng-container *ngSwitchCase="layout.medium_cards">
121+
<div
122+
*ngFor="let person of bookmarkedPersons; index as i"
123+
cdkDropList
124+
[cdkDropListData]="i"
125+
cdkDropListOrientation="horizontal"
126+
class="card-container"
127+
>
128+
<app-user-small-card
129+
[person]="person"
130+
[actionButtonIcon]="'close'"
131+
[actionButtonClasses]="'white'"
132+
(actionButtonClicked)="removeFromBookmarkedPersons(person)"
133+
class="pb-small-card pb-card"
134+
cdkDrag
135+
(cdkDragEntered)="entered($event)"
136+
(cdkDragEnded)="ended($event)"
137+
[cdkDragData]="i"
138+
[cdkDragDisabled]="favoriteSort != ''"
139+
></app-user-small-card>
140+
</div>
141+
</ng-container>
142+
<ng-container *ngSwitchCase="layout.small_cards">
143+
<div
144+
*ngFor="let person of bookmarkedPersons; index as i"
145+
cdkDropList
146+
[cdkDropListData]="i"
147+
cdkDropListOrientation="horizontal"
148+
class="card-container"
149+
>
150+
<app-user-tiny-card
151+
[person]="person"
152+
[actionButtonIcon]="'close'"
153+
[actionButtonClasses]="'white'"
154+
(actionButtonClicked)="removeFromBookmarkedPersons(person)"
155+
class="pb-card"
156+
cdkDrag
157+
(cdkDragEntered)="entered($event)"
158+
(cdkDragEnded)="ended($event)"
159+
[cdkDragData]="i"
160+
[cdkDragDisabled]="favoriteSort != ''"
161+
></app-user-tiny-card>
162+
</div>
163+
</ng-container>
116164
</div>
117165
<div
118166
*ngIf="bookmarkedPersons.length === 0"

Phonebook.Frontend/src/app/pages/dashboard/dashboard.component.scss

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ mat-drawer-container {
1111

1212
.pb-bookmarked {
1313
height: 100%;
14+
margin-right: 50px;
1415
display: flex;
1516
flex-direction: column;
1617
flex: 1;
@@ -93,3 +94,17 @@ mat-drawer-container {
9394
.cdk-drag-animating {
9495
transition: transform 200ms cubic-bezier(0, 0, 0.2, 1);
9596
}
97+
98+
::ng-deep .selectLayout div.mat-select-arrow-wrapper {
99+
display: none;
100+
}
101+
102+
::ng-deep .selectLayout.mat-select {
103+
display: inline;
104+
}
105+
106+
.changeLayoutButton {
107+
position: absolute;
108+
right: 0;
109+
margin-right: 10px;
110+
}

Phonebook.Frontend/src/app/pages/dashboard/dashboard.component.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ import { untilComponentDestroyed } from 'ng2-rx-componentdestroyed';
66
import { Observable, Subscription } from 'rxjs';
77
import { map } from 'rxjs/operators';
88
import { Person, PhonebookSortDirection } from 'src/app/shared/models';
9+
import { Layout } from 'src/app/shared/models/enumerables/Layout';
910
import {
1011
AppState,
1112
BookmarksState,
13+
SetLayout,
1214
SetRecentPeopleDrawer,
1315
ToggleBookmark,
1416
UpdateBookmarkOrder,
@@ -36,6 +38,11 @@ export class DashboardComponent implements OnInit, OnDestroy {
3638
@Select(BookmarksState)
3739
public bookmarkedPersons$: Observable<Person[]>;
3840
public removedLastPersons: Person[] | null = null;
41+
@Select(AppState.activeLayout)
42+
public activeLayout$: Observable<Layout>;
43+
public layouts: string[] = Object.values(Layout);
44+
45+
public layout: typeof Layout = Layout;
3946
public drawerOpen: boolean = false;
4047
public smallScreen: boolean = false;
4148
constructor(
@@ -118,11 +125,28 @@ export class DashboardComponent implements OnInit, OnDestroy {
118125
this.store.dispatch(new ToggleBookmark(person));
119126
}
120127

128+
public changeLayout(layoutClass: Layout) {
129+
this.store.dispatch(new SetLayout(layoutClass));
130+
}
131+
132+
public getLayoutName(layout: Layout): string {
133+
switch (layout) {
134+
case Layout.medium_cards: {
135+
return $localize`:NavigationComponent|View Mode - MediumCards@@NavigationComponentViewModeMediumCards:Medium Cards`;
136+
}
137+
case Layout.small_cards: {
138+
return $localize`:NavigationComponent|View Mode - SmallCards@@NavigationComponentViewModeSmallCards:Small Cards`;
139+
}
140+
default:
141+
throw Error(`Translation for layout ${layout} does not exist.`);
142+
}
143+
}
144+
121145
public toggleDrawer() {
122146
this.drawerOpen = !this.drawerOpen;
123147
if (!this.smallScreen) {
124148
this.store.dispatch(new SetRecentPeopleDrawer(this.drawerOpen));
125149
}
126150
}
127-
ngOnDestroy(): void {}
151+
public ngOnDestroy(): void {}
128152
}

Phonebook.Frontend/src/app/pages/settings/settings.component.html

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,15 @@ <h1 i18n="SettingsComponent|Title of the settings page@@SettingsComponentTitle">
1313

1414
<mat-card-content class="settings">
1515
<div class="pb-flex-1">
16-
<h2 i18n="SettingsComponent|Language SubTitle@@SettingsComponentSubTitleLanguage"
17-
>Language</h2
16+
<h2
17+
class="subheading"
18+
i18n="
19+
SettingsComponent|Subtitle General of the settings page@@SettingsComponentSubtitleGeneral"
20+
>
21+
General
22+
</h2>
23+
<h4 i18n="SettingsComponent|Language SubTitle@@SettingsComponentSubTitleLanguage"
24+
>Language</h4
1825
>
1926
<mat-list>
2027
<mat-list-item>
@@ -28,8 +35,8 @@ <h1 i18n="SettingsComponent|Title of the settings page@@SettingsComponentTitle">
2835
</mat-form-field>
2936
</mat-list-item>
3037
</mat-list>
31-
<h2 i18n="SettingsComponent|Color Theme SubTitle@@SettingsComponentSubTitleColorTheme"
32-
>Color Theme</h2
38+
<h4 i18n="SettingsComponent|Color Theme SubTitle@@SettingsComponentSubTitleColorTheme"
39+
>Color Theme</h4
3340
>
3441
<mat-list>
3542
<mat-list-item>
@@ -47,23 +54,6 @@ <h1 i18n="SettingsComponent|Title of the settings page@@SettingsComponentTitle">
4754
</mat-form-field>
4855
</mat-list-item>
4956
</mat-list>
50-
<h2 i18n="SettingsComponent|Layout Subtitle@@SettingsComponentSubTitleLayout">Layout</h2>
51-
<mat-list>
52-
<mat-list-item>
53-
<mat-icon class="pb-margin-20">{{ layoutValue }}</mat-icon>
54-
<mat-form-field>
55-
<mat-select [(ngModel)]="layoutValue" (ngModelChange)="changeLayout(layoutValue)">
56-
<mat-select-trigger>
57-
<span>{{ getLayoutName(layoutValue) }}</span>
58-
</mat-select-trigger>
59-
<mat-option *ngFor="let view of layout" [value]="view">
60-
<mat-icon>{{ view }}</mat-icon>
61-
<span>{{ getLayoutName(view) }}</span>
62-
</mat-option>
63-
</mat-select>
64-
</mat-form-field>
65-
</mat-list-item>
66-
</mat-list>
6757
</div>
6858
</mat-card-content>
6959
</mat-card>

Phonebook.Frontend/src/app/pages/settings/settings.component.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,7 @@
22
display: flex;
33
flex-direction: row;
44
}
5+
6+
.subheading {
7+
margin: 10px 0 0 0 !important;
8+
}
Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
import { Component, OnDestroy, OnInit } from '@angular/core';
22
import { MatSlideToggleChange } from '@angular/material/slide-toggle';
3-
4-
import { Store, Select } from '@ngxs/store';
3+
import { Select, Store } from '@ngxs/store';
54
import { Observable } from 'rxjs';
65
import { FeatureFlagService } from 'src/app/modules/feature-flag/feature-flag.service';
7-
import { NotImplementedService } from 'src/app/modules/not-implemented/not-implemented.service';
86
import { LanguageService } from 'src/app/services/language.service';
97
import { Language } from 'src/app/shared/models/enumerables/Language';
10-
import { AppState, SetTheme } from 'src/app/shared/states';
118
import { Theme } from 'src/app/shared/models/enumerables/Theme';
9+
import { AppState, SetTheme } from 'src/app/shared/states';
1210

1311
@Component({
1412
selector: 'app-settings',
@@ -21,16 +19,13 @@ export class SettingsComponent implements OnInit, OnDestroy {
2119
public themeValue$: Observable<Theme>;
2220
public themes: string[] = Object.values(Theme);
2321
public languages: string[] = Object.keys(Language);
24-
public layoutValue: Layout = Layout.view_module;
25-
public layout: string[] = Object.values(Layout);
2622
public featureFlags: Observable<
2723
{ name: string; value: boolean }[]
2824
> = this.featureFlagService.getAllDefaultDisabled();
2925

3026
constructor(
3127
private store: Store,
3228
public languageService: LanguageService,
33-
private notImplementedService: NotImplementedService,
3429
public featureFlagService: FeatureFlagService
3530
) {}
3631

@@ -46,11 +41,6 @@ export class SettingsComponent implements OnInit, OnDestroy {
4641
this.languageService.setLanguage(lang);
4742
}
4843

49-
public changeLayout(layout: Layout) {
50-
this.notImplementedService.notImplemented();
51-
this.layoutValue = layout;
52-
}
53-
5444
public getThemeName(theme: Theme) {
5545
switch (theme) {
5646
case Theme.blue_light_theme: {
@@ -73,29 +63,9 @@ export class SettingsComponent implements OnInit, OnDestroy {
7363
}
7464
}
7565

76-
public getLayoutName(layout: Layout): string {
77-
switch (layout) {
78-
case Layout.view_list: {
79-
return $localize`:NavigationComponent|View Mode - List@@NavigationComponentViewModeList:List View`;
80-
}
81-
case Layout.view_module: {
82-
return $localize`:NavigationComponent|View Mode - Module@@NavigationComponentViewModeModule:Module View`;
83-
}
84-
case Layout.view_stream: {
85-
return $localize`:NavigationComponent|View Mode - Stream@@NavigationComponentViewModeStream:Stream View`;
86-
}
87-
}
88-
}
89-
9066
public changeFeatureFlag(event: MatSlideToggleChange, flag: string) {
9167
this.featureFlagService.set(flag, event.checked);
9268
}
9369

9470
public ngOnDestroy() {}
9571
}
96-
97-
enum Layout {
98-
view_list = 'view_list',
99-
view_module = 'view_module',
100-
view_stream = 'view_stream',
101-
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export enum Layout {
2+
medium_cards = 'view_stream',
3+
small_cards = 'view_module',
4+
}

Phonebook.Frontend/src/app/shared/states/App.state.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,17 @@ import { Injectable } from '@angular/core';
22
import { Action, Selector, State, StateContext } from '@ngxs/store';
33
import { ThemeService } from 'src/app/services/theme.service';
44
import { Theme } from 'src/app/shared/models/enumerables/Theme';
5+
import { Layout } from 'src/app/shared/models/enumerables/Layout';
56

67
export class ServiceWorkerNotificationDisplayed {
78
public static readonly type: string = '[App State] Service Worker Notification displayed';
89
}
910

11+
export class SetLayout {
12+
public static readonly type: string = '[App State] Set activeLayout';
13+
constructor(public activeLayout: Layout) {}
14+
}
15+
1016
export class SetVersion {
1117
public static readonly type: string = '[App State] Set Version';
1218
constructor(public version: string) {}
@@ -45,6 +51,7 @@ export interface AppStateModel {
4551
*/
4652
sendFeedback: boolean | null;
4753
activeTheme: Theme;
54+
activeLayout: Layout;
4855
recentPeopleDrawer: boolean;
4956
}
5057

@@ -56,6 +63,7 @@ export interface AppStateModel {
5663
displayedNotificationVersion: 0,
5764
sendFeedback: null,
5865
activeTheme: Theme.magenta_light_theme,
66+
activeLayout: Layout.medium_cards,
5967
recentPeopleDrawer: true,
6068
},
6169
})
@@ -75,6 +83,10 @@ export class AppState {
7583
public static activeTheme(state: AppStateModel): Theme {
7684
return state.activeTheme;
7785
}
86+
@Selector()
87+
public static activeLayout(state: AppStateModel): Layout {
88+
return state.activeLayout;
89+
}
7890

7991
@Selector()
8092
public static displayedNotificationVersion(state: AppStateModel): number {
@@ -143,6 +155,15 @@ export class AppState {
143155
this.themeService.setTheme(state.activeTheme);
144156
}
145157

158+
@Action(SetLayout)
159+
public setLayout(ctx: StateContext<AppStateModel>, action: SetLayout) {
160+
const state = ctx.getState();
161+
ctx.setState({
162+
...state,
163+
activeLayout: action.activeLayout,
164+
});
165+
}
166+
146167
@Action(SetRecentPeopleDrawer)
147168
public setDrawer(ctx: StateContext<AppStateModel>, action: SetRecentPeopleDrawer) {
148169
const state = ctx.getState();

0 commit comments

Comments
 (0)