Merge pull request #5041 from GabrielInTheWorld/reworkMotionCommands
Separates the menu for multi-select of motions
This commit is contained in:
commit
f9cea53659
@ -136,5 +136,11 @@
|
||||
<mat-icon>clear</mat-icon>
|
||||
<span translate>Deselect all</span>
|
||||
</button>
|
||||
|
||||
<ng-container *osPerms="'motions.can_manage'; or: 'motions.can_manage_metadata'">
|
||||
<mat-divider></mat-divider>
|
||||
<os-motion-multiselect-actions [selectedMotions]="selectedRows" (action)="multiselectWrapper($event)">
|
||||
</os-motion-multiselect-actions>
|
||||
</ng-container>
|
||||
</div>
|
||||
</mat-menu>
|
||||
|
@ -3,6 +3,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { E2EImportsModule } from 'e2e-imports.module';
|
||||
|
||||
import { AmendmentListComponent } from './amendment-list.component';
|
||||
import { MotionMultiselectActionsComponent } from '../shared-motion/motion-multiselect-actions/motion-multiselect-actions.component';
|
||||
|
||||
describe('AmendmentListComponent', () => {
|
||||
let component: AmendmentListComponent;
|
||||
@ -11,7 +12,7 @@ describe('AmendmentListComponent', () => {
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [E2EImportsModule],
|
||||
declarations: [AmendmentListComponent]
|
||||
declarations: [AmendmentListComponent, MotionMultiselectActionsComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
|
@ -13,11 +13,13 @@ import { AmendmentSortListService } from '../../services/amendment-sort-list.ser
|
||||
import { StorageService } from 'app/core/core-services/storage.service';
|
||||
import { MotionRepositoryService } from 'app/core/repositories/motions/motion-repository.service';
|
||||
import { LinenumberingService } from 'app/core/ui-services/linenumbering.service';
|
||||
import { OverlayService } from 'app/core/ui-services/overlay.service';
|
||||
import { ItemVisibilityChoices } from 'app/shared/models/agenda/item';
|
||||
import { largeDialogSettings } from 'app/shared/utils/dialog-settings';
|
||||
import { BaseListViewComponent } from 'app/site/base/base-list-view';
|
||||
import { MotionExportDialogComponent } from '../shared-motion/motion-export-dialog/motion-export-dialog.component';
|
||||
import { MotionExportInfo, MotionExportService } from '../../services/motion-export.service';
|
||||
import { MotionMultiselectService } from '../../services/motion-multiselect.service';
|
||||
import { MotionPdfExportService } from '../../services/motion-pdf-export.service';
|
||||
import { MotionSortListService } from '../../services/motion-sort-list.service';
|
||||
import { ViewMotion } from '../../models/view-motion';
|
||||
@ -92,12 +94,14 @@ export class AmendmentListComponent extends BaseListViewComponent<ViewMotion> im
|
||||
private route: ActivatedRoute,
|
||||
public motionRepo: MotionRepositoryService,
|
||||
public motionSortService: MotionSortListService,
|
||||
public motionMultiSelectService: MotionMultiselectService,
|
||||
public amendmentSortService: AmendmentSortListService,
|
||||
public amendmentFilterService: AmendmentFilterListService,
|
||||
private dialog: MatDialog,
|
||||
private motionExport: MotionExportService,
|
||||
private linenumberingService: LinenumberingService,
|
||||
private pdfExport: MotionPdfExportService
|
||||
private pdfExport: MotionPdfExportService,
|
||||
private overlayService: OverlayService
|
||||
) {
|
||||
super(titleService, translate, matSnackBar, storage);
|
||||
super.setTitle('Amendments');
|
||||
@ -155,6 +159,15 @@ export class AmendmentListComponent extends BaseListViewComponent<ViewMotion> im
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to await the promises. Afterwards it will hide the spinner.
|
||||
*
|
||||
* @param action The promise to await.
|
||||
*/
|
||||
public async multiselectWrapper(action: Promise<void>): Promise<void> {
|
||||
action.then(() => this.overlayService.hideSpinner(), this.raiseError);
|
||||
}
|
||||
|
||||
/**
|
||||
* Export the given motion ist as special PDF
|
||||
*/
|
||||
|
@ -325,107 +325,27 @@
|
||||
<mat-icon>clear</mat-icon>
|
||||
<span translate>Deselect all</span>
|
||||
</button>
|
||||
<div *ngIf="perms.isAllowed('change_metadata')">
|
||||
<ng-container *ngIf="perms.isAllowed('change_metadata')">
|
||||
<mat-divider></mat-divider>
|
||||
<button
|
||||
mat-menu-item
|
||||
[disabled]="!selectedRows.length"
|
||||
(click)="multiselectWrapper(multiselectService.bulkSetFavorite(selectedRows))"
|
||||
>
|
||||
<mat-icon>star</mat-icon>
|
||||
<span translate>Set favorite</span>
|
||||
</button>
|
||||
<button
|
||||
mat-menu-item
|
||||
[disabled]="!selectedRows.length"
|
||||
(click)="multiselectWrapper(multiselectService.setStateOfMultiple(selectedRows))"
|
||||
>
|
||||
<mat-icon>label</mat-icon>
|
||||
<span translate>Set status</span>
|
||||
</button>
|
||||
<button
|
||||
*ngIf="recommendationEnabled"
|
||||
[disabled]="!selectedRows.length"
|
||||
mat-menu-item
|
||||
(click)="multiselectWrapper(multiselectService.setRecommendation(selectedRows))"
|
||||
>
|
||||
<mat-icon>report</mat-icon>
|
||||
<!-- TODO: better icon -->
|
||||
<span translate>Set recommendation</span>
|
||||
</button>
|
||||
<button
|
||||
mat-menu-item
|
||||
[disabled]="!selectedRows.length"
|
||||
*ngIf="categories.length"
|
||||
(click)="multiselectWrapper(multiselectService.setCategory(selectedRows))"
|
||||
>
|
||||
<mat-icon>category</mat-icon>
|
||||
<!-- TODO: icon -->
|
||||
<span translate>Set category</span>
|
||||
</button>
|
||||
<button
|
||||
mat-menu-item
|
||||
*ngIf="motionBlocks.length"
|
||||
[disabled]="!selectedRows.length"
|
||||
(click)="multiselectWrapper(multiselectService.setMotionBlock(selectedRows))"
|
||||
>
|
||||
<mat-icon>widgets</mat-icon>
|
||||
<!-- TODO: icon -->
|
||||
<span translate>Set motion block</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
mat-menu-item
|
||||
[disabled]="!selectedRows.length"
|
||||
(click)="multiselectWrapper(multiselectService.changeSubmitters(selectedRows))"
|
||||
>
|
||||
<mat-icon>person_add</mat-icon>
|
||||
<!-- TODO: icon -->
|
||||
<span translate>Add/remove submitters</span>
|
||||
</button>
|
||||
<button
|
||||
mat-menu-item
|
||||
*ngIf="tags.length"
|
||||
[disabled]="!selectedRows.length"
|
||||
(click)="multiselectWrapper(multiselectService.changeTags(selectedRows))"
|
||||
>
|
||||
<mat-icon>bookmarks</mat-icon>
|
||||
<!-- TODO: icon -->
|
||||
<span translate>Add/remove tags</span>
|
||||
</button>
|
||||
<button
|
||||
mat-menu-item
|
||||
[disabled]="!selectedRows.length"
|
||||
(click)="multiselectWrapper(multiselectService.moveToItem(selectedRows))"
|
||||
>
|
||||
<mat-icon>sort</mat-icon>
|
||||
<span translate>Move to agenda item</span>
|
||||
</button>
|
||||
<button
|
||||
mat-menu-item
|
||||
[disabled]="!selectedRows.length"
|
||||
(click)="multiselectWrapper(multiselectService.bulkMoveItems(selectedRows))"
|
||||
>
|
||||
<mat-icon>format_indent_increase</mat-icon>
|
||||
<span translate>Move in call list</span>
|
||||
</button>
|
||||
</div>
|
||||
<div *ngIf="perms.isAllowed('manage')">
|
||||
<button mat-menu-item [disabled]="!selectedRows.length" (click)="openExportDialog()">
|
||||
<mat-icon>archive</mat-icon>
|
||||
<span translate>Export selected motions</span>
|
||||
</button>
|
||||
<mat-divider></mat-divider>
|
||||
<button
|
||||
mat-menu-item
|
||||
class="red-warning-text"
|
||||
[disabled]="!selectedRows.length"
|
||||
(click)="multiselectWrapper(multiselectService.delete(selectedRows)); toggleMultiSelect()"
|
||||
>
|
||||
<mat-icon>delete</mat-icon>
|
||||
<span translate>Delete</span>
|
||||
</button>
|
||||
</div>
|
||||
<os-motion-multiselect-actions [selectedMotions]="selectedRows" (action)="multiselectWrapper($event)">
|
||||
<button
|
||||
mat-menu-item
|
||||
[disabled]="!selectedRows.length"
|
||||
(click)="multiselectWrapper(multiselectService.moveToItem(selectedRows))"
|
||||
>
|
||||
<mat-icon>sort</mat-icon>
|
||||
<span translate>Move to agenda item</span>
|
||||
</button>
|
||||
<button
|
||||
mat-menu-item
|
||||
[disabled]="!selectedRows.length"
|
||||
(click)="multiselectWrapper(multiselectService.bulkMoveItems(selectedRows))"
|
||||
>
|
||||
<mat-icon>format_indent_increase</mat-icon>
|
||||
<span translate>Move in call list</span>
|
||||
</button>
|
||||
</os-motion-multiselect-actions>
|
||||
</ng-container>
|
||||
</div>
|
||||
</mat-menu>
|
||||
|
||||
|
@ -3,6 +3,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { E2EImportsModule } from 'e2e-imports.module';
|
||||
|
||||
import { MotionListComponent } from './motion-list.component';
|
||||
import { MotionMultiselectActionsComponent } from '../../../shared-motion/motion-multiselect-actions/motion-multiselect-actions.component';
|
||||
|
||||
describe('MotionListComponent', () => {
|
||||
let component: MotionListComponent;
|
||||
@ -11,7 +12,7 @@ describe('MotionListComponent', () => {
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [E2EImportsModule],
|
||||
declarations: [MotionListComponent]
|
||||
declarations: [MotionListComponent, MotionMultiselectActionsComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
|
@ -362,13 +362,7 @@ export class MotionListComponent extends BaseListViewComponent<ViewMotion> imple
|
||||
* @param multiselectPromise The promise returned by multiselect actions.
|
||||
*/
|
||||
public async multiselectWrapper(multiselectPromise: Promise<void>): Promise<void> {
|
||||
try {
|
||||
await multiselectPromise;
|
||||
} catch (e) {
|
||||
this.raiseError(e);
|
||||
} finally {
|
||||
this.overlayService.hideSpinner();
|
||||
}
|
||||
multiselectPromise.then(() => this.overlayService.hideSpinner(), this.raiseError);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,85 @@
|
||||
<button
|
||||
mat-menu-item
|
||||
[disabled]="!selectedMotions.length"
|
||||
(click)="action.emit(multiselectService.bulkSetFavorite(selectedMotions))"
|
||||
>
|
||||
<mat-icon>star</mat-icon>
|
||||
<span translate>Set favorite</span>
|
||||
</button>
|
||||
<button
|
||||
mat-menu-item
|
||||
[disabled]="!selectedMotions.length"
|
||||
(click)="action.emit(multiselectService.setStateOfMultiple(selectedMotions))"
|
||||
>
|
||||
<mat-icon>label</mat-icon>
|
||||
<span translate>Set status</span>
|
||||
</button>
|
||||
<button
|
||||
*ngIf="recommendationEnabled"
|
||||
[disabled]="!selectedMotions.length"
|
||||
mat-menu-item
|
||||
(click)="action.emit(multiselectService.setRecommendation(selectedMotions))"
|
||||
>
|
||||
<mat-icon>report</mat-icon>
|
||||
<!-- TODO: better icon -->
|
||||
<span translate>Set recommendation</span>
|
||||
</button>
|
||||
<button
|
||||
mat-menu-item
|
||||
[disabled]="!selectedMotions.length"
|
||||
*ngIf="categories.length"
|
||||
(click)="action.emit(multiselectService.setCategory(selectedMotions))"
|
||||
>
|
||||
<mat-icon>category</mat-icon>
|
||||
<!-- TODO: icon -->
|
||||
<span translate>Set category</span>
|
||||
</button>
|
||||
<button
|
||||
mat-menu-item
|
||||
*ngIf="motionBlocks.length"
|
||||
[disabled]="!selectedMotions.length"
|
||||
(click)="action.emit(multiselectService.setMotionBlock(selectedMotions))"
|
||||
>
|
||||
<mat-icon>widgets</mat-icon>
|
||||
<!-- TODO: icon -->
|
||||
<span translate>Set motion block</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
mat-menu-item
|
||||
[disabled]="!selectedMotions.length"
|
||||
(click)="action.emit(multiselectService.changeSubmitters(selectedMotions))"
|
||||
>
|
||||
<mat-icon>person_add</mat-icon>
|
||||
<!-- TODO: icon -->
|
||||
<span translate>Add/remove submitters</span>
|
||||
</button>
|
||||
<button
|
||||
mat-menu-item
|
||||
*ngIf="tags.length"
|
||||
[disabled]="!selectedMotions.length"
|
||||
(click)="action.emit(multiselectService.changeTags(selectedMotions))"
|
||||
>
|
||||
<mat-icon>bookmarks</mat-icon>
|
||||
<!-- TODO: icon -->
|
||||
<span translate>Add/remove tags</span>
|
||||
</button>
|
||||
|
||||
<ng-content></ng-content>
|
||||
|
||||
<ng-container *osPerms="'motions.can_manage'">
|
||||
<button mat-menu-item [disabled]="!selectedMotions.length" (click)="openExportDialog()">
|
||||
<mat-icon>archive</mat-icon>
|
||||
<span translate>Export selected motions</span>
|
||||
</button>
|
||||
<mat-divider></mat-divider>
|
||||
<button
|
||||
mat-menu-item
|
||||
class="red-warning-text"
|
||||
[disabled]="!selectedMotions.length"
|
||||
(click)="action.emit(multiselectService.delete(selectedMotions))"
|
||||
>
|
||||
<mat-icon>delete</mat-icon>
|
||||
<span translate>Delete</span>
|
||||
</button>
|
||||
</ng-container>
|
@ -0,0 +1,27 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { E2EImportsModule } from 'e2e-imports.module';
|
||||
|
||||
import { MotionMultiselectActionsComponent } from './motion-multiselect-actions.component';
|
||||
|
||||
describe('MotionMultiselectActionsComponent', () => {
|
||||
let component: MotionMultiselectActionsComponent;
|
||||
let fixture: ComponentFixture<MotionMultiselectActionsComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [E2EImportsModule],
|
||||
declarations: [MotionMultiselectActionsComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(MotionMultiselectActionsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,111 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { MatDialog, MatSnackBar } from '@angular/material';
|
||||
import { Title } from '@angular/platform-browser';
|
||||
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { CategoryRepositoryService } from 'app/core/repositories/motions/category-repository.service';
|
||||
import { MotionBlockRepositoryService } from 'app/core/repositories/motions/motion-block-repository.service';
|
||||
import { TagRepositoryService } from 'app/core/repositories/tags/tag-repository.service';
|
||||
import { ConfigService } from 'app/core/ui-services/config.service';
|
||||
import { largeDialogSettings } from 'app/shared/utils/dialog-settings';
|
||||
import { BaseViewComponent } from 'app/site/base/base-view';
|
||||
import { ViewCategory } from 'app/site/motions/models/view-category';
|
||||
import { ViewMotion } from 'app/site/motions/models/view-motion';
|
||||
import { ViewMotionBlock } from 'app/site/motions/models/view-motion-block';
|
||||
import { MotionExportInfo, MotionExportService } from 'app/site/motions/services/motion-export.service';
|
||||
import { MotionMultiselectService } from 'app/site/motions/services/motion-multiselect.service';
|
||||
import { ViewTag } from 'app/site/tags/models/view-tag';
|
||||
import { MotionExportDialogComponent } from '../motion-export-dialog/motion-export-dialog.component';
|
||||
|
||||
@Component({
|
||||
selector: 'os-motion-multiselect-actions',
|
||||
templateUrl: './motion-multiselect-actions.component.html',
|
||||
styleUrls: ['./motion-multiselect-actions.component.scss']
|
||||
})
|
||||
export class MotionMultiselectActionsComponent extends BaseViewComponent implements OnInit {
|
||||
/**
|
||||
* The list of the selected motions.
|
||||
*/
|
||||
@Input()
|
||||
public selectedMotions: ViewMotion[] = [];
|
||||
|
||||
/**
|
||||
* An EventEmitter to send the selected actions.
|
||||
*/
|
||||
@Output()
|
||||
public action = new EventEmitter<Promise<void>>();
|
||||
|
||||
/**
|
||||
* Boolean, if the recommendation is enabled.
|
||||
*/
|
||||
public recommendationEnabled = false;
|
||||
|
||||
/**
|
||||
* The list of all categories.
|
||||
*/
|
||||
public categories: ViewCategory[] = [];
|
||||
|
||||
/**
|
||||
* The list of all tags.
|
||||
*/
|
||||
public tags: ViewTag[] = [];
|
||||
|
||||
/**
|
||||
* The list of all motion-blocks.
|
||||
*/
|
||||
public motionBlocks: ViewMotionBlock[] = [];
|
||||
|
||||
/**
|
||||
* The default constructor.
|
||||
*
|
||||
* @param multiselectService
|
||||
* @param categoryRepo
|
||||
* @param motionBlockRepo
|
||||
* @param tagRepo
|
||||
* @param configService
|
||||
*/
|
||||
public constructor(
|
||||
title: Title,
|
||||
protected translate: TranslateService,
|
||||
matSnackbar: MatSnackBar,
|
||||
public multiselectService: MotionMultiselectService,
|
||||
private categoryRepo: CategoryRepositoryService,
|
||||
private motionBlockRepo: MotionBlockRepositoryService,
|
||||
private tagRepo: TagRepositoryService,
|
||||
private configService: ConfigService,
|
||||
private dialog: MatDialog,
|
||||
private motionExport: MotionExportService
|
||||
) {
|
||||
super(title, translate, matSnackbar);
|
||||
}
|
||||
|
||||
/**
|
||||
* OnInit-method.
|
||||
*
|
||||
* Subscribe to all view-model-lists.
|
||||
*/
|
||||
public ngOnInit(): void {
|
||||
this.subscriptions.push(
|
||||
this.categoryRepo.getViewModelListObservable().subscribe(categories => (this.categories = categories)),
|
||||
this.motionBlockRepo.getViewModelListObservable().subscribe(blocks => (this.motionBlocks = blocks)),
|
||||
this.tagRepo.getViewModelListObservable().subscribe(tags => (this.tags = tags)),
|
||||
this.configService.get<string>('motions_recommendations_by').subscribe(recommender => {
|
||||
this.recommendationEnabled = !!recommender;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the dialog to choose options for exporting selected motions.
|
||||
*/
|
||||
public openExportDialog(): void {
|
||||
const exportDialogRef = this.dialog.open(MotionExportDialogComponent, largeDialogSettings);
|
||||
|
||||
exportDialogRef
|
||||
.afterClosed()
|
||||
.subscribe((exportInfo: MotionExportInfo) =>
|
||||
this.motionExport.evaluateExportRequest(exportInfo, this.selectedMotions)
|
||||
);
|
||||
}
|
||||
}
|
@ -3,10 +3,12 @@ import { NgModule } from '@angular/core';
|
||||
|
||||
import { SharedModule } from 'app/shared/shared.module';
|
||||
import { MotionExportDialogComponent } from './motion-export-dialog/motion-export-dialog.component';
|
||||
import { MotionMultiselectActionsComponent } from './motion-multiselect-actions/motion-multiselect-actions.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, SharedModule],
|
||||
declarations: [MotionExportDialogComponent],
|
||||
exports: [MotionMultiselectActionsComponent],
|
||||
declarations: [MotionExportDialogComponent, MotionMultiselectActionsComponent],
|
||||
entryComponents: [MotionExportDialogComponent]
|
||||
})
|
||||
export class SharedMotionModule {}
|
||||
|
Loading…
Reference in New Issue
Block a user