diff --git a/app/assets/javascripts/app/controllers/ticket_overview.coffee b/app/assets/javascripts/app/controllers/ticket_overview.coffee index 7fc700e74..368519ef3 100644 --- a/app/assets/javascripts/app/controllers/ticket_overview.coffee +++ b/app/assets/javascripts/app/controllers/ticket_overview.coffee @@ -755,7 +755,7 @@ class Table extends App.Controller checkbox: checkbox ) table = $(table) - table.delegate('[name="bulk_all"]', 'click', (e) -> + table.delegate('[name="bulk_all"]', 'change', (e) -> if $(e.currentTarget).prop('checked') $(e.currentTarget).closest('table').find('[name="bulk"]').prop('checked', true) else @@ -891,7 +891,7 @@ class Table extends App.Controller @bulkForm.show() # show/hide bulk action - @$('.table-overview').delegate('input[name="bulk"], input[name="bulk_all"]', 'click', (e) => + @$('.table-overview').delegate('input[name="bulk"], input[name="bulk_all"]', 'change', (e) => if @$('.table-overview').find('input[name="bulk"]:checked').length == 0 @bulkForm.hide() @bulkForm.reset() @@ -900,9 +900,21 @@ class Table extends App.Controller ) # deselect bulk_all if one item is uncheck observ - @$('.table-overview').delegate('[name="bulk"]', 'click', (e) -> - if !$(e.target).prop('checked') - $(e.target).parents().find('[name="bulk_all"]').prop('checked', false) + @$('.table-overview').delegate('[name="bulk"]', 'change', (e) => + bulkAll = @$('.table-overview').find('[name="bulk_all"]') + checkedCount = @$('.table-overview').find('input[name="bulk"]:checked').length + checkboxCount = @$('.table-overview').find('input[name="bulk"]').length + + if checkedCount is 0 + bulkAll.prop('indeterminate', false) + bulkAll.prop('checked', false) + else + if checkedCount is checkboxCount + bulkAll.prop('indeterminate', false) + bulkAll.prop('checked', true) + else + bulkAll.prop('checked', false) + bulkAll.prop('indeterminate', true) ) getSelected: -> diff --git a/app/assets/javascripts/app/views/generic/table.jst.eco b/app/assets/javascripts/app/views/generic/table.jst.eco index 8374ac870..d535c3e45 100644 --- a/app/assets/javascripts/app/views/generic/table.jst.eco +++ b/app/assets/javascripts/app/views/generic/table.jst.eco @@ -10,6 +10,7 @@ <%- @Icon('checkbox', 'icon-unchecked') %> <%- @Icon('checkbox-checked', 'icon-checked') %> + <%- @Icon('checkbox-indeterminate', 'icon-indeterminate') %> <% end %> diff --git a/app/assets/stylesheets/svg-dimensions.css b/app/assets/stylesheets/svg-dimensions.css index 2ab6116f7..ee2e6940a 100644 --- a/app/assets/stylesheets/svg-dimensions.css +++ b/app/assets/stylesheets/svg-dimensions.css @@ -4,6 +4,7 @@ .icon-arrow-up { width: 13px; height: 7px; } .icon-chat { width: 24px; height: 24px; } .icon-checkbox-checked { width: 11px; height: 11px; } +.icon-checkbox-indeterminate { width: 11px; height: 11px; } .icon-checkbox { width: 11px; height: 11px; } .icon-checkmark { width: 16px; height: 14px; } .icon-clipboard { width: 16px; height: 16px; } diff --git a/app/assets/stylesheets/zammad.scss b/app/assets/stylesheets/zammad.scss index 96d76fddd..452937072 100644 --- a/app/assets/stylesheets/zammad.scss +++ b/app/assets/stylesheets/zammad.scss @@ -1018,76 +1018,82 @@ th.align-right { align-items: center; justify-content: center; position: relative; + + .icon-checked { + color: black; + } + + .icon-unchecked { + color: hsl(60,1%,61%); + } + + .icon-indeterminate { + display: none; + color: hsl(60,1%,61%); + } + + &.is-disabled { + cursor: default; + } + + &.checkbox-replacement--fullscreen, + &.radio-replacement--fullscreen { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + } + + &.checkbox-replacement--inline, + &.radio-replacement--inline { + display: inline-flex; + margin-right: 3px; + } + + input { + pointer-events: none; + position: absolute; + opacity: 0; + + &:disabled ~ .icon { + opacity: 0.33; + fill: none; + cursor: default; + } + + &:not(:checked) ~ .icon-checked, + &:checked ~ .icon-unchecked { + display: none; + } + + &:focus:not(.is-active) ~ .icon-checked, + &:focus:not(.is-active) ~ .icon-unchecked { + box-shadow: 0 0 0 2px hsl(201,62%,90%); + color: hsl(200,71%,59%); + } + + &:indeterminate { + ~ .icon-checked, + ~ .icon-unchecked { + display: none; + } + ~ .icon-indeterminate { + display: block; + } + } + } + + + .label-text { + margin-left: 0; + } } -.checkbox-replacement.checkbox-replacement--fullscreen, -.radio-replacement.radio-replacement--fullscreen { - position: absolute; - left: 0; - top: 0; - width: 100%; - height: 100%; -} - - -.checkbox-replacement.checkbox-replacement--inline, -.radio-replacement.radio-replacement--inline { - display: inline-flex; - margin-right: 3px; -} - -.checkbox-replacement input, -.radio-replacement input { - pointer-events: none; - position: absolute; - opacity: 0; -} - -.checkbox-replacement .icon-checked, -.radio-replacement .icon-checked { - color: black; -} - -.checkbox-replacement .icon-unchecked, -.radio-replacement .icon-unchecked { - color: hsl(60,1%,61%); -} - -.checkbox-replacement.is-disabled, -.radio-replacement.is-disabled { - cursor: default; -} - -.checkbox-replacement input:disabled ~.icon, -.radio-replacement input:disabled ~.icon { - opacity: 0.33; - fill: none; - cursor: default; -} - -.checkbox-replacement input:not(:checked) ~ .icon-checked, -.checkbox-replacement input:checked ~ .icon-unchecked, -.radio-replacement input:not(:checked) ~ .icon-checked, -.radio-replacement input:checked ~ .icon-unchecked { - display: none; -} - -.checkbox-replacement input:focus:not(.is-active) ~ .icon-checked, -.checkbox-replacement input:focus:not(.is-active) ~ .icon-unchecked, -.radio-replacement input:focus:not(.is-active) ~ .icon-checked, -.radio-replacement input:focus:not(.is-active) ~ .icon-unchecked, { - box-shadow: 0 0 0 2px hsl(201,62%,90%); - color: hsl(200,71%,59%); -} - -.radio-replacement input:focus ~ .icon-checked, -.radio-replacement input:focus ~ .icon-unchecked { - border-radius: 100%; -} - -.checkbox-replacement + .label-text, -.radio-replacement + .label-text { - margin-left: 0; +.radio-replacement { + input:focus ~ .icon-checked, + input:focus ~ .icon-unchecked { + border-radius: 100%; + } } .table .checkbox-replacement, @@ -2639,7 +2645,8 @@ ol.tabs li { } .icon-checkbox, -.icon-checkbox-checked { +.icon-checkbox-checked, +.icon-checkbox-indeterminate { fill: white; } diff --git a/contrib/icon-sprite.sketch b/contrib/icon-sprite.sketch index c621909d8..4d9d54570 100644 Binary files a/contrib/icon-sprite.sketch and b/contrib/icon-sprite.sketch differ diff --git a/public/assets/images/icons.svg b/public/assets/images/icons.svg index 69291a6bc..624589138 100644 --- a/public/assets/images/icons.svg +++ b/public/assets/images/icons.svg @@ -1 +1 @@ -arrow-downarrow-leftarrow-rightarrow-upchatcheckbox-checkedcheckboxcheckmarkclipboardclockcloudcogcrowndashboarddiagonal-crossdownloaddraggabledropdown-listemail-buttonemaileyedropperfacebook-buttonfacebookformgithub-buttongitlab-buttongoogle-buttongrouphelpimportantin-processinfoline-left-arrowline-right-arrowlinkedin-buttonlistloadinglock-openlocklogotypelong-arrow-rightmagnifiermarkermessageminus-smallminusmood-badmood-goodmood-okmood-superbadmood-supergoodmutenoteoauth2-buttonone-ticketorganizationoutbound-callsoverviewspackagepaperclippenpersonphoneplus-smallplusradio-checkedradioreceived-callsreloadreopeningreply-allreplyreportsearchdetailsignoutsmall-dotsplitstatus-modified-outer-circlestatusstopwatchswitchViewtask-stateteamtemplatestoolstotal-ticketstrashtwitter-buttontwitterunmuteuserwebzoom-inzoom-out \ No newline at end of file +arrow-downarrow-leftarrow-rightarrow-upchatcheckbox-checkedcheckbox-indeterminatecheckboxcheckmarkclipboardclockcloudcogcrowndashboarddiagonal-crossdownloaddraggabledropdown-listemail-buttonemaileyedropperfacebook-buttonfacebookformgithub-buttongitlab-buttongoogle-buttongrouphelpimportantin-processinfoline-left-arrowline-right-arrowlinkedin-buttonlistloadinglock-openlocklogotypelong-arrow-rightmagnifiermarkermessageminus-smallminusmood-badmood-goodmood-okmood-superbadmood-supergoodmutenoteoauth2-buttonone-ticketorganizationoutbound-callsoverviewspackagepaperclippenpersonphoneplus-smallplusradio-checkedradioreceived-callsreloadreopeningreply-allreplyreportsearchdetailsignoutsmall-dotsplitstatus-modified-outer-circlestatusstopwatchswitchViewtask-stateteamtemplatestoolstotal-ticketstrashtwitter-buttontwitterunmuteuserwebzoom-inzoom-out \ No newline at end of file diff --git a/public/assets/images/icons/checkbox-indeterminate.svg b/public/assets/images/icons/checkbox-indeterminate.svg new file mode 100644 index 000000000..a91d66d94 --- /dev/null +++ b/public/assets/images/icons/checkbox-indeterminate.svg @@ -0,0 +1,14 @@ + + + + checkbox-indeterminate + Created with Sketch. + + + + + + + + + \ No newline at end of file