Skip to content

Commit

Permalink
Merge pull request runbox#1613 from shadowbas/feature-create-draft-on…
Browse files Browse the repository at this point in the history
…-template-item-click

feat(templates): Create draft on template item click
  • Loading branch information
castaway authored Nov 11, 2024
2 parents 7498a3a + 3f0b333 commit 8142db4
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 43 deletions.
16 changes: 14 additions & 2 deletions e2e/cypress/integration/compose.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ describe('Composing emails', () => {
cy.visit('/compose');
cy.wait('@listAllmessages', {'timeout':10000});
cy.visit('/compose?new=true');

cy.get('button[mattooltip="Close draft"').click();
cy.location().should((loc) => {
expect(loc.pathname).to.eq('/compose');
Expand Down Expand Up @@ -141,7 +141,7 @@ describe('Composing emails', () => {
cy.location().should((loc) => {
expect(loc.pathname).to.eq('/contacts/id-mr-postcode');
expect(loc.search).to.eq('');
});
});
});

it('should find the same address in original "To" and our "From" field in Reply', () => {
Expand All @@ -152,4 +152,16 @@ describe('Composing emails', () => {
cy.get('button[mattooltip="Reply"]').click();
cy.get('.mat-select-value-text span').contains(address, { matchCase: false });
});

it('should show a save template button and save on click', () => {
cy.visit('/compose?new=true');
cy.get('input[data-placeholder="Subject"]').type('Template subject here');
cy.get('button[mattooltip="Save as template"').click();
cy.location().should((loc) => {
expect(loc.pathname).to.eq('/compose');
expect(loc.search).to.eq('?new=true');
});

cy.get('snack-bar-container').should('contain', 'Saved to templates');
})
});
13 changes: 13 additions & 0 deletions e2e/cypress/integration/folders.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
/// <reference types="cypress" />

describe('Folder management', () => {
function canvas() {
return cy.get('canvastable canvas:first-of-type');
}

it('should create folder at root level', () => {
cy.visit('/');

Expand All @@ -26,4 +30,13 @@ describe('Folder management', () => {
cy.contains('div.mat-menu-content button', 'Empty trash').click();
cy.wait('@emptyTrashReq');
});

it('should create new draft on templates folder message click', () => {
cy.visit('/')
cy.contains('mat-tree-node', 'Templates').click()
canvas().click({ x: 55, y: 40 });
cy.location().should((loc) => {
expect(loc.pathname).to.eq('/compose');
});
})
});
37 changes: 31 additions & 6 deletions e2e/mockserver/mockserver.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
// --------- BEGIN RUNBOX LICENSE ---------
// Copyright (C) 2016-2018 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 ----------
Expand Down Expand Up @@ -105,6 +105,22 @@ export class MockServer {
'subfolders': [],
'type': 'trash'
},
{
'id': '2',
'total': 1,
'size': '344',
'name': 'Templates',
'new': 0,
'folder': 'Templates',
'type': 'templates',
'old': 296,
'msg_total': 1,
'priority': '4',
'subfolders': [],
'msg_new': 0,
'msg_size': '344',
'parent': null
},
];

vtimezone_oslo =
Expand Down Expand Up @@ -355,7 +371,7 @@ END:VCALENDAR
response.end(JSON.stringify(this.emailFoldersListResponse()));
break;
case '/mail/download_xapian_index':
response.end('');
response.end(this.templatescontents());
break;
case '/mail/download_xapian_index?inbox':
response.end(this.inboxcontents());
Expand Down Expand Up @@ -413,6 +429,15 @@ END:VCALENDAR
return trashlines.join('\n');
}

templatescontents() {
const lines = [];
for (let msg_id = 1000; msg_id < 10000; msg_id++) {
lines.push(`${msg_id} 1548071429 1547830043 Templates 1 0 0 "Template" <[email protected]> ` +
`Template2<[email protected]> TEMPLATE 709 n `);
}
return lines.join('\n');
}

inboxcontents() {
const inboxlines = [];
for (let msg_id = 1; msg_id < 10; msg_id++) {
Expand Down Expand Up @@ -844,7 +869,7 @@ END:VCALENDAR

profiles_verified() {
return {
'results':
'results':
[{
'smtp_username': null,
'email': '[email protected]',
Expand Down
23 changes: 17 additions & 6 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
// --------- BEGIN RUNBOX LICENSE ---------
// Copyright (C) 2016-2022 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 ----------
Expand Down Expand Up @@ -74,7 +74,7 @@ const LOCAL_STORAGE_SHOW_UNREAD_ONLY = 'rmm7mailViewerShowUnreadOnly';
const LOCAL_STORAGE_SHOW_POPULAR_RECIPIENTS = 'showPopularRecipients';
const LOCAL_STORAGE_INDEX_PROMPT = 'localSearchPromptDisplayed';
const TOOLBAR_LIST_BUTTON_WIDTH = 30;

@Component({
moduleId: 'angular2/app/',
// eslint-disable-next-line @angular-eslint/component-selector
Expand Down Expand Up @@ -718,7 +718,7 @@ export class AppComponent implements OnInit, AfterViewInit, CanvasTableSelectLis
) - 1;
}
}


public openMarkOpMenu() {
this.showSelectMarkOpMenu = true;
Expand Down Expand Up @@ -916,6 +916,17 @@ export class AppComponent implements OnInit, AfterViewInit, CanvasTableSelectLis
}

public rowSelected(rowIndex: number, columnIndex: number, multiSelect?: boolean) {
const isSelect = (columnIndex === 0) || multiSelect

if ((this.selectedFolder === this.messagelistservice.templateFolderName) && !isSelect) {
this.draftDeskService.newTemplateDraft(
this.canvastable.rows.getRowMessageId(rowIndex)
);
this.drafts();

return;
}

this.canvastable.rows.rowSelected(rowIndex, columnIndex, multiSelect);
this.showSelectOperations = this.canvastable.rows.anySelected();

Expand Down
35 changes: 19 additions & 16 deletions src/app/compose/compose.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,16 @@
</button>
<button *ngIf="!editing" mat-icon-button (click)="editDraft()" matTooltip="Edit draft" id="editDraftIcon">
<mat-icon svgIcon="pencil"></mat-icon>
</button>
</button>
<button *ngIf="editing" mat-icon-button matTooltip="Save as template" (click)="saveTemplate(true)" id="saveTemplate">
<mat-icon svgIcon="file-document"></mat-icon>
</button>
<button *ngIf="editing" mat-icon-button matTooltip="Send mail" (click)="submit(true)" id="sendMail">
<mat-icon svgIcon="send"></mat-icon>
</button>
</div>
</mat-card-actions>
<mat-card-subtitle>
</mat-card-actions>
<mat-card-subtitle>
<mat-form-field floatPlaceholder="always" *ngIf="editing" style="width: 100%" id="fieldFrom">
<mat-select placeholder="From" formControlName="from">
<mat-option *ngFor="let from of draftDeskservice.fromsSubject.value" [value]="from.nameAndAddress">
Expand All @@ -42,7 +45,7 @@
<span *ngFor="let t of model.to">
{{t.nameAndAddress}}
</span>
</span>
</span>
<div class="fieldRecipient">
<mailrecipient-input *ngIf="editing" style="flex-grow: 1"
[initialfocus]="model.to.length === 0"
Expand Down Expand Up @@ -86,7 +89,7 @@
[recipients]="model.cc"
(updateRecipient)="onUpdateRecipient('cc', $event)"
></mailrecipient-input>
<button mat-icon-button (click)="formGroup.controls.cc.setValue(null)"><mat-icon svgIcon="close"></mat-icon></button>
<button mat-icon-button (click)="formGroup.controls.cc.setValue(null)"><mat-icon svgIcon="close"></mat-icon></button>
</div>
<div style="display: flex;" *ngIf="editing && hasBCC" class="fieldRecipient" (drop)="recipientDropped($event, 'bcc')">
<mailrecipient-input *ngIf="editing" style="width: auto; flex-grow: 1"
Expand All @@ -96,11 +99,11 @@
></mailrecipient-input>
<button mat-icon-button (click)="formGroup.controls.bcc.setValue(null)"><mat-icon svgIcon="close"></mat-icon></button>
</div>
</mat-card-subtitle>
<mat-card-content>
</mat-card-subtitle>
<mat-card-content>
<mat-form-field *ngIf="editing" floatPlaceholder="auto" id="fieldSubject">
<input matInput placeholder="Subject" name="subject" formControlName="subject" />
</mat-form-field>
</mat-form-field>
<section *ngIf="editing" [ngClass]="{'dropzonehighlight': showDropZone, 'overdropzone': draggingOverDropZone}" (dragover)="draggingOverDropZone=true" (dragleave)="draggingOverDropZone=false" (drop)="dropFiles($event)" id="dropZone">
<h1 *ngIf="showDropZone" id="dropZoneText">Drop files here</h1>
<ng-container *ngIf="uploadProgress | async as uprogress">
Expand All @@ -127,11 +130,11 @@ <h1 *ngIf="showDropZone" id="dropZoneText">Drop files here</h1>
<button mat-icon-button id="deleteAttachment" (click)="removeAttachment(i)"><mat-icon svgIcon="delete"></mat-icon></button>
</ng-container>
</div>
</section>
</section>
<span [hidden]="editing">
{{this.model.preview}}
</span>

<div [hidden]="!editing">
<div class="draft-buttons">
<button *ngIf="editing" mat-icon-button matTooltip="Attach files" id="attachMobile" (click)="attachFilesClicked()">
Expand All @@ -142,21 +145,21 @@ <h1 *ngIf="showDropZone" id="dropZoneText">Drop files here</h1>
<textarea style="
width: 100%;
height: 300px;
"
"
[id]="selector"
[hidden]="!formGroup.value.useHTML">
</textarea>
<mat-form-field id="messageTextArea" *ngIf="!formGroup.value.useHTML" floatPlaceholder="auto">
<textarea
<textarea
#messageTextArea
placeholder="Message text"
matInput
placeholder="Message text"
matInput
formControlName="msg_body"
rows="20"
>
</textarea>
</mat-form-field>
</div>
</mat-form-field>
</div>
</mat-card-content>

</mat-card>
Loading

0 comments on commit 8142db4

Please sign in to comment.