add local modal

Usage:

new option "container" [jquery element] (default: body)
if the modal should be local the container should be the content element.

Demo:

Merge Ticket in Ticket Zoom
=> new App.TicketMerge in ticket_zoom.js.coffee:332
This commit is contained in:
Felix Niklas 2015-01-15 10:07:06 +01:00
parent 4efebb9b1d
commit fe42d16383
8 changed files with 593 additions and 10 deletions

View file

@ -500,6 +500,7 @@ class App.ControllerModal extends App.Controller
head: '?' head: '?'
buttonClass: 'btn--success' buttonClass: 'btn--success'
centerButtons: [] centerButtons: []
container: null
options = _.extend( defaults, options ) options = _.extend( defaults, options )
@ -526,10 +527,14 @@ class App.ControllerModal extends App.Controller
if @content if @content
@body.html @content @body.html @content
if @container
@el.addClass('modal--local')
@el.modal @el.modal
keyboard: @keyboard keyboard: @keyboard
show: true show: true
backdrop: @backdrop backdrop: @backdrop
container: @container
.on .on
'show.bs.modal': @onShow 'show.bs.modal': @onShow
'shown.bs.modal': @onShown 'shown.bs.modal': @onShown

View file

@ -732,4 +732,15 @@ class RichText extends App.ControllerContent
App.Config.set( 'layout_ref/richtext', RichText, 'Routes' ) App.Config.set( 'layout_ref/richtext', RichText, 'Routes' )
class LocalModalRef extends App.ControllerContent
constructor: ->
super
@render()
render: ->
@html App.view('layout_ref/local_modal')()
App.Config.set( 'layout_ref/local_modal', LocalModalRef, 'Routes' )
App.Config.set( 'LayoutRef', { prio: 1700, parent: '#current_user', name: 'Layout Reference', target: '#layout_ref', role: [ 'Admin' ] }, 'NavBarRight' ) App.Config.set( 'LayoutRef', { prio: 1700, parent: '#current_user', name: 'Layout Reference', target: '#layout_ref', role: [ 'Admin' ] }, 'NavBarRight' )

View file

