Skip to content

Commit

Permalink
web-app: fix html table layouts
Browse files Browse the repository at this point in the history
Tables were unable to shrink horizontally. Fix column sizes and remove
white-space-nowrap style.
  • Loading branch information
bennettpeter committed Jun 6, 2023
1 parent 1a0d866 commit dfc19de
Show file tree
Hide file tree
Showing 13 changed files with 128 additions and 86 deletions.
3 changes: 3 additions & 0 deletions mythtv/html/assets/i18n/en_US.json
Expand Up @@ -128,6 +128,9 @@
"template_apply": "Apply Template Change",
"isearch": "Search",
"heading": "Schedule recording"
},
"recrules": {
"heading": "Recording Rules"
}
},
"navbar": {
Expand Down
2 changes: 2 additions & 0 deletions mythtv/html/backend/src/app/app.module.ts
Expand Up @@ -78,6 +78,7 @@ import { WizChanneleditComponent } from './config/setupwizard/wiz-channeledit/wi
import { RecordingsComponent } from './dashboard/recordings/recordings.component';
import { ScheduleComponent } from './schedule/schedule.component';
import { UpcomingComponent } from './dashboard/upcoming/upcoming.component';
import { RecrulesComponent } from './dashboard/recrules/recrules.component';

// AoT requires an exported function for factories
export function HttpLoaderFactory(http: HttpClient) {
Expand Down Expand Up @@ -151,6 +152,7 @@ export function HttpLoaderFactory(http: HttpClient) {
RecordingsComponent,
ScheduleComponent,
UpcomingComponent,
RecrulesComponent,
],
imports: [
BrowserModule,
Expand Down
@@ -1,7 +1,7 @@
<h2>{{ 'settings.chanedit.title' | translate }}</h2>
<div class="block card w-full" style="height: 90vh" *ngIf="(chansLoaded && transDone >= numTranslations) else loading">
<p-table [value]="allChannels" scrollHeight="flex" [scrollable]="true" styleClass="p-datatable-striped"
[rowHover]="true" (onFilter)="onFilter($event)">
[rowHover]="true" (onFilter)="onFilter($event)" responsiveLayout="scroll">
<ng-template pTemplate="caption">
<button pButton pRipple label="{{ 'settings.chanedit.new_channel' | translate }}" icon="pi pi-plus"
class="p-button-success mr-2" (click)="openNew()"></button>
Expand All @@ -27,18 +27,18 @@ <h2>{{ 'settings.chanedit.title' | translate }}</h2>
</th>
</tr>
<tr>
<th style="flex-grow: 42; flex-basis: 0;">&nbsp;</th>
<th style="flex-grow: 44; flex-basis: 0;" pSortableColumn="ChanSeq">
<th style="flex-basis: 8%">&nbsp;</th>
<th style="flex-basis: 9%" pSortableColumn="ChanSeq">
{{ 'settings.chanedit.col_channum' | translate }} <p-sortIcon field="ChanSeq"></p-sortIcon></th>
<th style="flex-grow: 30; flex-basis: 0;">{{ 'settings.chanedit.col_freqid' | translate }}</th>
<th style="flex-grow: 50; flex-basis: 0;">{{ 'settings.chanedit.col_callsign' | translate }}</th>
<th style="flex-grow: 120; flex-basis: 0;">{{ 'settings.chanedit.col_name' | translate }}</th>
<th style="flex-grow: 80; flex-basis: 0;" pSortableColumn="Source">
<th style="flex-basis: 6%">{{ 'settings.chanedit.col_freqid' | translate }}</th>
<th style="flex-basis: 10%">{{ 'settings.chanedit.col_callsign' | translate }}</th>
<th style="flex-basis: 24%">{{ 'settings.chanedit.col_name' | translate }}</th>
<th style="flex-basis: 16%" pSortableColumn="Source">
{{ 'settings.chanedit.col_source' | translate }} <p-sortIcon field="Source"></p-sortIcon></th>
<th style="flex-grow: 30; flex-basis: 0;">{{ 'settings.chanedit.col_priority' | translate }}</th>
<th style="flex-grow: 50; flex-basis: 0;">{{ 'settings.chanedit.col_visibility' | translate }}</th>
<th style="flex-grow: 30; flex-basis: 0;">{{ 'settings.chanedit.col_useeit' | translate }}</th>
<th style="flex-grow: 30; flex-basis: 0;">
<th style="flex-basis: 6%">{{ 'settings.chanedit.col_priority' | translate }}</th>
<th style="flex-basis: 10%">{{ 'settings.chanedit.col_visibility' | translate }}</th>
<th style="flex-basis: 6%">{{ 'settings.chanedit.col_useeit' | translate }}</th>
<th style="flex-basis: 6%">
<!-- These are disabled buttons to ensure the spacing of the heading
matches the spacing of the rows -->
<button pButton pRipple icon="pi pi-pencil" class="p-button-text p-button-success"
Expand All @@ -50,20 +50,20 @@ <h2>{{ 'settings.chanedit.title' | translate }}</h2>
</ng-template>
<ng-template pTemplate="body" let-channel>
<tr height="40" [ngClass]="{'line-through' : channel.ChanId < 0}">
<td style="flex-grow: 42">
<td style="flex-basis: 8%">
<img src="{{channel.IconURL}}" height="32" width="42" *ngIf="channel.IconURL; else nullIcon"
style="background-color:#000000" onerror="this.height='0'">
<ng-template #nullIcon><img height="32" width="42"></ng-template>
</td>
<td style="flex-grow: 44; flex-basis: 0;">{{ channel.ChanNum }}</td>
<td style="flex-grow: 30; flex-basis: 0;">{{ channel.FrequencyId }}</td>
<td style="flex-grow: 50; flex-basis: 0;">{{ channel.CallSign }}</td>
<td style="flex-grow: 120; flex-basis: 0;">{{ channel.ChannelName }}</td>
<td style="flex-grow: 80; flex-basis: 0;">{{ channel.Source }}</td>
<td style="flex-grow: 30; flex-basis: 0;">{{ channel.RecPriority }}</td>
<td style="flex-grow: 50; flex-basis: 0;">{{ getVisibility(channel) }}</td>
<td style="flex-grow: 30; flex-basis: 0;">{{ channel.UseEIT ? 'Y' : 'N' }}</td>
<td style="flex-grow: 30; flex-basis: 0;">
<td style="flex-basis: 9%">{{ channel.ChanNum }}</td>
<td style="flex-basis: 6%">{{ channel.FrequencyId }}</td>
<td style="flex-basis: 10%">{{ channel.CallSign }}</td>
<td style="flex-basis: 24%">{{ channel.ChannelName }}</td>
<td style="flex-basis: 16%">{{ channel.Source }}</td>
<td style="flex-basis: 6%">{{ channel.RecPriority }}</td>
<td style="flex-basis: 10%">{{ getVisibility(channel) }}</td>
<td style="flex-basis: 6%">{{ channel.UseEIT ? 'Y' : 'N' }}</td>
<td style="flex-basis: 6%">
<button pButton pRipple icon="pi pi-pencil" class="p-button-text p-button-success"
(click)="editChannel(channel)" [disabled]="channel.ChanId < 0"
pTooltip="{{ 'settings.chanedit.updatechan' | translate }}"></button>
Expand Down
Expand Up @@ -6,6 +6,7 @@ import { ChannelEditorComponent } from '../config/settings/channel-editor/channe
import { GuideComponent } from '../guide/guide.component';
import { RecordingsComponent } from './recordings/recordings.component';
import { UpcomingComponent } from './upcoming/upcoming.component';
import { RecrulesComponent } from './recrules/recrules.component';

@NgModule({
imports: [
Expand All @@ -17,6 +18,7 @@ import { UpcomingComponent } from './upcoming/upcoming.component';
{ path: 'program-guide', component: GuideComponent },
{ path: 'recordings', component: RecordingsComponent },
{ path: 'upcoming', component: UpcomingComponent },
{ path: 'recrules', component: RecrulesComponent },
]
}
])
Expand Down
Expand Up @@ -17,6 +17,7 @@ export class DashboardComponent implements OnInit {
{ label: 'dashboard.programguide', routerLink: 'program-guide' },
{ label: 'dashboard.recordings.heading', routerLink: 'recordings' },
{ label: 'dashboard.upcoming.heading', routerLink: 'upcoming' },
{ label: 'dashboard.recrules.heading', routerLink: 'recrules' },
]

activeItem = this.fullMenu[0];
Expand Down
Expand Up @@ -6,7 +6,7 @@ <h2>{{ 'dashboard.recordings.heading' | translate }}</h2>
<div class="block card w-full" style="height: 90vh" *ngIf="recordings else loading">
<p-menu #menu [popup]="true" [model]="menuToShow"></p-menu>
<p-table [value]="recordings.Programs" scrollHeight="flex" [scrollable]="true" styleClass="p-datatable-striped"
[rowHover]="true">
[rowHover]="true" responsiveLayout="scroll">
<ng-template pTemplate="caption">
</ng-template>
<ng-template pTemplate="header">
Expand All @@ -25,57 +25,57 @@ <h2>{{ 'dashboard.recordings.heading' | translate }}</h2>
</th>
</tr>
<tr>
<th style="flex-grow: 40; flex-basis: 0;" class="p-1" pSortableColumn="Title">
<th style="flex-basis: 12%" class="p-1" pSortableColumn="Title">
{{ 'dashboard.recordings.title' | translate }} <p-sortIcon field="Title"></p-sortIcon></th>
<th style="flex-grow: 3; flex-basis: 0;" class="p-1"></th>
<th style="flex-grow: 45; flex-basis: 0;" class="p-1">{{ 'dashboard.recordings.subtitle' | translate
<th style="flex-basis: 2%" class="p-1"></th>
<th style="flex-basis: 18%" class="p-1">{{ 'dashboard.recordings.subtitle' | translate
}}</th>
<th style="flex-grow: 10; flex-basis: 0;" class="p-1">{{ 'dashboard.recordings.seas_ep' | translate
<th style="flex-basis: 4%" class="p-1">{{ 'dashboard.recordings.seas_ep' | translate
}}</th>
<th style="flex-grow: 20; flex-basis: 0;" class="justify-content-end p-1" pSortableColumn="Airdate">
<th style="flex-basis: 8%" class="justify-content-end p-1" pSortableColumn="Airdate">
{{ 'dashboard.recordings.orig_airdate' | translate }} <p-sortIcon field="Airdate"></p-sortIcon>
</th>
<th style="flex-grow: 20; flex-basis: 0;" class="justify-content-end p-1"
<th style="flex-basis: 8%" class="justify-content-end p-1"
pSortableColumn="StartTime">
{{ 'dashboard.recordings.airdate' | translate }} <p-sortIcon field="StartTime"></p-sortIcon>
</th>
<th style="flex-grow: 25; flex-basis: 0;" class="p-1">{{ 'dashboard.recordings.channel' | translate
<th style="flex-basis: 10%" class="p-1">{{ 'dashboard.recordings.channel' | translate
}}</th>
<th style="flex-grow: 15; flex-basis: 0;" class="p-1" pSortableColumn="Recording.RecGroup">
<th style="flex-basis: 8%" class="p-1" pSortableColumn="Recording.RecGroup">
{{ 'dashboard.recordings.recgrp' | translate }} <p-sortIcon
field="Recording.RecGroup"></p-sortIcon> </th>
<th style="flex-grow: 10; flex-basis: 0;" class="justify-content-end p-1">
<th style="flex-basis: 6%" class="justify-content-end p-1">
{{ 'dashboard.recordings.duration' | translate }}
</th>
<th style="flex-grow: 20; flex-basis: 0;" class="justify-content-end p-1">{{
<th style="flex-basis: 8%" class="justify-content-end p-1">{{
'dashboard.recordings.file_size' | translate }}</th>
<th style="flex-grow: 3; flex-basis: 0;" class="p-1">
<th style="flex-basis: 2%" class="p-1">
<button pButton pRipple icon="pi pi-ellipsis-v" class="p-button-text p-button-primary"></button>
</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-program>
<tr height="25" [ngClass]="{'line-through' : program.Recording.RecGroup == 'Deleted'}">
<td style="flex-grow: 40; flex-basis: 0;" class="p-1 white-space-nowrap overflow-hidden">
<tr [ngClass]="{'line-through' : program.Recording.RecGroup == 'Deleted'}">
<td style="flex-basis: 12%" class="p-1 overflow-hidden">
{{program.Title}}</td>
<td style="flex-grow: 3; flex-basis: 0;" class="p-1">
<td style="flex-basis: 2%" class="p-1">
<i class="pi pi-eye" *ngIf="program.ProgramFlagNames.indexOf('WATCHED') > -1"></i>
</td>
<td style="flex-grow: 45; flex-basis: 0;" class="p-1 white-space-nowrap overflow-hidden">
<td style="flex-basis: 18%" class="p-1 overflow-hidden">
{{program.SubTitle}}</td>
<td style="flex-grow: 10; flex-basis: 0;" class="p-1">{{program.Season}}x{{program.Episode}}</td>
<td style="flex-grow: 20; flex-basis: 0;" class="justify-content-end p-1">
<td style="flex-basis: 4%" class="p-1">{{program.Season}}x{{program.Episode}}</td>
<td style="flex-basis: 8%" class="justify-content-end p-1">
{{formatDate(program.Airdate)}}</td>
<td style="flex-grow: 20; flex-basis: 0;" class="justify-content-end p-1">
<td style="flex-basis: 8%" class="justify-content-end p-1">
{{formatDate(program.StartTime)}}</td>
<td style="flex-grow: 25; flex-basis: 0;" class="p-1">
{{program.Channel.ChanNum}}/{{program.Channel.CallSign}}</td>
<td style="flex-grow: 15; flex-basis: 0;" class="p-1">{{program.Recording.RecGroup}}</td>
<td style="flex-grow: 10; flex-basis: 0;" class="justify-content-end p-1">{{ getDuration(program) |
<td style="flex-basis: 10%" class="p-1">
{{program.Channel.ChanNum}} {{program.Channel.CallSign}}</td>
<td style="flex-basis: 8%" class="p-1">{{program.Recording.RecGroup}}</td>
<td style="flex-basis: 6%" class="justify-content-end p-1">{{ getDuration(program) |
number:'1.0-0' }} min</td>
<td style="flex-grow: 20; flex-basis: 0;" class="justify-content-end p-1">
<td style="flex-basis: 8%" class="justify-content-end p-1">
{{program.Recording.FileSize / 1000000 | number:'1.0-0'}} MB</td>
<td style="flex-grow: 3; flex-basis: 0;" class="p-1">
<td style="flex-basis: 2%" class="p-1">
<button pButton pRipple icon="pi pi-ellipsis-v" class="p-button-text p-button-primary"
(click)="showMenu(program,$event)"></button>
</td>
Expand Down
Empty file.
@@ -0,0 +1 @@
<h2>Coming soon</h2>
@@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { RecrulesComponent } from './recrules.component';

describe('RecrulesComponent', () => {
let component: RecrulesComponent;
let fixture: ComponentFixture<RecrulesComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ RecrulesComponent ]
})
.compileComponents();
});

beforeEach(() => {
fixture = TestBed.createComponent(RecrulesComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';

@Component({
selector: 'app-recrules',
templateUrl: './recrules.component.html',
styleUrls: ['./recrules.component.css']
})
export class RecrulesComponent implements OnInit {

constructor() { }

ngOnInit(): void {
}

}

0 comments on commit dfc19de

Please sign in to comment.