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 @@
-
\ No newline at end of file
+
\ 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 @@
+
+
\ No newline at end of file