diff --git a/app/assets/javascripts/app/controllers/_application_controller_table.coffee b/app/assets/javascripts/app/controllers/_application_controller_table.coffee index ed6288638..b7b78d994 100644 --- a/app/assets/javascripts/app/controllers/_application_controller_table.coffee +++ b/app/assets/javascripts/app/controllers/_application_controller_table.coffee @@ -24,15 +24,15 @@ class App.ControllerTable extends App.Controller for key, value of data['headerWidth'] @headerWidth[key] = value + @availableWidth = @el.width() @render() - $(window).on 'resize.table', @readjustHeaderWidths + $(window).on 'resize.table', @onResize release: => - $(window).off 'resize.table', @readjustHeaderWidths + $(window).off 'resize.table', @onResize render: => @html @tableGen() - @readjustHeaderWidths() if @dndCallback dndOptions = @@ -172,7 +172,7 @@ class App.ControllerTable extends App.Controller # e.g. column: owner headerFound = true if @headerWidth[attribute.name] - attribute.displayWidth = @headerWidth[attribute.name] + attribute.displayWidth = @headerWidth[attribute.name] * @availableWidth else if !attribute.width attribute.displayWidth = @baseColWidth else @@ -191,7 +191,7 @@ class App.ControllerTable extends App.Controller if attributeName is rowWithoutId headerFound = true if @headerWidth[attribute.name] - attribute.displayWidth = @headerWidth[attribute.name] + attribute.displayWidth = @headerWidth[attribute.name] * @availableWidth else if !attribute.width attribute.displayWidth = @baseColWidth else @@ -281,6 +281,8 @@ class App.ControllerTable extends App.Controller @objects = @objects.concat groupObjects[group] groupObjects[group] = [] # release old array + @calculateHeaderWidths() + # get content table = App.view('generic/table')( table_id: @table_id @@ -360,7 +362,6 @@ class App.ControllerTable extends App.Controller # if we have a personalised table if @table_id - # enable resize column table.on 'mousedown', '.js-col-resize', @onColResizeMousedown table.on 'click', '.js-col-resize', @stopPropagation @@ -404,17 +405,15 @@ class App.ControllerTable extends App.Controller item: item container: @container - adjustHeaderWidths: -> + calculateHeaderWidths: -> if !@headers return - availableWidth = @el.width() - - if availableWidth is 0 - availableWidth = @minTableWidth + if @availableWidth is 0 + @availableWidth = @minTableWidth widths = @getHeaderWidths() - shrinkBy = Math.ceil (widths - availableWidth) / @getShrinkableHeadersCount() + shrinkBy = Math.ceil (widths - @availableWidth) / @getShrinkableHeadersCount() # make all cols evenly smaller @headers = _.map @headers, (col) => @@ -423,11 +422,13 @@ class App.ControllerTable extends App.Controller return col # give left-over space from rounding to last column to get to 100% - roundingLeftOver = availableWidth - @getHeaderWidths() + roundingLeftOver = @availableWidth - @getHeaderWidths() # but only if there is something left over (will get negative when there are too many columns for each column to stay in their min width) if roundingLeftOver > 0 @headers[@headers.length - 1].displayWidth = @headers[@headers.length - 1].displayWidth + roundingLeftOver + @storeHeaderWidths() + getShrinkableHeadersCount: -> _.reduce @headers, (memo, col) -> return if col.unresizable then memo else memo+1 @@ -449,12 +450,24 @@ class App.ControllerTable extends App.Controller return widths - readjustHeaderWidths: => - @adjustHeaderWidths() + setHeaderWidths: => + @calculateHeaderWidths() @tableHead.each (i, el) => el.style.width = @headers[i].displayWidth + 'px' + storeHeaderWidths: -> + widths = {} + + for header in @headers + widths[header.name] = header.displayWidth / @availableWidth + + App.LocalStorage.set(@preferencesStoreKey(), { headerWidth: widths }, @Session.get('id')) + + onResize: => + @availableWidth = @el.width() + @setHeaderWidths() + stopPropagation: (event) -> event.stopPropagation() @@ -488,18 +501,12 @@ class App.ControllerTable extends App.Controller # switch to percentage resizeBaseWidth = @resizeTargetLeft.parents('table').width() - leftWidth = @resizeTargetLeft.width() - rightWidth = @resizeTargetRight.width() + leftWidth = @resizeTargetLeft.width() / resizeBaseWidth + rightWidth = @resizeTargetRight.width() / resizeBaseWidth leftColumnKey = @resizeTargetLeft.attr('data-column-key') rightColumnKey = @resizeTargetRight.attr('data-column-key') - # save table changed widths - storeColWidths = [ - { key: leftColumnKey, width: leftWidth } - { key: rightColumnKey, width: rightWidth } - ] - # update store and runtime @headerWidth @preferencesStore('headerWidth', leftColumnKey, leftWidth) _.find(@headers, (column) -> column.name is leftColumnKey).displayWidth = leftWidth @@ -543,4 +550,4 @@ class App.ControllerTable extends App.Controller data preferencesStoreKey: => - "tablePreferences:#{@table_id}" + "tablePrefs:#{@table_id}" diff --git a/app/assets/javascripts/app/controllers/navigation.coffee b/app/assets/javascripts/app/controllers/navigation.coffee index 6aaaa95b3..8b5155af8 100644 --- a/app/assets/javascripts/app/controllers/navigation.coffee +++ b/app/assets/javascripts/app/controllers/navigation.coffee @@ -1,6 +1,9 @@ class App.Navigation extends App.ControllerWidgetPermanent className: 'navigation vertical' + events: + 'click .js-toggleNotifications': 'toggleNotifications' + constructor: -> super @render() @@ -202,9 +205,8 @@ class App.Navigation extends App.ControllerWidgetPermanent @emptyAndClose() ) - new App.OnlineNotificationWidget( - el: @el - ) + @notificationWidget = new App.OnlineNotificationWidget() + $('#app').append @notificationWidget.el listNavigate: (e) => if e.keyCode is 27 # close on esc @@ -468,4 +470,8 @@ class App.Navigation extends App.ControllerWidgetPermanent @renderPersonal() App.RecentView.fetchFull(load) + toggleNotifications: (event) -> + event.stopPropagation() + @notificationWidget.toggle() + App.Config.set('navigation', App.Navigation, 'Navigations') diff --git a/app/assets/javascripts/app/controllers/widget/online_notification.coffee b/app/assets/javascripts/app/controllers/widget/online_notification.coffee index a09bbcdc2..63ecb774a 100644 --- a/app/assets/javascripts/app/controllers/widget/online_notification.coffee +++ b/app/assets/javascripts/app/controllers/widget/online_notification.coffee @@ -1,8 +1,22 @@ class App.OnlineNotificationWidget extends App.Controller alreadyShown: {} + shown: false + className: 'popover popover--notifications right' + attributes: + role: 'tooltip' + + events: + 'click .js-mark': 'markAllAsRead' + 'click .js-item': 'hide' + 'click .js-remove': 'removeItem' + 'click .js-locationVerify': 'onItemClick' + 'keydown': 'listNavigate' elements: - '.js-toggleNotifications': 'toggle' + '.js-notificationsContainer': 'container' + '.js-mark': 'mark' + '.js-item': 'item' + '.js-content': 'content' constructor: -> super @@ -29,27 +43,26 @@ class App.OnlineNotificationWidget extends App.Controller # rebuild widget on auth @bind 'auth', (user) => if !user - @el.find('.js-counter').text('') + @counterUpdate(0) else if !@access() - @el.find('.js-counter').text('') + @counterUpdate(0) return - @createContainer() if @access() - @createContainer() - @subscribeId = App.OnlineNotification.subscribe(@updateContent) + @subscribeId = App.OnlineNotification.subscribe(@show) - @bind('ui:rerender', => - @updateContent() + @bind('ui:reshow', => + @show() 'popover' ) + $(window).on 'click.notifications', @hide + release: -> - @removeContainer() $(window).off 'click.notifications' - $(window).off 'keydown.notifications' App.OnlineNotification.unsubscribe(@subscribeId) + super access: -> return false if !@Session.get() @@ -58,9 +71,8 @@ class App.OnlineNotificationWidget extends App.Controller return false listNavigate: (e) => - if e.keyCode is 27 # close on esc - @hidePopover() + @hide() return else if e.keyCode is 38 # up @nudge(e, -1) @@ -69,25 +81,24 @@ class App.OnlineNotificationWidget extends App.Controller @nudge(e, 1) return else if e.keyCode is 13 # enter - $('.js-notificationsContainer .popover-content .activity-entry.is-hover .js-locationVerify').click() + @item.filter('.is-hover').find('.js-locationVerify').click() nudge: (e, position) -> # get current - navigation = $('.js-notificationsContainer .popover-content') - current = navigation.find('.activity-entry.is-hover') - if !current.get(0) - navigation.find('.activity-entry').first().addClass('is-hover') + current = @item.filter('.is-hover') + if !current.size() + @item.first().addClass('is-hover') return if position is 1 - next = current.next('.activity-entry') - if next.get(0) + next = current.next('.js-item') + if next.size() current.removeClass('is-hover') next.addClass('is-hover') else - prev = current.prev('.activity-entry') - if prev.get(0) + prev = current.prev('.is-item') + if prev.size() current.removeClass('is-hover') prev.addClass('is-hover') @@ -97,13 +108,19 @@ class App.OnlineNotificationWidget extends App.Controller @scrollToIfNeeded(prev, true) counterUpdate: (count) => + count = '' if count is 0 + + $('.js-notificationsCounter').text(count) + @count = count + + # show mark all as read if needed if !count - @$('.js-counter').text('') - return + @mark.addClass('hidden') + else + @mark.removeClass('hidden') - @$('.js-counter').text(count) - - markAllAsRead: => + markAllAsRead: (event) -> + event.preventDefault() @counterUpdate(0) @ajax( id: 'markAllAsRead' @@ -115,80 +132,49 @@ class App.OnlineNotificationWidget extends App.Controller updateHeight: -> # set height of notification popover - notificationsContainer = $('.js-notificationsContainer') heightApp = $('#app').height() heightPopoverSpacer = 22 - heightPopoverHeader = notificationsContainer.find('.popover-notificationsHeader').outerHeight(true) - heightPopoverContent = notificationsContainer.find('.popover-content').prop('scrollHeight') - heightPopoverContentNew = heightPopoverContent + heightPopoverHeader = @header.outerHeight(true) + heightPopoverContent = 0 + @item.each -> heightPopoverContent += @clientHeight + if (heightPopoverHeader + heightPopoverContent + heightPopoverSpacer) > heightApp - heightPopoverContentNew = heightApp - heightPopoverHeader - heightPopoverSpacer - notificationsContainer.addClass('is-overflowing') + heightPopoverContent = heightApp - heightPopoverHeader - heightPopoverSpacer + @container.addClass('is-overflowing') else - notificationsContainer.removeClass('is-overflowing') + @container.removeClass('is-overflowing') - notificationsContainer.find('.popover-content').css('height', "#{heightPopoverContentNew}px") - - onShow: => - @updateContent() - @updateHeight() - - # mark all notifications as read - notificationsContainer = $('.js-notificationsContainer') - notificationsContainer.find('.js-markAllAsRead').on('click', (e) => - e.preventDefault() - @markAllAsRead() - @hidePopover() - ) - - notificationsContainer.on 'click', @stopPropagation - $(window).on 'click.notifications', @hidePopover - $(window).on 'keydown.notifications', @listNavigate - - onHide: -> - $(window).off 'click.notifications' - $(window).off 'keydown.notifications' - - hidePopover: => - @toggle.popover('hide') + @content.css('height', heightPopoverContent) fetch: => load = (data) => @fetchedData = true App.OnlineNotification.refresh(data.stream, clear: true) - @updateContent() + @show() App.OnlineNotification.fetchFull(load) - updateContent: => + toggle: => + if @shown + @hide() + else + @show() + + show: => + @shown = true if !@Session.get() - $('.js-notificationsContainer .popover-content').html('') + @content.html('') return items = App.OnlineNotification.search(sortBy: 'created_at', order: 'DESC') - counter = 0 + @count = 0 for item in items if !item.seen - counter = counter + 1 - @counterUpdate(counter) + @count++ - # update title - $('.js-notificationsContainer .popover-title').html( - App.i18n.translateInline('Notifications') + " #{counter}" - ) - - # show mark all as read if needed - if counter is 0 - $('.js-notificationsContainer .js-markAllAsRead').addClass('hidden') - else - $('.js-notificationsContainer .js-markAllAsRead').removeClass('hidden') + @counterUpdate(@count) # update content items = @prepareForObjectList(items) - $('.js-notificationsContainer .popover-content').html( - $( App.view('widget/online_notification_content')(items: items) ) - ) - - notificationsContainer = $('.js-notificationsContainer .popover-content') # generate desktop notifications for item in items @@ -206,54 +192,25 @@ class App.OnlineNotificationWidget extends App.Controller ) App.OnlineNotification.play() - # execute controller again of already open (because hash hasn't changed, we need to do it manually) - notificationsContainer.find('.js-locationVerify').on('click', (e) => - @locationVerify(e) - @hidePopover() + @html App.view('widget/online_notification')( + items: items + count: @count ) - # close notification list on click - notificationsContainer.find('.activity-entry').on('click', (e) => - @hidePopover() - ) + @el.show() - # remove - notificationsContainer.find('.js-remove').on('click', (e) => - e.preventDefault() - e.stopPropagation() - row = $(e.target).closest('.activity-entry') - id = row.data('id') - App.OnlineNotification.destroy(id) - @updateHeight() - ) + hide: => + @shown = false + @el.hide() - createContainer: => - @removeContainer() - - # show popover - waitUntilOldPopoverIsRemoved = => - @toggle.popover - trigger: 'click' - container: 'body' - html: true - placement: 'right' - viewport: { selector: '#app', padding: 10 } - template: App.view('widget/online_notification')() - title: ' ' - content: ' ' - .on - 'shown.bs.popover': @onShow - 'hide.bs.popover': @onHide - - @updateContent() - - @delay( - -> waitUntilOldPopoverIsRemoved() - 600 - 'popover' - ) - - removeContainer: => - @counterUpdate(0) - @toggle.popover('destroy') + onItemClick: (event) -> + @locationVerify(event) + @hide() + removeItem: (event) -> + event.preventDefault() + event.stopPropagation() + row = $(e.target).closest('.js-item') + id = row.data('id') + App.OnlineNotification.destroy(id) + @updateHeight() diff --git a/app/assets/javascripts/app/views/generic/table.jst.eco b/app/assets/javascripts/app/views/generic/table.jst.eco index 6b52e354d..9c24b3058 100644 --- a/app/assets/javascripts/app/views/generic/table.jst.eco +++ b/app/assets/javascripts/app/views/generic/table.jst.eco @@ -56,7 +56,7 @@