@ -329,7 +329,10 @@ class App.TicketZoom extends App.Controller
showTicketHistory = => showTicketHistory = =>
new App.TicketHistory( ticket_id: @ticket.id ) new App.TicketHistory( ticket_id: @ticket.id )
showTicketMerge = => showTicketMerge = =>
new App.TicketMerge( ticket: @ticket, task_key: @task_key ) new App.TicketMerge
ticket: @ticket
task_key: @task_key
container: @el
changeCustomer = (e, el) => changeCustomer = (e, el) =>
new App.TicketCustomer( new App.TicketCustomer(
ticket: @ticket ticket: @ticket

View file

@ -6,6 +6,12 @@
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* ======================================================================== */ * ======================================================================== */
/*
modified by Felix Jan-2014
- change $body to $container
- add this.$container = $(options.container || document.body)
*/
+function ($) { +function ($) {
'use strict'; 'use strict';
@ -15,7 +21,7 @@
var Modal = function (element, options) { var Modal = function (element, options) {
this.options = options this.options = options
this.$body = $(document.body) this.$container = $(options.container || document.body)
this.$element = $(element) this.$element = $(element)
this.$backdrop = this.$backdrop =
this.isShown = null this.isShown = null
@ -57,7 +63,8 @@
this.checkScrollbar() this.checkScrollbar()
this.setScrollbar() this.setScrollbar()
this.$body.addClass('modal-open')
this.$container.addClass('modal-open')
this.escape() this.escape()
this.resize() this.resize()
@ -68,7 +75,7 @@
var transition = $.support.transition && that.$element.hasClass('fade') var transition = $.support.transition && that.$element.hasClass('fade')
if (!that.$element.parent().length) { if (!that.$element.parent().length) {
that.$element.appendTo(that.$body) // don't move modals dom position that.$element.appendTo(that.$container) // don't move modals dom position
} }
that.$element that.$element
@ -160,7 +167,7 @@
var that = this var that = this
this.$element.hide() this.$element.hide()
this.backdrop(function () { this.backdrop(function () {
that.$body.removeClass('modal-open') that.$container.removeClass('modal-open')
that.resetAdjustments() that.resetAdjustments()
that.resetScrollbar() that.resetScrollbar()
that.$element.trigger('hidden.bs.modal') that.$element.trigger('hidden.bs.modal')
@ -253,20 +260,20 @@
} }
Modal.prototype.setScrollbar = function () { Modal.prototype.setScrollbar = function () {
var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10) var bodyPad = parseInt((this.$container.css('padding-right') || 0), 10)
if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth) if (this.bodyIsOverflowing) this.$container.css('padding-right', bodyPad + this.scrollbarWidth)
} }
Modal.prototype.resetScrollbar = function () { Modal.prototype.resetScrollbar = function () {
this.$body.css('padding-right', '') this.$container.css('padding-right', '')
} }
Modal.prototype.measureScrollbar = function () { // thx walsh Modal.prototype.measureScrollbar = function () { // thx walsh
var scrollDiv = document.createElement('div') var scrollDiv = document.createElement('div')
scrollDiv.className = 'modal-scrollbar-measure' scrollDiv.className = 'modal-scrollbar-measure'
this.$body.append(scrollDiv) this.$container.append(scrollDiv)
var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
this.$body[0].removeChild(scrollDiv) this.$container[0].removeChild(scrollDiv)
return scrollbarWidth return scrollbarWidth
} }

View file

@ -19,6 +19,7 @@
<li><a href="#layout_ref/organization_profile">Organization Profile</a></li> <li><a href="#layout_ref/organization_profile">Organization Profile</a></li>
<li><a href="#layout_ref/setup">Setup Wizard</a></li> <li><a href="#layout_ref/setup">Setup Wizard</a></li>
<li><a href="#layout_ref/richtext">Richtext</a></li> <li><a href="#layout_ref/richtext">Richtext</a></li>
<li><a href="#layout_ref/local_modal">Local Modal</a></li>
</ul> </ul>
</div> </div>

View file

@ -0,0 +1,537 @@
<div class="flex profile">
<div class="modal modal--local">
<div class="modal-backdrop"></div>
<div class="modal-dialog">
<form>
<div class="modal-content">
<div class="modal-header">
<div class="modal-close js-close">
<div class="close icon"></div>
</div>
<h1 class="modal-title">Edit Customer</h1>
</div>
<div class="modal-body">
<fieldset>
<div class="input form-group formGroup--halfSize">
<div class="formGroup-label">
<label for="User_968887_firstname">Firstname <span>*</span></label>
</div>
<div class="controls"><input id="User_968887_firstname" type="text" name="firstname" value="Nicole" class="form-control " required="" autofocus="">
<span class="help-inline"></span>
<span class="help-block"></span>
</div>
</div><div class="input form-group formGroup--halfSize">
<div class="formGroup-label">
<label for="User_968887_lastname">Lastname <span>*</span></label>
</div>
<div class="controls"><input id="User_968887_lastname" type="text" name="lastname" value="Braun" class="form-control " required="">
<span class="help-inline"></span>
<span class="help-block"></span>
</div>
</div><div class="input form-group formGroup--halfSize">
<div class="formGroup-label">
<label for="User_968887_email">Email <span>*</span></label>
</div>
<div class="controls"><input id="User_968887_email" type="email" name="email" value="nicole.braun@zammad.org" class="form-control " required="">
<span class="help-inline"></span>
<span class="help-block"></span>
</div>
</div><div class="input form-group formGroup--halfSize">
<div class="formGroup-label">
<label for="User_968887_web">Web <span></span></label>
</div>
<div class="controls"><input id="User_968887_web" type="url" name="web" value="" class="form-control ">
<span class="help-inline"></span>
<span class="help-block"></span>
</div>
</div><div class="input form-group formGroup--halfSize">
<div class="formGroup-label">
<label for="User_968887_phone">Phone <span></span></label>
</div>
<div class="controls"><input id="User_968887_phone" type="phone" name="phone" value="" class="form-control ">
<span class="help-inline"></span>
<span class="help-block"></span>
</div>
</div><div class="input form-group formGroup--halfSize">
<div class="formGroup-label">
<label for="User_968887_mobile">Mobile <span></span></label>
</div>
<div class="controls"><input id="User_968887_mobile" type="phone" name="mobile" value="" class="form-control ">
<span class="help-inline"></span>
<span class="help-block"></span>
</div>
</div><div class="input form-group formGroup--halfSize">
<div class="formGroup-label">
<label for="User_968887_fax">Fax <span></span></label>
</div>
<div class="controls"><input id="User_968887_fax" type="phone" name="fax" value="" class="form-control ">
<span class="help-inline"></span>
<span class="help-block"></span>
</div>
</div><div class="select form-group formGroup--halfSize">
<div class="formGroup-label">
<label for="User_968887_organization_id">Organization <span></span></label>
</div>
<div class="controls"><div class="u-positionOrigin">
<select id="User_968887_organization_id" class="form-control" name="organization_id">
<option value="">-</option>
<option value="1" selected="">Zammad Foundation</option>
</select>
<div class="select-arrow icon"></div>
</div>
<span class="help-inline"></span>
<span class="help-block"></span>
</div>
</div><div class="input form-group formGroup--halfSize">
<div class="formGroup-label">
<label for="User_968887_department">Department <span></span></label>
</div>
<div class="controls"><input id="User_968887_department" type="text" name="department" value="" class="form-control ">
<span class="help-inline"></span>
<span class="help-block"></span>
</div>
</div><div class="input form-group">
<div class="formGroup-label">
<label for="User_968887_street">Street <span></span></label>
</div>
<div class="controls"><input id="User_968887_street" type="text" name="street" value="" class="form-control ">
<span class="help-inline"></span>
<span class="help-block"></span>
</div>
</div><div class="input form-group formGroup--halfSize">
<div class="formGroup-label">
<label for="User_968887_zip">Zip <span></span></label>
</div>
<div class="controls"><input id="User_968887_zip" type="text" name="zip" value="" class="form-control ">
<span class="help-inline"></span>
<span class="help-block"></span>
</div>
</div><div class="input form-group formGroup--halfSize">
<div class="formGroup-label">
<label for="User_968887_city">City <span></span></label>
</div>
<div class="controls"><input id="User_968887_city" type="text" name="city" value="" class="form-control ">
<span class="help-inline"></span>
<span class="help-block"></span>
</div>
</div><div class="input form-group">
<div class="formGroup-label">
<label for="User_968887_password">Password <span></span></label>
</div>
<div class="controls"><input id="User_968887_password" type="password" name="password" value="" class="form-control " autocomplete="off">
<span class="help-inline"></span>
<span class="help-block"></span>
</div>
</div><div class="input form-group">
<div class="formGroup-label">
<label for="User_968887_password_confirm">Password (confirm) <span></span></label>
</div>
<div class="controls"><input id="User_968887_password_confirm" type="password" name="password_confirm" value="" class="form-control " autocomplete="off">
<span class="help-inline"></span>
<span class="help-block"></span>
</div>
</div><div class="richtext form-group">
<div class="formGroup-label">
<label for="User_968887_note">Note <span></span></label>
<div class="align-right help-message" title="Notes are visible to agents only, never to customers. ">
<div class="help icon"></div>
</div>
</div>
<div class="controls"><div class="richtext form-control">
<div contenteditable="true" id="User_968887_note" data-name="note" class=""></div>
</div>
<span class="help-inline"></span>
<span class="help-block"></span>
</div>
</div><div class="checkbox form-group">
<div class="formGroup-label">
<label for="User_968887_role_ids">Roles <span>*</span></label>
</div>
<div class="controls"><div class=" checkbox">
<label><input type="checkbox" value="1" name="role_ids"> Admin - To configure your system.</label>
<label><input type="checkbox" value="2" name="role_ids"> Agent - To work on Tickets.</label>
<label><input type="checkbox" value="3" name="role_ids" checked=""> Customer - People who create Tickets ask for help.</label>
</div>
<span class="help-inline"></span>
<span class="help-block"></span>
</div>
</div><div class="checkbox form-group">
<div class="formGroup-label">
<label for="User_968887_group_ids">Groups <span></span></label>
</div>
<div class="controls"><div class=" checkbox">
<label><input type="checkbox" value="1" name="group_ids"> Users - Standard Group/Pool for Tickets.</label>
</div>
<span class="help-inline"></span>
<span class="help-block"></span>
</div>
</div><div class="boolean form-group">
<div class="formGroup-label">
<label for="User_968887_active">Active <span>*</span></label>
</div>
<div class="controls"><div class="u-positionOrigin">
<select id="User_968887_active" class="form-control" name="active" required="">
<option value="{boolean}::true" selected="">active</option>
<option value="{boolean}::false">inactive</option>
</select>
<div class="select-arrow icon"></div>
</div>
<span class="help-inline"></span>
<span class="help-block"></span>
</div>
</div>
</fieldset>
</div>
<div class="modal-footer horizontal">
<a class="subtle-link standalone js-cancel" href="#/">Cancel & Go Back</a>
<button type="submit" class="btn btn--success js-submit align-right">Update & Back</button>
</div>
</div>
</form>
</div>
</div>
<div class="profile-window">
<div class="profile-section vertical centered">
<div class="align-right profile-action dropdown dropdown--actions">
<div class="dropdown-toggle horizontal center" id="profileAction" data-toggle="dropdown">
<div class="light cog icon"></div>
<label>Aktion</label>
<span class="select-arrow icon"></span>
</div>
<ul class="dropdown-menu dropdown-menu-right" role="menu" aria-labelledby="profileAction">
<li role="presentation"><a role="menuitem" tabindex="-1">Kontaktdaten bearbeiten</a>
<li role="presentation"><a role="menuitem" tabindex="-1" href="#">Änderungsprotokoll</a>
<li role="presentation"><a role="menuitem" tabindex="-1">Benutzer zusammenführen</a>
<li role="presentation"><a role="menuitem" tabindex="-1">Benutzer löschen</a>
</ul>
</div>
<div class="avatar size-80" style="background-image: url(https://pbs.twimg.com/profile_images/1216362658/DSC_0084-p_bigger.jpg)"></div>
<h1>Doreen Kubiak</h1>
<div class="profile-subtitle">Steuerbüro C. Kaik</div>
</div>
<div class="profile-section">
<div class="profile-details horizontal wrap">
<div class="profile-detailsEntry">
<label>Email</label>
<a href="mailto:doreen.kubiak@gmail.com">doreen.kubiak@gmail.com</a>
</div>
<div class="profile-detailsEntry">
<label>Organization</label>
Steuerbüro C. Kaik
</div>
<div class="profile-detailsEntry">
<label>Web</label>
<a href="http://ckaik.com" target="_blank">chaik.com</a>
</div>
<div class="profile-detailsEntry">
<label>Strasse</label>
Johannitergasse 2/2
</div>
<div class="profile-detailsEntry">
<label>Telefon</label>
+43 5522 36346
</div>
<div class="profile-detailsEntry">
<label>PLZ, ORT</label>
6800 Feldkirch
</div>
<div class="profile-detailsEntry">
<label>Mobile-Nr.</label>
+43 699 4565789
</div>
<div class="profile-detailsEntry">
<label>Land</label>
Österreich
</div>
</div>
</div>
<div class="profile-section">
<!-- if user has organization -->
<div class="tabs wide-tabs horizontal">
<div class="tab js-userTickets active">Tickets von Doreen Kubiak</div>
<div class="tab js-organizationTickets">Tickets von Steuerbüro C. Kaik</div>
</div>
<!-- endif -->
<div class="profile-ticketLists horizontal">
<div class="profile-ticketList">
<label>Offene Tickets (0)</label>
<div class="profile-ticketsPlaceholder vertical centered">
<div class="mood icon supergood-state"></div>
Keine offenen Tickets
</div>
<a href="#">Alle Tickets von Doreen Kubiak …</a>
</div>
<div class="profile-ticketList">
<label>Bearbeitete Tickets (12)</label>
<ol class="tasks tasks--standalone">
<li class="task level-1">
<div class="icon-holder">
<div class="priority icon"></div>
</div>
<div class="flex">
<div class="name">Micro-SIM doesn't work</div>
<div class="time">23 minutes ago</div>
</div>
<li class="task level-1">
<div class="icon-holder">
<div class="priority icon"></div>
</div>
<div class="flex">
<div class="name">Superb Service!</div>
<div class="time">43 minutes ago</div>
</div>
<li class="task level-1">
<div class="icon-holder">
<div class="priority icon"></div>
</div>
<div class="flex">
<div class="name">Print sheets strip off</div>
<div class="time">1 hour ago</div>
</div>
<li class="task level-1">
<div class="icon-holder">
<div class="priority icon"></div>
</div>
<div class="flex">
<div class="name">Block not properly wrought</div>
<div class="time">2 hour ago</div>
</div>
</ol>
<a href="#">Alle Tickets von Steuerbüro C. Kaik …</a>
</div>
</div>
</div>
<div class="profile-section horizontal two-columns">
<div class="column status stat-widget vertical">
<h3>Status</h3>
<div class="stat-graphic">
<div class="stat-tickets vertical reverse end">
<div class="stat-ticket icon supergood-state"></div>
<div class="stat-ticket icon supergood-state"></div>
<div class="stat-ticket icon supergood-state"></div>
<div class="stat-ticket icon supergood-state"></div>
<div class="stat-ticket icon supergood-state"></div>
<div class="stat-ticket icon supergood-state"></div>
</div>
<div class="stat-all-tickets icon"></div>
</div>
<!--
Achtung: hier müssen wir schauen, dass wir das Widget genauso verwenden wie im Dashboard. Sonst gibt's Verwirrung.
-->
<div class="stat-label">Tickets of my Group: 78 of 234</div>
<div class="stat-detail">Average: 22%</div>
</div>
<div class="column mood stat-widget vertical">
<h3>Stimmung</h3>
<div class="stat-graphic">
<div class="mood icon supergood-state"></div>
</div>
<div class="stat-label">3% of my tickets escalated.</div>
<div class="stat-detail">Average: 17%</div>
</div>
</div>
<div class="profile-section">
<div class="frequency stat-widget vertical">
<h3>Frequency</h3>
<div class="stat-graphic">
<div class="stats-row">
<div class="stat-bars">
<div class="stat-bar primary" style="height: 80%"></div>
<div class="stat-bar secondary" style="height: 34%"></div>
</div>
<div class="stat-label">Jan</div>
</div>
<div class="stats-row">
<div class="stat-bars">
<div class="stat-bar primary" style="height: 53%"></div>
<div class="stat-bar secondary" style="height: 47%"></div>
</div>
<div class="stat-label">Feb</div>
</div>
<div class="stats-row">
<div class="stat-bars">
<div class="stat-bar primary" style="height: 46%"></div>
<div class="stat-bar secondary" style="height: 21%"></div>
</div>
<div class="stat-label">Mär</div>
</div>
<div class="stats-row">
<div class="stat-bars">
<div class="stat-bar primary" style="height: 24%"></div>
<div class="stat-bar secondary" style="height: 18%"></div>
</div>
<div class="stat-label">Apr</div>
</div>
<div class="stats-row">
<div class="stat-bars">
<div class="stat-bar primary" style="height: 13%"></div>
<div class="stat-bar secondary" style="height: 5%"></div>
</div>
<div class="stat-label">Mai</div>
</div>
<div class="stats-row">
<div class="stat-bars">
<div class="stat-bar primary" style="height: 18%"></div>
<div class="stat-bar secondary" style="height: 10%"></div>
</div>
<div class="stat-label">Jun</div>
</div>
<div class="stats-row">
<div class="stat-bars">
<div class="stat-bar primary" style="height: 50%"></div>
<div class="stat-bar secondary" style="height: 8%"></div>
</div>
<div class="stat-label">Jul</div>
</div>
<div class="stats-row">
<div class="stat-bars">
<div class="stat-bar primary" style="height: 67%"></div>
<div class="stat-bar secondary" style="height: 13%"></div>
</div>
<div class="stat-label">Aug</div>
</div>
<div class="stats-row">
<div class="stat-bars">
<div class="stat-bar primary" style="height: 34%"></div>
<div class="stat-bar secondary" style="height: 2%"></div>
</div>
<div class="stat-label">Sep</div>
</div>
<div class="stats-row">
<div class="stat-bars">
<div class="stat-bar primary" style="height: 5%"></div>
<div class="stat-bar secondary" style="height: 0%"></div>
</div>
<div class="stat-label">Okt</div>
</div>
<div class="stats-row">
<div class="stat-bars">
<div class="stat-bar primary" style="height: 25%"></div>
<div class="stat-bar secondary" style="height: 0%"></div>
</div>
<div class="stat-label">Nov</div>
</div>
<div class="stats-row">
<div class="stat-bars">
<div class="stat-bar primary" style="height: 80%"></div>
<div class="stat-bar secondary" style="height: 5%"></div>
</div>
<div class="stat-label">Dez</div>
</div>
</div>
<div class="stat-legend">
<div class="stat-legendEntry primary"><span class="primary stat-circle"></span>Bearbeitet</div>
<div class="stat-legendEntry secondary"><span class="secondary stat-circle"></span>Offen</div>
</div>
</div>
</div>
</div>
</div>

View file

@ -26,7 +26,10 @@
//= require ./app/lib/bootstrap/tooltip.js //= require ./app/lib/bootstrap/tooltip.js
//= require ./app/lib/bootstrap/popover.js //= require ./app/lib/bootstrap/popover.js
//= require ./app/lib/bootstrap/popover-enhance.js //= require ./app/lib/bootstrap/popover-enhance.js
// modified by Felix Jan-2014
//= require ./app/lib/bootstrap/modal.js //= require ./app/lib/bootstrap/modal.js
//= require ./app/lib/bootstrap/tab.js //= require ./app/lib/bootstrap/tab.js
//= require ./app/lib/bootstrap/transition.js //= require ./app/lib/bootstrap/transition.js
//= require ./app/lib/bootstrap/button.js //= require ./app/lib/bootstrap/button.js

View file

@ -4070,6 +4070,22 @@ footer {
border: none; border: none;
} }
.modal.modal--local {
display: block;
padding-left: 40px;
position: absolute;
overflow: auto;
background: hsla(210,17%,98%,.55);
.modal-backdrop {
display: none;
}
.modal-dialog {
box-shadow: 0 0 40px hsla(210,17%,40%,.34);
}
}
.caret { .caret {
position: absolute; position: absolute;
top: 50%; top: 50%;