Improve Mail editor

Resolves #3705
pull/210/head
Francis Lachapelle 2016-05-31 11:46:58 -04:00
parent 0d507ff038
commit ac229bacf6
2 changed files with 215 additions and 210 deletions

1
NEWS
View File

@ -18,6 +18,7 @@ Bug fixes
- [web] restored Catalan and Slovak translations (#3687)
- [web] fixed restore of mailboxes expansion state when multiple IMAP accounts are configured
- [web] improved CSS sanitizer for HTML messages (#3700)
- [web] fixed toolbar of mail editor when sender address was too long (#3705)
- [core] strip X- tags when securing content (#3695)
3.1.0 (2016-05-18)

View File

@ -10,219 +10,222 @@
nv-file-over="nv-file-over"
over-class="sg-over-dropzone"
uploader="editor.uploader">
<md-toolbar>
<div class="md-toolbar-tools">
<md-icon class="sg-icon-toolbar-bg">edit</md-icon>
<!-- from -->
<sg-avatar-image hide-sm="hide-sm"
sg-email="editor.message.editable.from"
size="32"><!-- avatar --></sg-avatar-image>
<md-input-container flex="flex">
<label><var:string label:value="From"/></label>
<md-select class="sg-no-wrap" name="from"
ng-model="editor.message.editable.from">
<md-option ng-value="identity" ng-repeat="identity in editor.identities">{{identity}}</md-option>
</md-select>
</md-input-container>
<div flex-gt-sm="flex-gt-sm"><!-- spacer --></div>
<md-button class="sg-icon-button" ng-click="editor.send()"
ng-disabled="!(editor.message.editable.to.length > 0 || editor.message.editable.cc.length > 0 || editor.message.editable.bcc.length > 0)">
<md-icon>send</md-icon>
</md-button>
<md-button class="sg-icon-button" ng-click="editor.save()">
<md-icon>save</md-icon>
</md-button>
<md-button class="sg-icon-button" ng-click="editor.cancel()">
<md-icon>close</md-icon>
</md-button>
</div>
</md-toolbar>
<div class="sg-dropzone">
<div layout="column" layout-align="center center" layout-fill="layout-fill">
<md-icon>file_upload</md-icon>
</div>
</div>
<md-dialog-content>
<header class="sg-padded">
<div class="msg-header-content">
<!-- to -->
<div class="pseudo-input-container">
<label class="pseudo-input-label">
<var:string label:value="To"/>
</label>
<md-chips ng-model="editor.message.editable.to"
md-separator-keys="editor.recipientSeparatorKeys"
md-transform-chip="editor.addRecipient($chip, 'to')"
sg-transform-on-blur="sg-transform-on-blur">
<md-autocomplete
class="sg-chips-autocomplete"
md-autofocus="true"
md-search-text="editor.autocomplete.to.searchText"
md-selected-item="editor.autocomplete.to.selected"
md-items="user in editor.contactFilter(editor.autocomplete.to.searchText)"
md-min-length="3"
md-delay="150"
md-no-cache="true"
label:placeholder="Add a recipient">
<md-item-template>
<span class="md-contact-suggestion">
<span class="md-contact-name"
md-highlight-text="editor.autocomplete.to.searchText"
md-highlight-flags="^i">{{user.$$fullname}}</span>
<span class="md-contact-email"
md-highlight-text="editor.autocomplete.to.searchText"
md-highlight-flags="^i">{{user.$$email}}</span>
</span>
</md-item-template>
</md-autocomplete>
<md-chip-template>{{$chip}}</md-chip-template>
</md-chips>
</div>
<!-- cc -->
<div class="pseudo-input-container ng-hide" ng-hide="editor.hideCc">
<label class="pseudo-input-label">
<var:string label:value="Cc"/>
</label>
<md-chips ng-model="editor.message.editable.cc"
md-separator-keys="editor.recipientSeparatorKeys"
md-transform-chip="editor.addRecipient($chip, 'cc')"
sg-transform-on-blur="sg-transform-on-blur">
<md-autocomplete
class="sg-chips-autocomplete"
md-search-text="editor.autocomplete.cc.searchText"
md-selected-item="editor.autocomplete.cc.selected"
md-items="user in editor.contactFilter(editor.autocomplete.cc.searchText)"
md-min-length="3"
md-delay="300"
md-no-cache="true"
label:placeholder="Add a recipient">
<md-item-template>
<span class="md-contact-suggestion">
<span class="md-contact-name"
md-highlight-text="editor.autocomplete.to.searchText"
md-highlight-flags="^i">{{user.$$fullname}}</span>
<span class="md-contact-email"
md-highlight-text="editor.autocomplete.to.searchText"
md-highlight-flags="^i">{{user.$$email}}</span>
</span>
</md-item-template>
</md-autocomplete>
<md-chip-template>{{$chip}}</md-chip-template>
</md-chips>
</div>
<!-- bcc -->
<div class="pseudo-input-container ng-hide" ng-hide="editor.hideBcc">
<label class="pseudo-input-label">
<var:string label:value="Bcc"/>
</label>
<md-chips ng-model="editor.message.editable.bcc"
md-separator-keys="editor.recipientSeparatorKeys"
md-transform-chip="editor.addRecipient($chip, 'bcc')"
sg-transform-on-blur="sg-transform-on-blur">
<md-autocomplete
class="sg-chips-autocomplete"
md-selected-item="editor.autocomplete.bcc.selected"
md-search-text="editor.autocomplete.bcc.searchText"
md-items="user in editor.contactFilter(editor.autocomplete.bcc.searchText)"
md-min-length="3"
md-delay="300"
md-no-cache="true"
label:placeholder="Add a recipient">
<md-item-template>
<span class="md-contact-suggestion">
<span class="md-contact-name"
md-highlight-text="editor.autocomplete.to.searchText"
md-highlight-flags="^i">{{user.$$fullname}}</span>
<span class="md-contact-email"
md-highlight-text="editor.autocomplete.to.searchText"
md-highlight-flags="^i">{{user.$$email}}</span>
</span>
</md-item-template>
</md-autocomplete>
<md-chip-template>{{$chip}}</md-chip-template>
</md-chips>
</div>
<!-- subject -->
<md-input-container>
<label>
<var:string label:value="Subject"/>
</label>
<input type="text" name="subject" ng-model="editor.message.editable.subject"/>
<form name="messageForm">
<md-toolbar>
<div class="md-toolbar-tools">
<!-- from -->
<sg-avatar-image class="hide-xs"
sg-email="editor.message.editable.from"
size="32"><!-- avatar --></sg-avatar-image>
<md-input-container class="sg-no-wrap">
<label><var:string label:value="From"/></label>
<md-select name="from"
ng-model="editor.message.editable.from">
<md-option ng-value="identity" ng-repeat="identity in editor.identities">{{identity}}</md-option>
</md-select>
</md-input-container>
<div flex="flex"><!-- spacer --></div>
<md-button class="sg-icon-button" ng-click="editor.send()"
ng-disabled="!(editor.message.editable.to.length > 0 || editor.message.editable.cc.length > 0 || editor.message.editable.bcc.length > 0) || messageForm.$invalid">
<md-icon>send</md-icon>
</md-button>
<md-button class="sg-icon-button" ng-click="editor.save()">
<md-icon>save</md-icon>
</md-button>
<md-button class="sg-icon-button" ng-click="editor.cancel()">
<md-icon>close</md-icon>
</md-button>
</div>
</md-toolbar>
<!-- toolbar to show cc/bcc/attachment fields -->
<div layout="column" layout-align="start end">
<md-button class="sg-icon-button " ng-show="editor.hideCc" ng-click="editor.hideCc = false">Cc</md-button>
<md-button class="sg-icon-button " ng-show="editor.hideBcc" ng-click="editor.hideBcc = false">Bcc</md-button>
<md-menu>
<md-button label:aria-label="More mail options" class="sg-icon-button" ng-click="$mdOpenMenu($event)">
<md-icon>more_vert</md-icon>
</md-button>
<md-menu-content width="4">
<md-menu-item>
<sg-checkmark ng-model="editor.message.editable.receipt">
<var:string label:value="Return Receipt"/>
</sg-checkmark>
</md-menu-item>
<md-menu-item>
<md-button class="md-primary" ng-disabled="true"><var:string label:value="Priority"/></md-button>
</md-menu-item>
<md-menu-item>
<md-button ng-click="editor.message.editable.priority = 1">
<md-icon ng-class="{ 'icon-check': editor.message.editable.priority == 1}"><!-- highest --></md-icon>
<var:string label:value="highest"/>
</md-button>
</md-menu-item>
<md-menu-item>
<md-button ng-click="editor.message.editable.priority = 2">
<md-icon ng-class="{ 'icon-check': editor.message.editable.priority == 2}"><!-- high --></md-icon>
<var:string label:value="high"/>
</md-button>
</md-menu-item>
<md-menu-item>
<md-button ng-click="editor.message.editable.priority = 3">
<md-icon ng-class="{ 'icon-check':
!editor.message.editable.priority
|| editor.message.editable.priority == 3}"><!-- normal --></md-icon>
<var:string label:value="normal"/>
</md-button>
</md-menu-item>
<md-menu-item>
<md-button ng-click="editor.message.editable.priority = 4">
<md-icon ng-class="{ 'icon-check': editor.message.editable.priority == 4}"><!-- low --></md-icon>
<var:string label:value="low"/>
</md-button>
</md-menu-item>
<md-menu-item>
<md-button ng-click="editor.message.editable.priority = 5">
<md-icon ng-class="{ 'icon-check': editor.message.editable.priority == 5}"><!-- lowest --></md-icon>
<var:string label:value="lowest"/>
</md-button>
</md-menu-item>
</md-menu-content>
</md-menu>
<div class="sg-dropzone">
<div layout="column" layout-align="center center" layout-fill="layout-fill">
<md-icon>file_upload</md-icon>
</div>
</header>
<!-- MESSAGE CONTENT -->
<div var:class="editorClass">
<textarea name="content" var:class="editorClass"
ck-locale="editor.localeCode"
ng-model="editor.message.editable.text"/>
</div>
</md-dialog-content>
<!-- ATTACHMENTS -->
<md-dialog-actions>
<div layout="row" layout-align="space-between center" layout-fill="layout-fill">
<md-dialog-content>
<header class="sg-padded">
<div class="msg-header-content">
<!-- to -->
<div class="pseudo-input-container">
<label class="pseudo-input-label">
<var:string label:value="To"/>
</label>
<md-chips ng-model="editor.message.editable.to"
md-separator-keys="editor.recipientSeparatorKeys"
md-transform-chip="editor.addRecipient($chip, 'to')"
sg-transform-on-blur="sg-transform-on-blur">
<md-autocomplete
class="sg-chips-autocomplete"
md-autofocus="true"
md-search-text="editor.autocomplete.to.searchText"
md-selected-item="editor.autocomplete.to.selected"
md-items="user in editor.contactFilter(editor.autocomplete.to.searchText)"
md-min-length="3"
md-delay="150"
md-no-cache="true"
label:placeholder="Add a recipient">
<md-item-template>
<span class="md-contact-suggestion">
<span class="md-contact-name"
md-highlight-text="editor.autocomplete.to.searchText"
md-highlight-flags="^i">{{user.$$fullname}}</span>
<span class="md-contact-email"
md-highlight-text="editor.autocomplete.to.searchText"
md-highlight-flags="^i">{{user.$$email}}</span>
</span>
</md-item-template>
</md-autocomplete>
<md-chip-template>{{$chip}}</md-chip-template>
</md-chips>
</div>
<!-- cc -->
<div class="pseudo-input-container ng-hide" ng-hide="editor.hideCc">
<label class="pseudo-input-label">
<var:string label:value="Cc"/>
</label>
<md-chips ng-model="editor.message.editable.cc"
md-separator-keys="editor.recipientSeparatorKeys"
md-transform-chip="editor.addRecipient($chip, 'cc')"
sg-transform-on-blur="sg-transform-on-blur">
<md-autocomplete
class="sg-chips-autocomplete"
md-search-text="editor.autocomplete.cc.searchText"
md-selected-item="editor.autocomplete.cc.selected"
md-items="user in editor.contactFilter(editor.autocomplete.cc.searchText)"
md-min-length="3"
md-delay="300"
md-no-cache="true"
label:placeholder="Add a recipient">
<md-item-template>
<span class="md-contact-suggestion">
<span class="md-contact-name"
md-highlight-text="editor.autocomplete.to.searchText"
md-highlight-flags="^i">{{user.$$fullname}}</span>
<span class="md-contact-email"
md-highlight-text="editor.autocomplete.to.searchText"
md-highlight-flags="^i">{{user.$$email}}</span>
</span>
</md-item-template>
</md-autocomplete>
<md-chip-template>{{$chip}}</md-chip-template>
</md-chips>
</div>
<!-- bcc -->
<div class="pseudo-input-container ng-hide" ng-hide="editor.hideBcc">
<label class="pseudo-input-label">
<var:string label:value="Bcc"/>
</label>
<md-chips ng-model="editor.message.editable.bcc"
md-separator-keys="editor.recipientSeparatorKeys"
md-transform-chip="editor.addRecipient($chip, 'bcc')"
sg-transform-on-blur="sg-transform-on-blur">
<md-autocomplete
class="sg-chips-autocomplete"
md-selected-item="editor.autocomplete.bcc.selected"
md-search-text="editor.autocomplete.bcc.searchText"
md-items="user in editor.contactFilter(editor.autocomplete.bcc.searchText)"
md-min-length="3"
md-delay="300"
md-no-cache="true"
label:placeholder="Add a recipient">
<md-item-template>
<span class="md-contact-suggestion">
<span class="md-contact-name"
md-highlight-text="editor.autocomplete.to.searchText"
md-highlight-flags="^i">{{user.$$fullname}}</span>
<span class="md-contact-email"
md-highlight-text="editor.autocomplete.to.searchText"
md-highlight-flags="^i">{{user.$$email}}</span>
</span>
</md-item-template>
</md-autocomplete>
<md-chip-template>{{$chip}}</md-chip-template>
</md-chips>
</div>
<!-- subject -->
<md-input-container>
<label>
<var:string label:value="Subject"/>
</label>
<input type="text" name="subject" ng-model="editor.message.editable.subject" ng-required="true"/>
<div ng-messages="messageForm.subject.$error">
<div ng-message="required"><var:string label:value="error_missingsubject"/></div>
</div>
</md-input-container>
</div>
<!-- toolbar to show cc/bcc/attachment fields -->
<div layout="column" layout-align="start end">
<md-button class="sg-icon-button " ng-show="editor.hideCc" ng-click="editor.hideCc = false">Cc</md-button>
<md-button class="sg-icon-button " ng-show="editor.hideBcc" ng-click="editor.hideBcc = false">Bcc</md-button>
<md-menu>
<md-button label:aria-label="More mail options" class="sg-icon-button" ng-click="$mdOpenMenu($event)">
<md-icon>more_vert</md-icon>
</md-button>
<md-menu-content width="4">
<md-menu-item>
<sg-checkmark ng-model="editor.message.editable.receipt">
<var:string label:value="Return Receipt"/>
</sg-checkmark>
</md-menu-item>
<md-menu-item>
<md-button class="md-primary" ng-disabled="true"><var:string label:value="Priority"/></md-button>
</md-menu-item>
<md-menu-item>
<md-button ng-click="editor.message.editable.priority = 1">
<md-icon ng-class="{ 'icon-check': editor.message.editable.priority == 1}"><!-- highest --></md-icon>
<var:string label:value="highest"/>
</md-button>
</md-menu-item>
<md-menu-item>
<md-button ng-click="editor.message.editable.priority = 2">
<md-icon ng-class="{ 'icon-check': editor.message.editable.priority == 2}"><!-- high --></md-icon>
<var:string label:value="high"/>
</md-button>
</md-menu-item>
<md-menu-item>
<md-button ng-click="editor.message.editable.priority = 3">
<md-icon ng-class="{ 'icon-check':
!editor.message.editable.priority
|| editor.message.editable.priority == 3}"><!-- normal --></md-icon>
<var:string label:value="normal"/>
</md-button>
</md-menu-item>
<md-menu-item>
<md-button ng-click="editor.message.editable.priority = 4">
<md-icon ng-class="{ 'icon-check': editor.message.editable.priority == 4}"><!-- low --></md-icon>
<var:string label:value="low"/>
</md-button>
</md-menu-item>
<md-menu-item>
<md-button ng-click="editor.message.editable.priority = 5">
<md-icon ng-class="{ 'icon-check': editor.message.editable.priority == 5}"><!-- lowest --></md-icon>
<var:string label:value="lowest"/>
</md-button>
</md-menu-item>
</md-menu-content>
</md-menu>
</div>
</header>
<!-- MESSAGE CONTENT -->
<div var:class="editorClass">
<textarea name="content" var:class="editorClass"
ck-locale="editor.localeCode"
ng-model="editor.message.editable.text"/>
</div>
</md-dialog-content>
<!-- ATTACHMENTS -->
<md-dialog-actions>
<div layout="row" layout-align="space-between center" layout-fill="layout-fill">
<!-- Attachments -->
<md-chips ng-model="editor.uploader.queue"
class="md-flex sg-readonly" readonly="true">
@ -247,8 +250,9 @@
Disable multiple until this issue is resolved:
https://github.com/nervgh/angular-file-upload/issues/525
-->
<!-- multiple="multiple" -->
</div>
</md-dialog-actions>
<!-- multiple="multiple" -->
</div>
</md-dialog-actions>
</form>
</md-dialog>
</container>