enhance motion tables with observer

This commit is contained in:
Sean Engelhardt 2018-08-09 13:27:04 +02:00 committed by FinnStutzenstein
parent 8cfb5bf597
commit 0099c34615
6 changed files with 149 additions and 119 deletions

1
.gitignore vendored
View File

@ -65,6 +65,7 @@ client/node_modules
!.vscode/extensions.json !.vscode/extensions.json
# misc # misc
Compodoc
client/.sass-cache client/.sass-cache
client/connect.lock client/connect.lock
client/coverage client/coverage

View File

@ -13,7 +13,8 @@ import {
MatSidenavModule, MatSidenavModule,
MatSnackBarModule, MatSnackBarModule,
MatTableModule, MatTableModule,
MatPaginatorModule MatPaginatorModule,
MatSortModule
} from '@angular/material'; } from '@angular/material';
import { MatDialogModule } from '@angular/material/dialog'; import { MatDialogModule } from '@angular/material/dialog';
import { MatListModule } from '@angular/material/list'; import { MatListModule } from '@angular/material/list';
@ -33,6 +34,7 @@ import { OsPermsDirective } from './directives/os-perms.directive';
import { DomChangeDirective } from './directives/dom-change.directive'; import { DomChangeDirective } from './directives/dom-change.directive';
import { LegalnoticeDialogComponent } from './components/legal-notice/legal-notice.dialog.component'; import { LegalnoticeDialogComponent } from './components/legal-notice/legal-notice.dialog.component';
import { PrivacyPolicyDialogComponent } from './components/privacy-policy/privacy-policy.dialog.component'; import { PrivacyPolicyDialogComponent } from './components/privacy-policy/privacy-policy.dialog.component';
// import { CdkTableModule } from '@angular/cdk/table';
library.add(fas); library.add(fas);
@ -56,6 +58,7 @@ library.add(fas);
MatCardModule, MatCardModule,
MatInputModule, MatInputModule,
MatTableModule, MatTableModule,
MatSortModule,
MatPaginatorModule, MatPaginatorModule,
MatProgressSpinnerModule, MatProgressSpinnerModule,
MatSidenavModule, MatSidenavModule,
@ -75,6 +78,7 @@ library.add(fas);
MatCardModule, MatCardModule,
MatInputModule, MatInputModule,
MatTableModule, MatTableModule,
MatSortModule,
MatPaginatorModule, MatPaginatorModule,
MatProgressSpinnerModule, MatProgressSpinnerModule,
MatSidenavModule, MatSidenavModule,

View File

@ -14,7 +14,7 @@
</mat-toolbar> </mat-toolbar>
<div class='custom-table-header'> <div class='custom-table-header on-transition-fade'>
<button mat-button> <button mat-button>
SORIEREN NACH SORIEREN NACH
</button> </button>
@ -23,43 +23,47 @@
</button> </button>
</div> </div>
<table mat-table [dataSource]="dataSource" matSort> <mat-table class='on-transition-fade' [dataSource]="dataSource" matSort>
<!-- identifier column --> <!-- identifier column -->
<ng-container matColumnDef="identifier"> <ng-container matColumnDef="identifier">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Bezeichner </th> <mat-header-cell *matHeaderCellDef mat-sort-header> Bezeichner </mat-header-cell>
<td mat-cell *matCellDef="let motion"> <mat-cell *matCellDef="let motion">
<span> <div class='innerTable'>
{{motion.identifier}} {{motion.identifier}}
</span> </div>
</td> </mat-cell>
</ng-container> </ng-container>
<!-- title column --> <!-- title column -->
<ng-container matColumnDef="title"> <ng-container matColumnDef="title">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Titel </th> <mat-header-cell *matHeaderCellDef mat-sort-header> Titel </mat-header-cell>
<td mat-cell *matCellDef="let motion"> <mat-cell *matCellDef="let motion">
<span class='motion-list-title'>{{motion.versions[0].title}}</span> <div class='innerTable'>
<br> <span class='motion-list-title'>{{motion.versions[0].title}}</span>
<span class='motion-list-from'> <br>
<span translate>von</span> <span class='motion-list-from'>
{{motion.submitterAsUser.username}} <span translate>von</span>
</span> {{motion.submitterAsUser.username}}
</td> </span>
</div>
</mat-cell>
</ng-container> </ng-container>
<!-- state column --> <!-- state column -->
<ng-container matColumnDef="state"> <ng-container matColumnDef="state">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Status </th> <mat-header-cell *matHeaderCellDef mat-sort-header> Status </mat-header-cell>
<td mat-cell *matCellDef="let motion"> <mat-cell *matCellDef="let motion">
<fa-icon icon={{getStateIcon(motion.stateName)}}></fa-icon> <div class='innerTable'>
<!-- <span class='motion.list.state'> <fa-icon icon={{getStateIcon(motion.stateName)}}></fa-icon>
{{motion.stateName}} <!-- <span class='motion.list.state'>
</span> --> {{motion.stateName}}
</td> </span> -->
</div>
</mat-cell>
</ng-container> </ng-container>
<tr mat-header-row *matHeaderRowDef="columnsToDisplayMinWidth"></tr> <mat-header-row *matHeaderRowDef="columnsToDisplayMinWidth"></mat-header-row>
<tr mat-row *matRowDef="let row; columns: columnsToDisplayMinWidth"></tr> <mat-row (click)='selectMotion(row)' *matRowDef="let row; columns: columnsToDisplayMinWidth"></mat-row>
</table> </mat-table>
<mat-paginator [pageSizeOptions]="[20, 40, 60, 80]"></mat-paginator> <mat-paginator class="on-transition-fade" [pageSizeOptions]="[20, 40, 60, 80]"></mat-paginator>

