From 44e9c14961c5cdde9d1c3324b37932fe130f3865 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 20 Sep 2022 19:31:29 +0200 Subject: [PATCH] Better teams overview. --- backend/i18n/frontend_en.json | 1 + backend/i18n/frontend_it.json | 1 + backend/i18n/frontend_nl.json | 1 + backend/i18n/frontend_zh.json | 1 + backend/i18n/source/frontend_en.json | 1 + .../apps/pages/apps-page.component.html | 28 +++++------ .../apps/pages/apps-page.component.scss | 38 ++++++++------ .../apps/pages/apps-page.component.ts | 38 +++++++++++--- .../features/apps/pages/team.component.html | 50 +++++++++---------- .../features/apps/pages/team.component.scss | 26 +++++++--- .../dashboard/cards/apps-card.component.html | 20 +++++--- .../dashboard/cards/apps-card.component.ts | 6 +-- frontend/src/app/theme/_vars.scss | 2 +- 13 files changed, 132 insertions(+), 81 deletions(-) diff --git a/backend/i18n/frontend_en.json b/backend/i18n/frontend_en.json index 75043e30f..a0dfbd855 100644 --- a/backend/i18n/frontend_en.json +++ b/backend/i18n/frontend_en.json @@ -992,6 +992,7 @@ "start.madeByCopyright": "Sebastian Stehle and Contributors, 2016-2021", "teams.create": "Create", "teams.createFailed": "Failed to create team. Please reload.", + "teams.empty": "This team has no apps yet.", "teams.leave": "Leave team", "teams.leaveConfirmText": "Do you really want to leave this team?", "teams.leaveConfirmTitle": "Leave team.", diff --git a/backend/i18n/frontend_it.json b/backend/i18n/frontend_it.json index 3b2988e9a..b9a2c798a 100644 --- a/backend/i18n/frontend_it.json +++ b/backend/i18n/frontend_it.json @@ -992,6 +992,7 @@ "start.madeByCopyright": "Sebastian Stehle e Collaboratori, 2016-2020", "teams.create": "Create", "teams.createFailed": "Failed to create team. Please reload.", + "teams.empty": "This team has no apps yet.", "teams.leave": "Leave team", "teams.leaveConfirmText": "Do you really want to leave this team?", "teams.leaveConfirmTitle": "Leave team.", diff --git a/backend/i18n/frontend_nl.json b/backend/i18n/frontend_nl.json index 6e69814db..fad02a121 100644 --- a/backend/i18n/frontend_nl.json +++ b/backend/i18n/frontend_nl.json @@ -992,6 +992,7 @@ "start.madeByCopyright": "Sebastian Stehle en medewerkers, 2016-2020", "teams.create": "Create", "teams.createFailed": "Failed to create team. Please reload.", + "teams.empty": "This team has no apps yet.", "teams.leave": "Leave team", "teams.leaveConfirmText": "Do you really want to leave this team?", "teams.leaveConfirmTitle": "Leave team.", diff --git a/backend/i18n/frontend_zh.json b/backend/i18n/frontend_zh.json index 16be6a543..1bf64f473 100644 --- a/backend/i18n/frontend_zh.json +++ b/backend/i18n/frontend_zh.json @@ -992,6 +992,7 @@ "start.madeByCopyright": "Sebastian Stehle 和贡献者,2016-2021", "teams.create": "Create", "teams.createFailed": "Failed to create team. Please reload.", + "teams.empty": "This team has no apps yet.", "teams.leave": "Leave team", "teams.leaveConfirmText": "Do you really want to leave this team?", "teams.leaveConfirmTitle": "Leave team.", diff --git a/backend/i18n/source/frontend_en.json b/backend/i18n/source/frontend_en.json index 75043e30f..a0dfbd855 100644 --- a/backend/i18n/source/frontend_en.json +++ b/backend/i18n/source/frontend_en.json @@ -992,6 +992,7 @@ "start.madeByCopyright": "Sebastian Stehle and Contributors, 2016-2021", "teams.create": "Create", "teams.createFailed": "Failed to create team. Please reload.", + "teams.empty": "This team has no apps yet.", "teams.leave": "Leave team", "teams.leaveConfirmText": "Do you really want to leave this team?", "teams.leaveConfirmTitle": "Leave team.", diff --git a/frontend/src/app/features/apps/pages/apps-page.component.html b/frontend/src/app/features/apps/pages/apps-page.component.html index 38950c451..d31e4c94b 100644 --- a/frontend/src/app/features/apps/pages/apps-page.component.html +++ b/frontend/src/app/features/apps/pages/apps-page.component.html @@ -9,27 +9,25 @@ - +
-
+

