diff --git a/src/app/dashboard/dashboard-tile-accordion-layout.component.html b/src/app/dashboard/dashboard-tile-accordion-layout.component.html new file mode 100644 index 0000000000..f9442c5555 --- /dev/null +++ b/src/app/dashboard/dashboard-tile-accordion-layout.component.html @@ -0,0 +1,13 @@ + + + + + + + + + + + + diff --git a/src/app/dashboard/dashboard-tile-left-tile.component.html b/src/app/dashboard/dashboard-tile-left-tile.component.html new file mode 100644 index 0000000000..b7d33b6263 --- /dev/null +++ b/src/app/dashboard/dashboard-tile-left-tile.component.html @@ -0,0 +1,11 @@ +
+ + + + + + + + + My Progress +
\ No newline at end of file diff --git a/src/app/dashboard/dashboard-tile-right-tile.component.html b/src/app/dashboard/dashboard-tile-right-tile.component.html new file mode 100644 index 0000000000..ddbf3548c2 --- /dev/null +++ b/src/app/dashboard/dashboard-tile-right-tile.component.html @@ -0,0 +1,26 @@ +
+
+ + +
+

{{item.firstLine}}

+

{{item.title}}

+ +
+
+
+ + Add item to {{cardTitle}} + +
+
\ No newline at end of file diff --git a/src/app/dashboard/dashboard-tile-row-layout.component.html b/src/app/dashboard/dashboard-tile-row-layout.component.html new file mode 100644 index 0000000000..6bf0bf3de9 --- /dev/null +++ b/src/app/dashboard/dashboard-tile-row-layout.component.html @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/src/app/dashboard/dashboard-tile.component.html b/src/app/dashboard/dashboard-tile.component.html index d61a5da9e8..c2bd85e640 100644 --- a/src/app/dashboard/dashboard-tile.component.html +++ b/src/app/dashboard/dashboard-tile.component.html @@ -1,39 +1,8 @@ -
- - - - - - - - - My Progress -
-
-
- - -
-

{{item.firstLine}}

-

{{item.title}}