View File

@ -1,68 +1,67 @@
table {
/* margin-top: 40px; */
width: 100%;
display: flex;
}
/** identifier */
.mat-column-identifier {
padding-left: 10px !important;
padding-right: 10px !important;
text-align: center;
flex: 0 0 70px !important;
span {
display: block;
}
}
/** Title */
.mat-column-title {
width: 100%;
flex: 5 0 100 !important;
padding-left: 10px;
.motion-list-title {
font-weight: bold;
}
.motion-list-from {
display: block;
margin-top: 5px;
color: rgba(0, 0, 0, 0.5);
font-size: 90%;
}
}
/** State */
.mat-column-state {
flex: 0 0 30 !important;
fa-icon {
font-size: 150%;
}
}
/** has to be in the theme also */
/** hide mat header row */
.mat-header-row {
display: none;
}
/** size of the mat row */
.mat-row {
height: 60px;
}
.custom-table-header { .custom-table-header {
/* display: inline-block; */ // display: none;
width: 100%; width: 100%;
height: 60px; height: 60px;
line-height: 60px; line-height: 60px;
text-align: right; text-align: right;
/* vertical-align: middle; */
/** has to be in the theme */
background: white; background: white;
border-bottom: 1px solid rgba(0, 0, 0, 0.12); border-bottom: 1px solid rgba(0, 0, 0, 0.12);
} }
/** css hacks https://codepen.io/edge0703/pen/iHJuA */
.innerTable {
display: inline-block;
vertical-align: middle;
line-height: normal;
}
mat-table {
width: 100%;
/** hide mat header row */
.mat-header-row {
display: none;
}
/** size of the mat row */
mat-row {
height: 60px;
}
/** identifier */
.mat-column-identifier {
padding-left: 10px;
padding-right: 30px;
flex: 0 0 40px;
line-height: 60px; // set the text in the vertical middle, since vertical-align will not work
display: initial; // reset display
text-align: center; // center text
}
/** Title */
.mat-column-title {
width: 100%;
flex: 1 0 200px;
padding-left: 10px;
.motion-list-title {
font-weight: bold;
}
.motion-list-from {
margin-top: 5px;
color: rgba(0, 0, 0, 0.5);
font-size: 90%;
}
}
/** State */
.mat-column-state {
flex: 0 0 30px;
text-align: center;
fa-icon {
font-size: 150%;
}
}
}

View File