{{ 'apps.empty' | sqxTranslate }}

- -

{{ 'common.apps' | sqxTranslate }}

- - -
- +
+
+ +
- -
-

{{ 'common.teams' | sqxTranslate }}

+
+ - - + + {{ 'teams.empty' | sqxTranslate }} + +
+
diff --git a/frontend/src/app/features/apps/pages/apps-page.component.scss b/frontend/src/app/features/apps/pages/apps-page.component.scss index d94517a73..df44c9071 100644 --- a/frontend/src/app/features/apps/pages/apps-page.component.scss +++ b/frontend/src/app/features/apps/pages/apps-page.component.scss @@ -2,12 +2,6 @@ @import 'vars'; .apps-section { - @include clearfix; - padding: 2rem 1.25rem 0 $size-sidebar-width + .25rem; -} - -.teams-section { - @include clearfix; padding: 2rem 1.25rem 0 $size-sidebar-width + .25rem; } @@ -17,10 +11,6 @@ overflow-y: auto; } -%no-decoration { - text-decoration: none; -} - :host ::ng-deep { .card { @include hover-visible('.deeplinks', inline); @@ -83,23 +73,39 @@ &-href { cursor: pointer; - &:hover { - @extend %no-decoration; - @include box-shadow-outer(0, 3px, 16px, .2); + &:active, + &:focus { + text-decoration: none; } &:focus { - @extend %no-decoration; outline: none; } - &:active { - @extend %no-decoration; + &:hover { + @include box-shadow-outer(0, 3px, 16px, .2); } } } } +.team { + margin-top: 1rem; + + &:first-child { + margin: 0; + } + + &-body { + @include clearfix; + + &.padded { + padding-bottom: 1rem; + padding-top: 1rem; + } + } +} + .info { color: $color-border-dark; } \ No newline at end of file diff --git a/frontend/src/app/features/apps/pages/apps-page.component.ts b/frontend/src/app/features/apps/pages/apps-page.component.ts index 0b81ebb42..8fde70032 100644 --- a/frontend/src/app/features/apps/pages/apps-page.component.ts +++ b/frontend/src/app/features/apps/pages/apps-page.component.ts @@ -6,11 +6,13 @@ */ import { Component, OnInit } from '@angular/core'; -import { Observable } from 'rxjs'; +import { combineLatest } from 'rxjs'; import { map, take } from 'rxjs/operators'; import { AppDto, AppsState, AuthService, DialogModel, FeatureDto, LocalStoreService, NewsService, OnboardingService, TeamDto, TeamsState, TemplateDto, TemplatesState, UIOptions, UIState } from '@app/shared'; import { Settings } from '@app/shared/state/settings'; +type GroupedApps = { team?: TeamDto; apps: AppDto[] }; + @Component({ selector: 'sqx-apps-page', styleUrls: ['./apps-page.component.scss'], @@ -27,18 +29,42 @@ export class AppsPageComponent implements OnInit { public info = ''; - public templates: Observable = + public templates = this.templatesState.templates.pipe( map(x => x.filter(t => t.isStarter))); + public groupedApps = + combineLatest([ + this.appsState.apps, + this.teamsState.teams, + ]).pipe(map(([apps, teams]) => { + const grouped: GroupedApps[] = [{ apps: [] }]; + + for (const team of teams) { + grouped.push({ team, apps: [] }); + } + + for (const app of apps) { + const group = grouped.find(x => x.team?.id === app.teamId) || grouped[0]; + + group.apps.push(app); + } + + if (grouped[0].apps.length === 0) { + grouped.shift(); + } + + return grouped; + })); + constructor( - public readonly appsState: AppsState, public readonly authState: AuthService, public readonly uiState: UIState, - public readonly teamsState: TeamsState, + private readonly appsState: AppsState, private readonly localStore: LocalStoreService, private readonly newsService: NewsService, private readonly onboardingService: OnboardingService, + private readonly teamsState: TeamsState, private readonly templatesState: TemplatesState, private readonly uiOptions: UIOptions, ) { @@ -92,7 +118,7 @@ export class AppsPageComponent implements OnInit { return app.id; } - public trackByTeam(_index: number, team: TeamDto) { - return team.id; + public trackByGroup(_index: number, group: GroupedApps) { + return group.team?.id || '0'; } } diff --git a/frontend/src/app/features/apps/pages/team.component.html b/frontend/src/app/features/apps/pages/team.component.html index 7a5f5a8ad..a07c35c97 100644 --- a/frontend/src/app/features/apps/pages/team.component.html +++ b/frontend/src/app/features/apps/pages/team.component.html @@ -1,29 +1,27 @@ -
-
-
-
-

{{team.name}}

- - -
+ \ No newline at end of file diff --git a/frontend/src/app/features/apps/pages/team.component.scss b/frontend/src/app/features/apps/pages/team.component.scss index 9a9e5321d..6bed31076 100644 --- a/frontend/src/app/features/apps/pages/team.component.scss +++ b/frontend/src/app/features/apps/pages/team.component.scss @@ -1,14 +1,28 @@ @import 'mixins'; @import 'vars'; -.btn { - @include absolute(1rem, 1rem); +h3 { + @include truncate; } -.card-body { - position: relative; +.row { + flex-wrap: nowrap; } -.card-title { - padding-right: 2rem; +.col { + overflow: hidden; +} + +.team-header { + border-bottom: 1px solid $color-border; +} + +.link { + font-size: $font-small; + font-weight: normal; + text-decoration: none; + + &:hover { + text-decoration: underline; + } } \ No newline at end of file diff --git a/frontend/src/app/features/teams/pages/dashboard/cards/apps-card.component.html b/frontend/src/app/features/teams/pages/dashboard/cards/apps-card.component.html index 6b32b199b..00306c481 100644 --- a/frontend/src/app/features/teams/pages/dashboard/cards/apps-card.component.html +++ b/frontend/src/app/features/teams/pages/dashboard/cards/apps-card.component.html @@ -1,13 +1,19 @@
{{ 'common.apps' | sqxTranslate }}
-
-
- {{app.displayName}} + + + {{ 'teams.empty' | sqxTranslate }} + + +
+
+ {{app.displayName}} +
+
- -
+
\ No newline at end of file diff --git a/frontend/src/app/features/teams/pages/dashboard/cards/apps-card.component.ts b/frontend/src/app/features/teams/pages/dashboard/cards/apps-card.component.ts index 6e79216dc..f015662bd 100644 --- a/frontend/src/app/features/teams/pages/dashboard/cards/apps-card.component.ts +++ b/frontend/src/app/features/teams/pages/dashboard/cards/apps-card.component.ts @@ -10,7 +10,7 @@ import { AppDto, AppsService, StatefulComponent, TeamDto } from '@app/shared'; interface State { // The apps for this team. - apps: ReadonlyArray; + apps?: ReadonlyArray; } @Component({ @@ -26,9 +26,7 @@ export class AppsCardComponent extends StatefulComponent implements OnIni constructor(changeDetector: ChangeDetectorRef, private readonly appsService: AppsService, ) { - super(changeDetector, { - apps: [], - }); + super(changeDetector, {}); } public ngOnInit() { diff --git a/frontend/src/app/theme/_vars.scss b/frontend/src/app/theme/_vars.scss index 4e77171d0..31e15d79d 100644 --- a/frontend/src/app/theme/_vars.scss +++ b/frontend/src/app/theme/_vars.scss @@ -10,7 +10,7 @@ $color-border-darker: darken($color-border, 15%); $color-title: #000; $color-text: #373a3c; -$color-text-decent: #6c707f; +$color-text-decent: #545863; $color-tooltip: #1a2129; $color-code-background: #f5f7f9;