Add bulk action drag UI
This commit is contained in:
parent
dda715be1b
commit
3b8ce3bd6d
5 changed files with 656 additions and 12 deletions
|
@ -1,13 +1,372 @@
|
||||||
class App.TicketOverview extends App.Controller
|
class App.TicketOverview extends App.Controller
|
||||||
className: 'overviews'
|
className: 'overviews'
|
||||||
activeFocus: 'nav'
|
activeFocus: 'nav'
|
||||||
|
mouse:
|
||||||
|
x: null
|
||||||
|
y: null
|
||||||
|
|
||||||
|
elements:
|
||||||
|
'.js-batch-overlay': 'batchOverlay'
|
||||||
|
'.js-batch-overlay-backdrop': 'batchOverlayBackdrop'
|
||||||
|
'.js-batch-cancel': 'batchCancel'
|
||||||
|
'.js-batch-macro-circle': 'batchMacroCircle'
|
||||||
|
'.js-batch-assign-circle': 'batchAssignCircle'
|
||||||
|
'.js-batch-assign': 'batchAssign'
|
||||||
|
'.js-batch-macro': 'batchMacro'
|
||||||
|
|
||||||
|
events:
|
||||||
|
'mousedown .item': 'startDragItem'
|
||||||
|
'mouseenter .js-batch-overlay-entry': 'highlightBatchEntry'
|
||||||
|
'mouseleave .js-batch-overlay-entry': 'unhighlightBatchEntry'
|
||||||
|
|
||||||
constructor: ->
|
constructor: ->
|
||||||
super
|
super
|
||||||
@render()
|
@render()
|
||||||
|
|
||||||
|
startDragItem: (event) ->
|
||||||
|
@grabbedItem = $(event.currentTarget)
|
||||||
|
offset = @grabbedItem.offset()
|
||||||
|
@batchDragger = $(App.view('ticket_overview/batch_dragger')())
|
||||||
|
@grabbedItemClone = @grabbedItem.clone()
|
||||||
|
@grabbedItemClone.data('offset', @grabbedItem.offset())
|
||||||
|
@grabbedItemClone.addClass('batch-dragger-item js-main-item')
|
||||||
|
@batchDragger.append @grabbedItemClone
|
||||||
|
|
||||||
|
@batchDragger.data
|
||||||
|
startX: event.pageX
|
||||||
|
startY: event.pageY
|
||||||
|
dx: Math.min(event.pageX - offset.left, 180)
|
||||||
|
dy: event.pageY - offset.top
|
||||||
|
moved: false
|
||||||
|
|
||||||
|
$(document).on 'mousemove.item', @dragItem
|
||||||
|
$(document).one 'mouseup.item', @endDragItem
|
||||||
|
# TODO: fire @cancelDrag on ESC
|
||||||
|
|
||||||
|
dragItem: (event) =>
|
||||||
|
event.preventDefault()
|
||||||
|
pos = @batchDragger.data()
|
||||||
|
threshold = 3
|
||||||
|
x = event.pageX - pos.dx
|
||||||
|
y = event.pageY - pos.dy
|
||||||
|
dir = if event.pageY > pos.startY then 1 else -1
|
||||||
|
|
||||||
|
if !pos.moved
|
||||||
|
if Math.abs(event.pageX - pos.startX) > threshold or Math.abs(event.pageY - pos.startY) > threshold
|
||||||
|
@batchDragger.data 'moved', true
|
||||||
|
# check grabbed items batch checkbox to make sure its checked
|
||||||
|
# (could be grabbed without checking the checkbox it)
|
||||||
|
@grabbedItemWasntChecked = !@grabbedItem.find('[name="bulk"]').prop('checked')
|
||||||
|
@grabbedItem.find('[name="bulk"]').prop('checked', true)
|
||||||
|
@grabbedItemClone.find('[name="bulk"]').prop('checked', true)
|
||||||
|
|
||||||
|
additionalItems = @el.find('[name="bulk"]:checked').parents('.item').not(@grabbedItem)
|
||||||
|
additionalItemsClones = additionalItems.clone()
|
||||||
|
@draggedItems = @grabbedItemClone.add(additionalItemsClones)
|
||||||
|
# store offsets for later use
|
||||||
|
additionalItemsClones.each (i, item) -> $(@).data('offset', additionalItems.eq(i).offset())
|
||||||
|
@batchDragger.prepend additionalItemsClones.addClass('batch-dragger-item').get().reverse()
|
||||||
|
if(additionalItemsClones.length)
|
||||||
|
@batchDragger.find('.js-batch-dragger-count').text(@draggedItems.length)
|
||||||
|
|
||||||
|
$('#app').append @batchDragger
|
||||||
|
|
||||||
|
@draggedItems.each (i, item) =>
|
||||||
|
dx = $(item).data('offset').left - $(item).offset().left - x
|
||||||
|
dy = $(item).data('offset').top - $(item).offset().top - y
|
||||||
|
$.Velocity.hook item, 'translateX', "#{dx}px"
|
||||||
|
$.Velocity.hook item, 'translateY', "#{dy}px"
|
||||||
|
|
||||||
|
@moveDraggedItems(-dir)
|
||||||
|
|
||||||
|
@mouseY = event.pageY
|
||||||
|
@showBatchOverlay()
|
||||||
|
else
|
||||||
|
return
|
||||||
|
|
||||||
|
$.Velocity.hook @batchDragger, 'translateX', "#{x}px"
|
||||||
|
$.Velocity.hook @batchDragger, 'translateY', "#{y}px"
|
||||||
|
|
||||||
|
endDragItem: (event) =>
|
||||||
|
$(document).off 'mousemove.item'
|
||||||
|
$(document).off 'mouseup.item'
|
||||||
|
pos = @batchDragger.data()
|
||||||
|
|
||||||
|
if !@hoveredBatchEntry
|
||||||
|
@cleanUpDrag()
|
||||||
|
return
|
||||||
|
|
||||||
|
$.Velocity.hook @batchDragger, 'transformOriginX', "#{pos.dx}px"
|
||||||
|
$.Velocity.hook @batchDragger, 'transformOriginY', "#{pos.dy}px"
|
||||||
|
@hoveredBatchEntry.velocity
|
||||||
|
properties:
|
||||||
|
scale: 1.1
|
||||||
|
options:
|
||||||
|
duration: 200
|
||||||
|
complete: =>
|
||||||
|
@hoveredBatchEntry.velocity "reverse",
|
||||||
|
duration: 200
|
||||||
|
complete: =>
|
||||||
|
# clean scale
|
||||||
|
@hoveredBatchEntry.removeAttr('style')
|
||||||
|
@cleanUpDrag(true)
|
||||||
|
@performBatchAction @hoveredBatchEntry.attr('data-action')
|
||||||
|
@hoveredBatchEntry = null
|
||||||
|
@batchDragger.velocity
|
||||||
|
properties:
|
||||||
|
scale: 0
|
||||||
|
options:
|
||||||
|
duration: 200
|
||||||
|
|
||||||
|
cancelDrag: ->
|
||||||
|
$(document).off 'mousemove.item'
|
||||||
|
$(document).off 'mouseup.item'
|
||||||
|
@cleanUpDrag()
|
||||||
|
|
||||||
|
cleanUpDrag: (success) ->
|
||||||
|
@hideBatchOverlay()
|
||||||
|
$('.batch-dragger').remove()
|
||||||
|
|
||||||
|
if @grabbedItemWasntChecked
|
||||||
|
@grabbedItem.find('[name="bulk"]').prop('checked', false)
|
||||||
|
|
||||||
|
if success
|
||||||
|
# uncheck all checked items
|
||||||
|
@el.find('[name="bulk"]:checked').prop('checked', false)
|
||||||
|
@el.find('[name="bulk_all"]').prop('checked', false)
|
||||||
|
|
||||||
|
moveDraggedItems: (dir) ->
|
||||||
|
@draggedItems.velocity
|
||||||
|
properties:
|
||||||
|
translateX: 0
|
||||||
|
translateY: (i) => dir * i * @batchDragger.height()/2
|
||||||
|
options:
|
||||||
|
easing: 'ease-in-out'
|
||||||
|
duration: 300
|
||||||
|
|
||||||
|
@batchDragger.find('.js-batch-dragger-count').velocity
|
||||||
|
properties:
|
||||||
|
translateY: if dir < 0 then 0 else -@batchDragger.height()+8
|
||||||
|
options:
|
||||||
|
easing: 'ease-in-out'
|
||||||
|
duration: 300
|
||||||
|
|
||||||
|
performBatchAction: (action) ->
|
||||||
|
console.log "perform action #{action} on checked items"
|
||||||
|
|
||||||
|
showBatchOverlay: ->
|
||||||
|
@batchOverlay.show()
|
||||||
|
@batchOverlayBackdrop.velocity { opacity: [1, 0] }, { duration: 500 }
|
||||||
|
@batchOverlayShown = true
|
||||||
|
$(document).on 'mousemove.batchoverlay', @controlBatchOverlay
|
||||||
|
|
||||||
|
hideBatchOverlay: ->
|
||||||
|
$(document).off 'mousemove.batchoverlay'
|
||||||
|
@batchOverlayShown = false
|
||||||
|
@batchOverlayBackdrop.velocity { opacity: [0, 1] }, { duration: 300, queue: false }
|
||||||
|
@hideBatchCircles =>
|
||||||
|
@batchOverlay.hide()
|
||||||
|
|
||||||
|
if @batchAssignShown
|
||||||
|
@hideBatchAssign()
|
||||||
|
|
||||||
|
if @batchMacroShown
|
||||||
|
@hideBatchMacro()
|
||||||
|
|
||||||
|
controlBatchOverlay: (event) =>
|
||||||
|
# store to detect if the mouse is hovering a drag-action entry
|
||||||
|
# after an animation ended -> @highlightBatchEntryAtMousePosition
|
||||||
|
@mouse.x = event.pageX
|
||||||
|
@mouse.y = event.pageY
|
||||||
|
|
||||||
|
if event.pageY <= window.innerHeight/5*2
|
||||||
|
mouseInArea = 'top'
|
||||||
|
else if event.pageY > window.innerHeight/5*2 && event.pageY <= window.innerHeight/5*3
|
||||||
|
mouseInArea = 'middle'
|
||||||
|
else
|
||||||
|
mouseInArea = 'bottom'
|
||||||
|
|
||||||
|
switch mouseInArea
|
||||||
|
when 'top'
|
||||||
|
if !@batchMacroShown
|
||||||
|
@hideBatchCircles()
|
||||||
|
@showBatchMacro()
|
||||||
|
@moveDraggedItems(1)
|
||||||
|
|
||||||
|
when 'middle'
|
||||||
|
if @batchAssignShown
|
||||||
|
@hideBatchAssign()
|
||||||
|
|
||||||
|
if @batchMacroShown
|
||||||
|
@hideBatchMacro()
|
||||||
|
|
||||||
|
if !@batchCirclesShown
|
||||||
|
@showBatchCircles()
|
||||||
|
|
||||||
|
when 'bottom'
|
||||||
|
if !@batchAssignShown
|
||||||
|
@hideBatchCircles()
|
||||||
|
@showBatchAssign()
|
||||||
|
@moveDraggedItems(-1)
|
||||||
|
|
||||||
|
showBatchCircles: ->
|
||||||
|
@batchCirclesShown = true
|
||||||
|
|
||||||
|
@batchMacroCircle.velocity
|
||||||
|
properties:
|
||||||
|
translateY: [0, '-150%']
|
||||||
|
opacity: [1, 0]
|
||||||
|
options:
|
||||||
|
easing: [1,-.55,.2,1.37]
|
||||||
|
duration: 500
|
||||||
|
visibility: 'visible'
|
||||||
|
delay: 200
|
||||||
|
|
||||||
|
@batchAssignCircle.velocity
|
||||||
|
properties:
|
||||||
|
translateY: [0, '150%']
|
||||||
|
opacity: [1, 0]
|
||||||
|
options:
|
||||||
|
easing: [1,-.55,.2,1.37]
|
||||||
|
duration: 500
|
||||||
|
visibility: 'visible'
|
||||||
|
delay: 200
|
||||||
|
|
||||||
|
hideBatchCircles: (callback) ->
|
||||||
|
@batchMacroCircle.velocity
|
||||||
|
properties:
|
||||||
|
translateY: ['-150%', 0]
|
||||||
|
opacity: [0, 1]
|
||||||
|
options:
|
||||||
|
duration: 300
|
||||||
|
visibility: 'hidden'
|
||||||
|
queue: false
|
||||||
|
|
||||||
|
@batchAssignCircle.velocity
|
||||||
|
properties:
|
||||||
|
translateY: ['150%', 0]
|
||||||
|
opacity: [0, 1]
|
||||||
|
options:
|
||||||
|
duration: 300
|
||||||
|
complete: callback
|
||||||
|
visibility: 'hidden'
|
||||||
|
queue: false
|
||||||
|
|
||||||
|
@batchCirclesShown = false
|
||||||
|
|
||||||
|
showBatchAssign: ->
|
||||||
|
return if !@batchOverlayShown # user might have dropped the item already
|
||||||
|
@batchAssignShown = true
|
||||||
|
|
||||||
|
@batchAssign.velocity
|
||||||
|
properties:
|
||||||
|
translateY: [0, '100%']
|
||||||
|
opacity: [1, 0]
|
||||||
|
options:
|
||||||
|
easing: [1,-.55,.2,1.37]
|
||||||
|
duration: 500
|
||||||
|
visibility: 'visible'
|
||||||
|
complete: @highlightBatchEntryAtMousePosition
|
||||||
|
delay: if @batchCirclesShown then 0 else 200
|
||||||
|
|
||||||
|
@batchCancel.css
|
||||||
|
top: 0
|
||||||
|
bottom: 'auto'
|
||||||
|
|
||||||
|
@batchCancel.velocity
|
||||||
|
properties:
|
||||||
|
translateY: [0, '100%']
|
||||||
|
opacity: [1, 0]
|
||||||
|
options:
|
||||||
|
easing: [1,-.55,.2,1.37]
|
||||||
|
duration: 500
|
||||||
|
visibility: 'visible'
|
||||||
|
delay: if @batchCirclesShown then 0 else 200
|
||||||
|
|
||||||
|
hideBatchAssign: ->
|
||||||
|
@batchAssign.velocity
|
||||||
|
properties:
|
||||||
|
translateY: ['100%', 0]
|
||||||
|
opacity: [0, 1]
|
||||||
|
options:
|
||||||
|
duration: 300
|
||||||
|
visibility: 'hidden'
|
||||||
|
queue: false
|
||||||
|
|
||||||
|
@batchCancel.velocity
|
||||||
|
properties:
|
||||||
|
translateY: ['100%', 0]
|
||||||
|
opacity: [0, 1]
|
||||||
|
options:
|
||||||
|
duration: 300
|
||||||
|
visibility: 'hidden'
|
||||||
|
queue: false
|
||||||
|
|
||||||
|
@batchAssignShown = false
|
||||||
|
|
||||||
|
showBatchMacro: ->
|
||||||
|
return if !@batchOverlayShown # user might have dropped the item already
|
||||||
|
@batchMacroShown = true
|
||||||
|
|
||||||
|
@batchMacro.velocity
|
||||||
|
properties:
|
||||||
|
translateY: [0, '-100%']
|
||||||
|
opacity: [1, 0]
|
||||||
|
options:
|
||||||
|
easing: [1,-.55,.2,1.37]
|
||||||
|
duration: 500
|
||||||
|
visibility: 'visible'
|
||||||
|
complete: @highlightBatchEntryAtMousePosition
|
||||||
|
delay: if @batchCirclesShown then 0 else 200
|
||||||
|
|
||||||
|
@batchCancel.css
|
||||||
|
top: 'auto'
|
||||||
|
bottom: 0
|
||||||
|
@batchCancel.velocity
|
||||||
|
properties:
|
||||||
|
translateY: [0, '-100%']
|
||||||
|
opacity: [1, 0]
|
||||||
|
options:
|
||||||
|
easing: [1,-.55,.2,1.37]
|
||||||
|
duration: 500
|
||||||
|
visibility: 'visible'
|
||||||
|
delay: if @batchCirclesShown then 0 else 200
|
||||||
|
|
||||||
|
hideBatchMacro: ->
|
||||||
|
@batchMacro.velocity
|
||||||
|
properties:
|
||||||
|
translateY: ['-100%', 0]
|
||||||
|
opacity: [0, 1]
|
||||||
|
options:
|
||||||
|
duration: 300
|
||||||
|
visibility: 'hidden'
|
||||||
|
queue: false
|
||||||
|
|
||||||
|
@batchCancel.velocity
|
||||||
|
properties:
|
||||||
|
translateY: ['-100%', 0]
|
||||||
|
opacity: [0, 1]
|
||||||
|
options:
|
||||||
|
duration: 300
|
||||||
|
visibility: 'hidden'
|
||||||
|
queue: false
|
||||||
|
|
||||||
|
@batchMacroShown = false
|
||||||
|
|
||||||
|
highlightBatchEntryAtMousePosition: =>
|
||||||
|
entryAtPoint = $(document.elementFromPoint(@mouse.x, @mouse.y)).closest('.js-batch-overlay-entry')
|
||||||
|
if(entryAtPoint.length)
|
||||||
|
@hoveredBatchEntry = entryAtPoint.addClass('is-hovered')
|
||||||
|
|
||||||
|
highlightBatchEntry: (event) ->
|
||||||
|
@hoveredBatchEntry = $(event.currentTarget).addClass('is-hovered')
|
||||||
|
|
||||||
|
unhighlightBatchEntry: (event) ->
|
||||||
|
@hoveredBatchEntry = null
|
||||||
|
$(event.currentTarget).removeClass('is-hovered')
|
||||||
|
|
||||||
render: ->
|
render: ->
|
||||||
elLocal = $(App.view('ticket_overview')())
|
elLocal = $(App.view('ticket_overview/index')())
|
||||||
|
|
||||||
@navBarControllerVertical = new Navbar
|
@navBarControllerVertical = new Navbar
|
||||||
el: elLocal.find('.overview-header')
|
el: elLocal.find('.overview-header')
|
||||||
|
@ -397,10 +756,10 @@ class Table extends App.Controller
|
||||||
)
|
)
|
||||||
table = $(table)
|
table = $(table)
|
||||||
table.delegate('[name="bulk_all"]', 'click', (e) ->
|
table.delegate('[name="bulk_all"]', 'click', (e) ->
|
||||||
if $(e.target).attr('checked')
|
if $(e.currentTarget).prop('checked')
|
||||||
$(e.target).closest('table').find('[name="bulk"]').attr('checked', true)
|
$(e.currentTarget).closest('table').find('[name="bulk"]').prop('checked', true)
|
||||||
else
|
else
|
||||||
$(e.target).closest('table').find('[name="bulk"]').attr('checked', false)
|
$(e.currentTarget).closest('table').find('[name="bulk"]').prop('checked', false)
|
||||||
)
|
)
|
||||||
@$('.table-overview').append(table)
|
@$('.table-overview').append(table)
|
||||||
else
|
else
|
||||||
|
@ -440,6 +799,25 @@ class Table extends App.Controller
|
||||||
@bulkForm.hide()
|
@bulkForm.hide()
|
||||||
else
|
else
|
||||||
@bulkForm.show()
|
@bulkForm.show()
|
||||||
|
|
||||||
|
if @lastChecked && e.shiftKey
|
||||||
|
# check items in a row
|
||||||
|
currentItem = $(e.currentTarget).parents('.item')
|
||||||
|
lastCheckedItem = @lastChecked.parents('.item')
|
||||||
|
items = currentItem.parent().children()
|
||||||
|
|
||||||
|
if currentItem.index() > lastCheckedItem.index()
|
||||||
|
# current item is below last checked item
|
||||||
|
startId = lastCheckedItem.index()
|
||||||
|
endId = currentItem.index()
|
||||||
|
else
|
||||||
|
# current item is above last checked item
|
||||||
|
startId = currentItem.index()
|
||||||
|
endId = lastCheckedItem.index()
|
||||||
|
|
||||||
|
items.slice(startId+1, endId).find('[name="bulk"]').prop('checked', (-> !@checked))
|
||||||
|
|
||||||
|
@lastChecked = $(e.currentTarget)
|
||||||
callbackIconHeader = (headers) ->
|
callbackIconHeader = (headers) ->
|
||||||
attribute =
|
attribute =
|
||||||
name: 'icon'
|
name: 'icon'
|
||||||
|
@ -523,8 +901,8 @@ class Table extends App.Controller
|
||||||
|
|
||||||
# deselect bulk_all if one item is uncheck observ
|
# deselect bulk_all if one item is uncheck observ
|
||||||
@$('.table-overview').delegate('[name="bulk"]', 'click', (e) ->
|
@$('.table-overview').delegate('[name="bulk"]', 'click', (e) ->
|
||||||
if !$(e.target).attr('checked')
|
if !$(e.target).prop('checked')
|
||||||
$(e.target).parents().find('[name="bulk_all"]').attr('checked', false)
|
$(e.target).parents().find('[name="bulk_all"]').prop('checked', false)
|
||||||
)
|
)
|
||||||
|
|
||||||
getSelected: ->
|
getSelected: ->
|
||||||
|
@ -540,7 +918,7 @@ class Table extends App.Controller
|
||||||
ticketId = $(element).val()
|
ticketId = $(element).val()
|
||||||
for ticketIdSelected in ticketIDs
|
for ticketIdSelected in ticketIDs
|
||||||
if ticketIdSelected is ticketId
|
if ticketIdSelected is ticketId
|
||||||
$(element).attr('checked', true)
|
$(element).prop('checked', true)
|
||||||
)
|
)
|
||||||
|
|
||||||
viewmode: (e) =>
|
viewmode: (e) =>
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
<div class="sidebar"></div>
|
|
||||||
<div class="main flex">
|
|
||||||
<div class="overview-header"></div>
|
|
||||||
<div class="overview-table"></div>
|
|
||||||
</div>
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
<div class="batch-dragger zIndex-10">
|
||||||
|
<div class="batch-dragger-counter js-batch-dragger-count"></div>
|
||||||
|
</div>
|
|
@ -0,0 +1,50 @@
|
||||||
|
<div class="sidebar"></div>
|
||||||
|
<div class="main flex">
|
||||||
|
<div class="overview-header"></div>
|
||||||
|
<div class="overview-table"></div>
|
||||||
|
</div>
|
||||||
|
<div class="batch-overlay js-batch-overlay">
|
||||||
|
<div class="batch-overlay-backdrop js-batch-overlay-backdrop"></div>
|
||||||
|
<div class="batch-overlay-cancel js-batch-cancel">
|
||||||
|
<%- @T('drag here to cancel') %>
|
||||||
|
</div>
|
||||||
|
<div class="batch-overlay-circle batch-overlay-circle--top js-batch-macro-circle">
|
||||||
|
<div class="batch-overlay-circle-label"><%- @T('run macro') %></div>
|
||||||
|
<%- @Icon('arrow-up') %>
|
||||||
|
</div>
|
||||||
|
<div class="batch-overlay-circle batch-overlay-circle--bottom js-batch-assign-circle">
|
||||||
|
<%- @Icon('arrow-down') %>
|
||||||
|
<div class="batch-overlay-circle-label"><%- @T('assign tickets') %></div>
|
||||||
|
</div>
|
||||||
|
<div class="batch-overlay-assign batch-overlay-box js-batch-assign">
|
||||||
|
<div class="batch-overlay-assign-entry js-batch-overlay-entry" data-action="assign">
|
||||||
|
<span class="avatar size-80 avatar--unique" style="background-position: -100px -150px;">HH</span>
|
||||||
|
<div class="batch-overlay-assign-entry-name">Hans Huber</div>
|
||||||
|
</div>
|
||||||
|
<div class="batch-overlay-assign-entry js-batch-overlay-entry" data-action="assign">
|
||||||
|
<span class="avatar avatar--organization size-80 avatar--unique" style="background-position: -200px -60px;">
|
||||||
|
<%- @Icon('organization') %>
|
||||||
|
</span>
|
||||||
|
<div class="batch-overlay-assign-entry-name">Zammad</div>
|
||||||
|
<div class="batch-overlay-assign-entry-detail">3 Personen</div>
|
||||||
|
</div>
|
||||||
|
<div class="batch-overlay-assign-entry js-batch-overlay-entry" data-action="assign">
|
||||||
|
<span class="avatar size-80 avatar--unique" style="background-position: -30px -10px;">FD</span>
|
||||||
|
<div class="batch-overlay-assign-entry-name">Felicity Dickens</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="batch-overlay-macro batch-overlay-box js-batch-macro">
|
||||||
|
<div class="batch-overlay-macro-entry js-batch-overlay-entry" data-action="macro">
|
||||||
|
<div class="batch-overlay-macro-entry-name">Close</div>
|
||||||
|
</div>
|
||||||
|
<div class="batch-overlay-macro-entry js-batch-overlay-entry" data-action="macro">
|
||||||
|
<div class="batch-overlay-macro-entry-name">Close & Tag as Spam</div>
|
||||||
|
</div>
|
||||||
|
<div class="batch-overlay-macro-entry js-batch-overlay-entry" data-action="macro">
|
||||||
|
<div class="batch-overlay-macro-entry-name">Close & Reply we're on Holidays</div>
|
||||||
|
</div>
|
||||||
|
<div class="batch-overlay-macro-entry js-batch-overlay-entry" data-action="macro">
|
||||||
|
<div class="batch-overlay-macro-entry-name">Escalate to 2nd level</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -3580,6 +3580,23 @@ footer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&--organization {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.icon-organization {
|
||||||
|
fill: currentColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.size-80 {
|
||||||
|
.icon-organization {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.icon-logo {
|
.icon-logo {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -8321,6 +8338,207 @@ output {
|
||||||
margin: 20px 0 32px;
|
margin: 20px 0 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.batch-overlay {
|
||||||
|
@extend .fit;
|
||||||
|
z-index: 1;
|
||||||
|
color: white;
|
||||||
|
text-transform: uppercase;
|
||||||
|
text-align: center;
|
||||||
|
letter-spacing: 0.07em;
|
||||||
|
font-size: 0.95em;
|
||||||
|
line-height: 1.3;
|
||||||
|
display: none;
|
||||||
|
will-change: display;
|
||||||
|
cursor: grabbing;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&-backdrop {
|
||||||
|
@extend .fit;
|
||||||
|
background: hsla(231,20%,8%,.8);
|
||||||
|
opacity: 0;
|
||||||
|
will-change: opacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-circle {
|
||||||
|
margin: 35px auto;
|
||||||
|
background: hsl(207,7%,29%);
|
||||||
|
border-radius: 100%;
|
||||||
|
border: 4px solid white;
|
||||||
|
width: 140px;
|
||||||
|
height: 140px;
|
||||||
|
padding: 20px 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
will-change: transform, opacity;
|
||||||
|
visibility: hidden;
|
||||||
|
|
||||||
|
&--top {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--bottom {
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
fill: currentColor;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-label {
|
||||||
|
width: 50%;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-cancel {
|
||||||
|
background: hsla(0,0%,100%,.21);
|
||||||
|
background-clip: padding-box;
|
||||||
|
border: 2px dashed hsla(0,0%,100%,.3);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 28px;
|
||||||
|
margin: 50px 200px;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
will-change: opacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-box {
|
||||||
|
background: hsl(232,9%,17%);
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
width: 100%;
|
||||||
|
padding: 37px 25px;
|
||||||
|
position: absolute;
|
||||||
|
visibility: hidden;
|
||||||
|
will-change: opacity, transition;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-assign {
|
||||||
|
padding-bottom: 87px; // 37px + 50px
|
||||||
|
bottom: -50px; // extra space for bounce animation
|
||||||
|
|
||||||
|
&-entry {
|
||||||
|
padding: 13px;
|
||||||
|
|
||||||
|
&.is-hovered {
|
||||||
|
.avatar {
|
||||||
|
border-color: $highlight-color;
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
border: 4px solid hsl(231,5%,30%);
|
||||||
|
margin-bottom: 10px;
|
||||||
|
box-sizing: content-box;
|
||||||
|
transition: transform 120ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-detail {
|
||||||
|
color: gray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-macro {
|
||||||
|
padding-top: 87px; // 37px + 50px
|
||||||
|
top: -50px; // extra space for bounce animation
|
||||||
|
|
||||||
|
&-entry {
|
||||||
|
margin: 13px;
|
||||||
|
border: 4px solid hsl(231,5%,30%);
|
||||||
|
background: hsl(233,9%,24%);
|
||||||
|
border-radius: 100%;
|
||||||
|
height: 120px;
|
||||||
|
width: 120px;
|
||||||
|
padding: 13px 13px 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 0.9em;
|
||||||
|
|
||||||
|
&.is-hovered {
|
||||||
|
border-color: $highlight-color;
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.batch-dragger {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
width: 250px;
|
||||||
|
height: 40px;
|
||||||
|
will-change: transform;
|
||||||
|
|
||||||
|
&-item {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
background: hsl(200,100%,91%);
|
||||||
|
border-radius: 4px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 11px 0 9px 11px;
|
||||||
|
box-shadow: 0 0 10px hsla(0,0%,0%,.28);
|
||||||
|
will-change: transform;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
display: block;
|
||||||
|
padding: 0 12px;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
&:nth-child(3) {
|
||||||
|
flex-shrink: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(n+4) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-counter {
|
||||||
|
position: absolute;
|
||||||
|
right: -8px;
|
||||||
|
bottom: -8px;
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
border-radius: 99px;
|
||||||
|
z-index: 1;
|
||||||
|
color: white;
|
||||||
|
background: $highlight-color;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
box-shadow: 0 0 10px hsla(0,0%,0%,.28);
|
||||||
|
will-change: transform;
|
||||||
|
|
||||||
|
&:empty {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
|
|
Loading…
Reference in a new issue