- -
-
-
- - Add item to {{cardTitle}} - -
-
+ + + +
diff --git a/src/app/dashboard/dashboard-tile.component.ts b/src/app/dashboard/dashboard-tile.component.ts index 9192d0e0ef..f4f707b1be 100644 --- a/src/app/dashboard/dashboard-tile.component.ts +++ b/src/app/dashboard/dashboard-tile.component.ts @@ -1,11 +1,12 @@ -import { Component, Input, ElementRef, ViewChild, Output, EventEmitter, AfterViewChecked, ChangeDetectorRef } from '@angular/core'; -import { tap } from 'rxjs/operators'; +import { Component, Input, ElementRef, ViewChild, Output, EventEmitter, AfterViewChecked, ChangeDetectorRef, HostListener } from '@angular/core'; +import { elementAt, tap } from 'rxjs/operators'; import { PlanetMessageService } from '../shared/planet-message.service'; import { UserService } from '../shared/user.service'; import { TeamsService } from '../teams/teams.service'; import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; import { MatDialog, MatDialogRef } from '@angular/material/dialog'; import { DialogsPromptComponent } from '../shared/dialogs/dialogs-prompt.component'; +import { DeviceInfoService, DeviceType } from '../shared/device-info.service'; // Main page once logged in. At this stage is more of a placeholder. @Component({ @@ -13,7 +14,7 @@ import { DialogsPromptComponent } from '../shared/dialogs/dialogs-prompt.compone templateUrl: './dashboard-tile.component.html', styleUrls: [ './dashboard-tile.scss' ] }) -export class DashboardTileComponent implements AfterViewChecked { +export class DashboardTileComponent { @Input() cardTitle: string; @Input() cardType: string; @Input() color: string; @@ -22,33 +23,38 @@ export class DashboardTileComponent implements AfterViewChecked { @Input() emptyLink; @Input() shelfName: string; @Output() teamRemoved = new EventEmitter(); - @ViewChild('items') itemDiv: ElementRef; + // @ViewChild('items') itemDiv: ElementRef; dialogPrompt: MatDialogRef; - tileLines = 2; + // tileLines = 2; + deviceType: DeviceType; + deviceTypes: typeof DeviceType = DeviceType; constructor( private planetMessageService: PlanetMessageService, private userService: UserService, private teamsService: TeamsService, private dialog: MatDialog, - private cd: ChangeDetectorRef - ) { } - - ngAfterViewChecked() { - const divHeight = this.itemDiv.nativeElement.offsetHeight; - const itemStyle = window.getComputedStyle(this.itemDiv.nativeElement.querySelector('.dashboard-item')); - const tilePadding = +(itemStyle.paddingTop.replace('px', '')) * 2; - const fontSize = +(itemStyle.fontSize.replace('px', '')); - const tileHeight = divHeight - tilePadding; - // line-height: normal varies by browser, but should be between 1-1.2 - const tileLines = Math.floor(tileHeight / (fontSize * 1.2)); - if (tileLines !== this.tileLines) { - this.tileLines = tileLines; - this.cd.detectChanges(); - } + private deviceInfoService: DeviceInfoService + // private cd: ChangeDetectorRef + ) { + this.deviceType = this.deviceInfoService.getDeviceType(); } - removeFromShelf(event, item: any) { + // ngAfterViewChecked() { + // const divHeight = this.itemDiv.nativeElement.offsetHeight; + // const itemStyle = window.getComputedStyle(this.itemDiv.nativeElement.querySelector('.dashboard-item')); + // const tilePadding = +(itemStyle.paddingTop.replace('px', '')) * 2; + // const fontSize = +(itemStyle.fontSize.replace('px', '')); + // const tileHeight = divHeight - tilePadding; + // // line-height: normal varies by browser, but should be between 1-1.2 + // const tileLines = Math.floor(tileHeight / (fontSize * 1.2)); + // if (tileLines !== this.tileLines) { + // this.tileLines = tileLines; + // this.cd.detectChanges(); + // } + // } + + removeFromShelf({ event, item }) { event.stopPropagation(); const { _id: userId, planetCode: userPlanetCode } = this.userService.get(); if (this.shelfName === 'myTeamIds') { @@ -94,6 +100,10 @@ export class DashboardTileComponent implements AfterViewChecked { } ); } + + @HostListener('window:resize') onResize() { + this.deviceType = this.deviceInfoService.getDeviceType(); + } } @Component({ @@ -110,3 +120,110 @@ export class DashboardTileTitleComponent { @Input() cardType; } + +@Component({ + selector: 'planet-dashboard-row-layout', + templateUrl: './dashboard-tile-row-layout.component.html', + styleUrls: [ './dashboard-tile.scss' ] +}) +export class DashboardTileRowLayoutComponent { + + @Input() cardTitle; + @Input() cardType; + @Input() link; + @Input() emptyLink; + @Input() itemData; + @Output() droppedEvent = new EventEmitter(); + @Output() removeEvent = new EventEmitter<{event, item}>(); + + drop(event: CdkDragDrop) { + this.droppedEvent.emit(event); + } + + removeFromShelf({ event, item }) { + this.removeEvent.emit({ event, item }); + } + +} + +@Component({ + selector: 'planet-dashboard-accordion-layout', + templateUrl: './dashboard-tile-accordion-layout.component.html', + styleUrls: [ './dashboard-tile.scss' ] +}) +export class DashboardTileAccordionLayoutComponent { + + @Input() deviceType; + @Input() deviceTypes; + @Input() cardTitle; + @Input() cardType; + @Input() link; + @Input() emptyLink; + @Input() itemData; + @Output() droppedEvent = new EventEmitter(); + @Output() removeEvent = new EventEmitter<{event, item}>(); + + drop(event: CdkDragDrop) { + this.droppedEvent.emit(event); + } + + removeFromShelf({ event, item }) { + this.removeEvent.emit({ event, item }); + } + +} + +@Component({ + selector: 'planet-dashboard-left-tile', + templateUrl: './dashboard-tile-left-tile.component.html', + styleUrls: [ './dashboard-tile.scss' ] +}) +export class DashboardTileLeftTileComponent { + + @Input() cardTitle; + @Input() cardType; + @Input() link; + @Input() emptyLink; +} + + +@Component({ + selector: 'planet-dashboard-right-tile', + templateUrl: './dashboard-tile-right-tile.component.html', + styleUrls: [ './dashboard-tile.scss' ] +}) +export class DashboardTileRightTileComponent implements AfterViewChecked { + + @Input() cardTitle; + @Input() itemData; + @Input() link; + @Input() emptyLink; + @Output() droppedEvent = new EventEmitter(); + @Output() removeEvent = new EventEmitter<{event, item}>(); + @ViewChild('items') itemDiv: ElementRef; + tileLines = 2; + + constructor( private cd: ChangeDetectorRef ) {} + + ngAfterViewChecked() { + const divHeight = this.itemDiv.nativeElement.offsetHeight; + const itemStyle = window.getComputedStyle(this.itemDiv.nativeElement.querySelector('.dashboard-item')); + const tilePadding = +(itemStyle.paddingTop.replace('px', '')) * 2; + const fontSize = +(itemStyle.fontSize.replace('px', '')); + const tileHeight = divHeight - tilePadding; + // line-height: normal varies by browser, but should be between 1-1.2 + const tileLines = Math.floor(tileHeight / (fontSize * 1.2)); + if (tileLines !== this.tileLines) { + this.tileLines = tileLines; + this.cd.detectChanges(); + } + } + + drop(event: CdkDragDrop) { + this.droppedEvent.emit(event); + } + + removeFromShelf(event, item: any) { + this.removeEvent.emit({ event, item }); + } +} diff --git a/src/app/dashboard/dashboard-tile.scss b/src/app/dashboard/dashboard-tile.scss index d3f21a4320..123da67d9f 100644 --- a/src/app/dashboard/dashboard-tile.scss +++ b/src/app/dashboard/dashboard-tile.scss @@ -1,74 +1,114 @@ -@import '../mixins.scss'; -@import '../variables'; +@import "../mixins.scss"; +@import "../variables"; :host { - @include left-right-grid-areas; // For Firefox. Otherwise grid tile will expand to fit text. min-width: 0; - .dashboard-card { + @media (min-width: 601px) { + .dashboard-card { + height: 100%; + padding: 0; + } + } + + .dashboard-card > planet-dashboard-row-layout { display: grid; grid-template-areas: "lt rt"; grid-template-rows: 1fr; grid-template-columns: $dashboard-tile-width 1fr; height: 100%; - padding: 0; + } + + planet-dashboard-row-layout & .left-tile { + border-radius: 2px 0 0 2px; + height: 100%; + &, + & planet-dashboard-tile-title { + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + flex-wrap: wrap; + font-size: 1.25rem; + } + } + + planet-dashboard-row-layout & .right-tile { + display: grid; + overflow-x: auto; + overflow-y: hidden; + height: 100%; + + .dashboard-items.dashboard-empty { + grid-auto-columns: auto; + } + + .dashboard-items { + display: grid; + grid-auto-columns: $dashboard-tile-width; + transition: transform 0.5s; - .left-tile { - border-radius: 2px 0 0 2px; - &, & planet-dashboard-tile-title { + .dashboard-item { + grid-column-end: span 1; + grid-row-end: 1; display: flex; + flex-direction: column; justify-content: center; align-items: center; - flex-direction: column; - flex-wrap: wrap; - font-size: 1.25rem; + text-align: center; + padding: 1rem 0.5rem; + position: relative; + word-break: break-word; + .delete-item { + position: absolute; + top: -0.25rem; + right: -0.25rem; + } + p { + margin: 0; + } + + .dashboard-text { + display: -webkit-box; + width: calc(125px - 1rem); + -webkit-box-orient: vertical; + overflow: hidden; + } } + } + } + + .dashboard-card > planet-dashboard-accordion-layout { + display: block; + } + planet-dashboard-accordion-layout & .left-tile { + &, + & planet-dashboard-tile-title { + justify-content: center; + transition: 0.5s; } + } - .right-tile { - display: grid; - overflow-x: auto; - overflow-y: hidden; + mat-expansion-panel-header:hover { + background: revert; + } - .dashboard-items.dashboard-empty { - grid-auto-columns: auto; - } + planet-dashboard-accordion-layout & .right-tile { + overflow: hidden; - .dashboard-items { - display: grid; - grid-auto-columns: $dashboard-tile-width; - transition: transform 0.5s; - - .dashboard-item { - grid-column-end: span 1; - grid-row-end: 1; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - text-align: center; - padding: 1rem 0.5rem; - position: relative; - word-break: break-word; - .delete-item { - position: absolute; - top: -0.25rem; - right: -0.25rem; - } - p { - margin: 0; - } - - .dashboard-text { - display: -webkit-box; - width: calc(125px - 1rem); - -webkit-box-orient: vertical; - overflow: hidden; - } + .dashboard-items { + display: block; + .dashboard-item { + display: flex; + flex-wrap: wrap; + flex-direction: row; + .delete-item { + position: absolute; + right: 1rem; } } } diff --git a/src/app/dashboard/dashboard.scss b/src/app/dashboard/dashboard.scss index 5640f7923b..47c65c38cf 100644 --- a/src/app/dashboard/dashboard.scss +++ b/src/app/dashboard/dashboard.scss @@ -16,9 +16,15 @@ $top-row-height: calc(#{$dashboard-tile-width} + 0.5rem); grid-template-rows: auto repeat(4, minmax(70px, 1fr)); } - planet-dashboard-tile { - overflow: hidden; - padding: 0 2px; + @media (min-width: 601px) { + planet-dashboard-tile { + overflow: hidden; + padding: 0 2px; + } + } + + @media (max-width: 601px) { + grid-template-rows: auto repeat(4, minmax(auto, 1fr)); } mat-card { diff --git a/src/app/home/home.module.ts b/src/app/home/home.module.ts index ca8dd811f1..b50e25f59e 100644 --- a/src/app/home/home.module.ts +++ b/src/app/home/home.module.ts @@ -9,7 +9,14 @@ import { HomeRouterModule } from './home-router.module'; import { PlanetFormsModule } from '../shared/forms/planet-forms.module'; import { MaterialModule } from '../shared/material.module'; -import { DashboardTileComponent, DashboardTileTitleComponent } from '../dashboard/dashboard-tile.component'; +import { + DashboardTileComponent, + DashboardTileTitleComponent, + DashboardTileLeftTileComponent, + DashboardTileRightTileComponent, + DashboardTileRowLayoutComponent, + DashboardTileAccordionLayoutComponent +} from '../dashboard/dashboard-tile.component'; import { NotificationsComponent } from '../notifications/notifications.component'; import { PlanetDialogsModule } from '../shared/dialogs/planet-dialogs.module'; import { PulsateIconDirective } from './pulsate-icon.directive'; @@ -51,6 +58,10 @@ import { CoursesViewDetailModule } from '../courses/view-courses/courses-view-de DashboardComponent, DashboardTileComponent, DashboardTileTitleComponent, + DashboardTileLeftTileComponent, + DashboardTileRightTileComponent, + DashboardTileRowLayoutComponent, + DashboardTileAccordionLayoutComponent, NotificationsComponent, PulsateIconDirective, UpgradeComponent, @@ -61,4 +72,4 @@ import { CoursesViewDetailModule } from '../courses/view-courses/courses-view-de HealthListComponent, ] }) -export class HomeModule {} +export class HomeModule { }