@ -3,63 +3,82 @@ import { Title } from '@angular/platform-browser';
import { BaseComponent } from 'app/base.component'; import { BaseComponent } from 'app/base.component';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { Motion } from '../../../shared/models/motions/motion'; import { Motion } from '../../../shared/models/motions/motion';
import { MatPaginator, MatSort, MatTableDataSource } from '@angular/material'; import { MatTable, MatPaginator, MatSort, MatTableDataSource } from '@angular/material';
import { Workflow } from '../../../shared/models/motions/workflow'; import { Workflow } from '../../../shared/models/motions/workflow';
export interface PeriodicElement {
state_id: string;
identifier: number;
weight: number;
symbol: string;
}
const ELEMENT_DATA: PeriodicElement[] = [
{ identifier: 1, state_id: 'Hydrogen', weight: 1.0079, symbol: 'H' },
{ identifier: 2, state_id: 'Helium', weight: 4.0026, symbol: 'He' },
{ identifier: 3, state_id: 'Lithium', weight: 6.941, symbol: 'Li' },
{ identifier: 4, state_id: 'Beryllium', weight: 9.0122, symbol: 'Be' },
{ identifier: 5, state_id: 'Boron', weight: 10.811, symbol: 'B' },
{ identifier: 6, state_id: 'Carbon', weight: 12.0107, symbol: 'C' },
{ identifier: 7, state_id: 'Nitrogen', weight: 14.0067, symbol: 'N' },
{ identifier: 8, state_id: 'Oxygen', weight: 15.9994, symbol: 'O' },
{ identifier: 9, state_id: 'Fluorine', weight: 18.9984, symbol: 'F' },
{ identifier: 10, state_id: 'Neon', weight: 20.1797, symbol: 'Ne' }
];
@Component({ @Component({
selector: 'app-motion-list', selector: 'app-motion-list',
templateUrl: './motion-list.component.html', templateUrl: './motion-list.component.html',
styleUrls: ['./motion-list.component.scss'] styleUrls: ['./motion-list.component.scss']
}) })
export class MotionListComponent extends BaseComponent implements OnInit { export class MotionListComponent extends BaseComponent implements OnInit {
/**
* Store motion workflows (to check the status of the motions)
*/
workflowArray: Array<Workflow>; workflowArray: Array<Workflow>;
motionArray: Array<Motion>;
dataSource: MatTableDataSource<Motion>;
// dataSource: MatTableDataSource<any>;
/**
* Store the motions
*/
motionArray: Array<Motion>;
/**
* Will be processed by the mat-table
*/
dataSource: MatTableDataSource<Motion>;
@ViewChild(MatTable) table: MatTable<Motion>;
@ViewChild(MatPaginator) paginator: MatPaginator; @ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort; @ViewChild(MatSort) sort: MatSort;
/** which colummns to display in the table */ /**
* Use for minimal width
*/
columnsToDisplayMinWidth = ['identifier', 'title', 'state']; columnsToDisplayMinWidth = ['identifier', 'title', 'state'];
// columnsToDisplayMinWidth = ['title']; /**
* Use for maximal width
*/
columnsToDisplayFullWidth = ['identifier', 'title', 'meta', 'state']; columnsToDisplayFullWidth = ['identifier', 'title', 'meta', 'state'];
/**
* Constructor implements title and translation Module.
* @param titleService
* @param translate
*/
constructor(titleService: Title, protected translate: TranslateService) { constructor(titleService: Title, protected translate: TranslateService) {
super(titleService, translate); super(titleService, translate);
} }
/**
* Init function
*/
ngOnInit() { ngOnInit() {
super.setTitle('Motions'); super.setTitle('Motions');
this.workflowArray = this.DS.get(Workflow) as Workflow[]; this.workflowArray = this.DS.get(Workflow) as Workflow[];
this.motionArray = this.DS.get(Motion) as Motion[]; this.motionArray = this.DS.get(Motion) as Motion[];
this.dataSource = new MatTableDataSource(this.motionArray); this.dataSource = new MatTableDataSource(this.motionArray);
// this.dataSource = new MatTableDataSource(ELEMENT_DATA);
this.dataSource.paginator = this.paginator; this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort; this.dataSource.sort = this.sort;
// Observe DataStore for motions. Initially, executes once for every motion.
// The alternative approach is to put the observable as DataSource to the table
this.DS.getObservable().subscribe(newModel => {
if (newModel instanceof Motion) {
this.motionArray.push(newModel as Motion);
this.dataSource.data = this.motionArray;
}
});
} }
selectMotion(motion) {
console.log('clicked a row, :', motion);
}
/**
* Get the icon to the coresponding Motion Status
* TODO Needs to be more accessible (Motion workflow needs adjustment on the server)
* @param stateName the name of the state
*/
getStateIcon(stateName) { getStateIcon(stateName) {
if (stateName === 'accepted') { if (stateName === 'accepted') {
return 'thumbs-up'; return 'thumbs-up';
@ -70,6 +89,9 @@ export class MotionListComponent extends BaseComponent implements OnInit {
} }
} }
/**
* Download all motions As PDF and DocX
*/
downloadMotionsButton() { downloadMotionsButton() {
console.log('Download Motions Button'); console.log('Download Motions Button');
} }

View File

@ -39,11 +39,11 @@ export class StartComponent extends BaseComponent implements OnInit {
* Set title and observe DataStore for changes. * Set title and observe DataStore for changes.
*/ */
ngOnInit() { ngOnInit() {
//required dummy translation, cause translations for config values were never set // required dummy translation, cause translations for config values were never set
const welcomeTitleTranslateDummy = this.translate.instant('Welcome to OpenSlides'); const welcomeTitleTranslateDummy = this.translate.instant('Welcome to OpenSlides');
super.setTitle('Home'); super.setTitle('Home');
//set welcome title and text // set welcome title and text
const welcomeTitleConfig = this.DS.filter( const welcomeTitleConfig = this.DS.filter(
Config, Config,
config => config.key === 'general_event_welcome_title' config => config.key === 'general_event_welcome_title'
@ -63,7 +63,7 @@ export class StartComponent extends BaseComponent implements OnInit {
} }
console.log(this.DS.filter(Config, config => config.key === 'general_event_welcome_title')); console.log(this.DS.filter(Config, config => config.key === 'general_event_welcome_title'));
//observe title and text in DS // observe title and text in DS
this.DS.getObservable().subscribe(newModel => { this.DS.getObservable().subscribe(newModel => {
if (newModel instanceof Config) { if (newModel instanceof Config) {
if (newModel.key === 'general_event_welcome_title') { if (newModel.key === 'general_event_welcome_title') {