Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions src/app/actions/movemessage.action.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// --------- BEGIN RUNBOX LICENSE ---------
// Copyright (C) 2016-2026 Runbox Solutions AS (runbox.com).
//
// This file is part of Runbox 7.
//
// Runbox 7 is free software: You can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// Runbox 7 is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Runbox 7. If not, see <https://www.gnu.org/licenses/>.
// ---------- END RUNBOX LICENSE ----------

import { of } from 'rxjs';
import { MatLegacyDialogRef as MatDialogRef } from '@angular/material/legacy-dialog';

import { FolderListEntry } from '../common/folderlistentry';
import { RunboxWebmailAPI } from '../rmmapi/rbwebmail';
import { MoveMessageDialogComponent } from './movemessage.action';

describe('MoveMessageDialogComponent', () => {
const folders = [
new FolderListEntry(1, 0, 10, 'inbox', 'Inbox', 'Inbox', 0),
new FolderListEntry(2, 0, 5, 'user', 'Projects', 'Archive/Projects', 1),
new FolderListEntry(3, 0, 2, 'user', 'Invoices', 'Archive/Invoices', 1),
new FolderListEntry(4, 0, 4, 'sent', 'Sent', 'Sent', 0),
new FolderListEntry(5, 0, 1, 'drafts', 'Drafts', 'Drafts', 0),
new FolderListEntry(6, 0, 1, 'templates', 'Templates', 'Templates', 0),
];

let dialogRef: MatDialogRef<MoveMessageDialogComponent>;
let component: MoveMessageDialogComponent;

beforeEach(() => {
dialogRef = {
close: jasmine.createSpy('close'),
} as unknown as MatDialogRef<MoveMessageDialogComponent>;
const rmmapi = {
getFolderList: () => of(folders),
} as unknown as RunboxWebmailAPI;
component = new MoveMessageDialogComponent(dialogRef, rmmapi);
});

it('should exclude folders that cannot be used as move targets', () => {
component.ngOnInit();

expect(component.folderListEntries.map(folder => folder.folderName))
.toEqual(['Inbox', 'Projects', 'Invoices']);
expect(component.filteredFolderListEntries.map(folder => folder.folderName))
.toEqual(['Inbox', 'Projects', 'Invoices']);
});

it('should filter folders by name or path', () => {
component.ngOnInit();

component.folderFilter = 'archive';
component.updateFolderFilter();
expect(component.filteredFolderListEntries.map(folder => folder.folderName))
.toEqual(['Projects', 'Invoices']);

component.folderFilter = 'invoice';
component.updateFolderFilter();
expect(component.filteredFolderListEntries.map(folder => folder.folderName))
.toEqual(['Invoices']);
});

it('should close with the selected folder id', () => {
component.moveMessages(3);

expect(dialogRef.close).toHaveBeenCalledWith(3);
});
});
59 changes: 52 additions & 7 deletions src/app/actions/movemessage.action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,19 @@ import { RunboxWebmailAPI } from '../rmmapi/rbwebmail';
@Component({
template: `
<mat-spinner *ngIf="moving"></mat-spinner>
<mat-dialog-content *ngIf="!moving">
<mat-nav-list dense id="moveMessagesToFolderList">
<mat-list-item *ngFor="let fce of folderListEntries" (click)="moveMessages(fce.folderId)"
<mat-dialog-content *ngIf="!moving" class="moveMessagesToFolderContent">
<mat-form-field class="moveMessagesFolderFilter">
<mat-label>Search folders</mat-label>
<input matInput
type="search"
autocomplete="off"
[(ngModel)]="folderFilter"
(ngModelChange)="updateFolderFilter()"
>
</mat-form-field>

<mat-nav-list *ngIf="filteredFolderListEntries.length" dense id="moveMessagesToFolderList">
<mat-list-item *ngFor="let fce of filteredFolderListEntries" (click)="moveMessages(fce.folderId)"
[style.paddingLeft.px]="fce.folderLevel*10"
>
<mat-icon *ngIf="fce.folderType==='inbox'" mat-list-icon class="folderIconStandard" svgIcon="inbox-arrow-down"></mat-icon>
Expand All @@ -39,12 +49,31 @@ import { RunboxWebmailAPI } from '../rmmapi/rbwebmail';
<p mat-line>{{fce.folderName}}</p>
</mat-list-item>
</mat-nav-list>
<p *ngIf="folderListEntries.length && !filteredFolderListEntries.length" class="moveMessagesNoMatches">
No matching folders
</p>
</mat-dialog-content>
`
`,
styles: [`
.moveMessagesToFolderContent {
min-width: min(420px, 90vw);
}

.moveMessagesFolderFilter {
width: 100%;
}

.moveMessagesNoMatches {
margin: 12px 0;
opacity: 0.75;
}
`]
})
export class MoveMessageDialogComponent implements OnInit {
moving = false;
folderListEntries: FolderListEntry[];
folderFilter = '';
folderListEntries: FolderListEntry[] = [];
filteredFolderListEntries: FolderListEntry[] = [];

constructor(
public dialogRef: MatDialogRef<MoveMessageDialogComponent>,
Expand All @@ -54,12 +83,28 @@ export class MoveMessageDialogComponent implements OnInit {

ngOnInit() {
this.rmmapi.getFolderList()
.subscribe((folderListEntries) => this.folderListEntries = folderListEntries
.subscribe((folderListEntries) => {
this.folderListEntries = folderListEntries
.filter(fce =>
fce.folderType !== 'drafts' &&
fce.folderType !== 'sent' &&
fce.folderType !== 'templates'
));
);
this.updateFolderFilter();
});
}

public updateFolderFilter() {
const folderFilter = this.folderFilter.trim().toLowerCase();
if (!folderFilter) {
this.filteredFolderListEntries = this.folderListEntries;
return;
}

this.filteredFolderListEntries = this.folderListEntries.filter(fce =>
fce.folderName.toLowerCase().includes(folderFilter) ||
fce.folderPath.toLowerCase().includes(folderFilter)
);
}

public moveMessages(folderId: number) {
Expand Down
4 changes: 2 additions & 2 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import { MatLegacyCardModule as MatCardModule } from '@angular/material/legacy-c
import { MatLegacyCheckboxModule as MatCheckboxModule } from '@angular/material/legacy-checkbox';
import { MatLegacyDialogModule as MatDialogModule } from '@angular/material/legacy-dialog';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatLegacyFormFieldModule as MatFormFieldModule } from '@angular/material/legacy-form-field';
import { MatIconModule, MatIconRegistry } from '@angular/material/icon';
import { DomSanitizer } from '@angular/platform-browser';
import { MatLegacyInputModule as MatInputModule } from '@angular/material/legacy-input';
Expand Down Expand Up @@ -155,7 +156,7 @@ const routes: Routes = [
MatExpansionModule,
MatListModule,
MatMenuModule,
MatCardModule, MatInputModule,
MatCardModule, MatFormFieldModule, MatInputModule,
MenuModule,
MatCheckboxModule,
MatToolbarModule,
Expand Down Expand Up @@ -213,4 +214,3 @@ export class AppModule {
);
}
}