From 5e52aaac6f0581b9d1b683bc1c0d6efcab48ea13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 21 Mar 2016 11:07:37 +0100 Subject: [PATCH 01/28] ux(): checkbox style test --- .../app/plugins/panel/graph/styleEditor.html | 21 +- public/sass/_grafana.scss | 1 + public/sass/components/_gf-form.scss | 12 +- public/sass/components/_switch.scss | 196 ++++++++++++++++++ 4 files changed, 225 insertions(+), 5 deletions(-) create mode 100644 public/sass/components/_switch.scss diff --git a/public/app/plugins/panel/graph/styleEditor.html b/public/app/plugins/panel/graph/styleEditor.html index 465e8d4894e..efa39b3b3f3 100644 --- a/public/app/plugins/panel/graph/styleEditor.html +++ b/public/app/plugins/panel/graph/styleEditor.html @@ -3,15 +3,30 @@
Draw Modes
- +
+
+ + +
+
- +
+
+ + +
+
- +
+
+ + +
+
diff --git a/public/sass/_grafana.scss b/public/sass/_grafana.scss index 32643962ddc..c7b4567bfb5 100644 --- a/public/sass/_grafana.scss +++ b/public/sass/_grafana.scss @@ -35,6 +35,7 @@ @import "components/navs"; @import "components/tabs"; @import "components/alerts"; +@import "components/switch"; @import "components/tooltip"; @import "components/tags"; @import "components/panel_graph"; diff --git a/public/sass/components/_gf-form.scss b/public/sass/components/_gf-form.scss index 3d93df79a29..95bbf6cb7ea 100644 --- a/public/sass/components/_gf-form.scss +++ b/public/sass/components/_gf-form.scss @@ -50,6 +50,12 @@ $gf-form-label-margin: 0.25rem; @include border-radius($label-border-radius-sm); } +.gf-form-switch-wrapper { + margin-right: $gf-form-label-margin; + padding: $input-padding-y $input-padding-x; + background-color: $input-bg; +} + .gf-form-checkbox { flex-shrink: 0; padding: $input-padding-y $input-padding-x; @@ -139,8 +145,8 @@ $gf-form-label-margin: 0.25rem; } } -.gf-form-select-wrapper + .gf-form-select-wrapper { - margin-left: $gf-form-label-margin; +.gf-form-select-wrapper + .gf-form-select-wrapper { + margin-left: $gf-form-label-margin; } .gf-form-btn { @@ -149,3 +155,5 @@ $gf-form-label-margin: 0.25rem; flex-shrink: 0; flex-grow: 0; } + + diff --git a/public/sass/components/_switch.scss b/public/sass/components/_switch.scss new file mode 100644 index 00000000000..be02ade9d77 --- /dev/null +++ b/public/sass/components/_switch.scss @@ -0,0 +1,196 @@ +$switch-border-radius: 1rem; +$switch-width: 3.5rem; +$switch-height: 1.5rem; + +/* ============================================================ + COMMON +============================================================ */ +.cmn-toggle { + position: absolute; + margin-left: -9999px; + visibility: hidden; +} +.cmn-toggle + label { + display: block; + position: relative; + cursor: pointer; + outline: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +/* ============================================================ + SWITCH 1 - ROUND +============================================================ */ +input.cmn-toggle-round + label { + padding: 2px; + width: $switch-width; + height: $switch-height; + background-color: $dark-1; + border-radius: $switch-border-radius; +} + +input.cmn-toggle-round + label:before, input.cmn-toggle-round + label:after { + display: block; + position: absolute; + top: 1px; + left: 1px; + bottom: 1px; + content: ""; +} + +input.cmn-toggle-round + label:before { + right: 1px; + background-color: $card-background; + border-radius: $switch-border-radius; + box-shadow: $card-shadow; + transition: background 0.4s; +} + +input.cmn-toggle-round + label:after { + width: $switch-height; + background-color: $dark-5; + border-radius: 100%; + box-shadow: $card-shadow; + transition: margin 0.4s; +} + +input.cmn-toggle-round:checked + label:before { + background-color: $blue; +} + +input.cmn-toggle-round:checked + label:after { + margin-left: $switch-width - $switch-height; +} + +/* ============================================================ + SWITCH 2 - ROUND FLAT +============================================================ */ +input.cmn-toggle-round-flat + label { + padding: 2px; + width: 120px; + height: 60px; + background-color: #dddddd; + -webkit-border-radius: 60px; + -moz-border-radius: 60px; + -ms-border-radius: 60px; + -o-border-radius: 60px; + border-radius: 60px; + -webkit-transition: background 0.4s; + -moz-transition: background 0.4s; + -o-transition: background 0.4s; + transition: background 0.4s; +} +input.cmn-toggle-round-flat + label:before, input.cmn-toggle-round-flat + label:after { + display: block; + position: absolute; + content: ""; +} +input.cmn-toggle-round-flat + label:before { + top: 2px; + left: 2px; + bottom: 2px; + right: 2px; + background-color: #fff; + -webkit-border-radius: 60px; + -moz-border-radius: 60px; + -ms-border-radius: 60px; + -o-border-radius: 60px; + border-radius: 60px; + -webkit-transition: background 0.4s; + -moz-transition: background 0.4s; + -o-transition: background 0.4s; + transition: background 0.4s; +} +input.cmn-toggle-round-flat + label:after { + top: 4px; + left: 4px; + bottom: 4px; + width: 52px; + background-color: #dddddd; + -webkit-border-radius: 52px; + -moz-border-radius: 52px; + -ms-border-radius: 52px; + -o-border-radius: 52px; + border-radius: 52px; + -webkit-transition: margin 0.4s, background 0.4s; + -moz-transition: margin 0.4s, background 0.4s; + -o-transition: margin 0.4s, background 0.4s; + transition: margin 0.4s, background 0.4s; +} +input.cmn-toggle-round-flat:checked + label { + background-color: #8ce196; +} +input.cmn-toggle-round-flat:checked + label:after { + margin-left: 60px; + background-color: #8ce196; +} + +/* ============================================================ + SWITCH 3 - YES NO +============================================================ */ +input.cmn-toggle-yes-no + label { + padding: 2px; + width: 120px; + height: 60px; +} +input.cmn-toggle-yes-no + label:before, input.cmn-toggle-yes-no + label:after { + display: block; + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + color: #fff; + font-family: "Roboto Slab", serif; + font-size: 20px; + text-align: center; + line-height: 60px; +} +input.cmn-toggle-yes-no + label:before { + background-color: #dddddd; + content: attr(data-off); + -webkit-transition: -webkit-transform 0.5s; + -moz-transition: -moz-transform 0.5s; + -o-transition: -o-transform 0.5s; + transition: transform 0.5s; + -webkit-backface-visibility: hidden; + -moz-backface-visibility: hidden; + -ms-backface-visibility: hidden; + -o-backface-visibility: hidden; + backface-visibility: hidden; +} +input.cmn-toggle-yes-no + label:after { + background-color: #8ce196; + content: attr(data-on); + -webkit-transition: -webkit-transform 0.5s; + -moz-transition: -moz-transform 0.5s; + -o-transition: -o-transform 0.5s; + transition: transform 0.5s; + -webkit-transform: rotateY(180deg); + -moz-transform: rotateY(180deg); + -ms-transform: rotateY(180deg); + -o-transform: rotateY(180deg); + transform: rotateY(180deg); + -webkit-backface-visibility: hidden; + -moz-backface-visibility: hidden; + -ms-backface-visibility: hidden; + -o-backface-visibility: hidden; + backface-visibility: hidden; +} +input.cmn-toggle-yes-no:checked + label:before { + -webkit-transform: rotateY(180deg); + -moz-transform: rotateY(180deg); + -ms-transform: rotateY(180deg); + -o-transform: rotateY(180deg); + transform: rotateY(180deg); +} +input.cmn-toggle-yes-no:checked + label:after { + -webkit-transform: rotateY(0); + -moz-transform: rotateY(0); + -ms-transform: rotateY(0); + -o-transform: rotateY(0); + transform: rotateY(0); +} From 530b6a5088c5244827d942428b5857756084a500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 21 Mar 2016 11:27:53 +0100 Subject: [PATCH 02/28] ux(): another checkbox design --- .../app/plugins/panel/graph/styleEditor.html | 14 ++- public/sass/base/_forms.scss | 2 +- public/sass/components/_gf-form.scss | 2 - public/sass/components/_switch.scss | 111 +++--------------- 4 files changed, 28 insertions(+), 101 deletions(-) diff --git a/public/app/plugins/panel/graph/styleEditor.html b/public/app/plugins/panel/graph/styleEditor.html index efa39b3b3f3..e10071fc0e7 100644 --- a/public/app/plugins/panel/graph/styleEditor.html +++ b/public/app/plugins/panel/graph/styleEditor.html @@ -80,11 +80,21 @@
Multiple Series
- +
+
+ + +
+
- +
+
+ + +
+
diff --git a/public/sass/base/_forms.scss b/public/sass/base/_forms.scss index 4f1d0778e0b..3891adc4085 100644 --- a/public/sass/base/_forms.scss +++ b/public/sass/base/_forms.scss @@ -174,7 +174,7 @@ label.cr1 { cursor:pointer; } -input[type="checkbox"]:checked+label { +input[type="checkbox"].cr1:checked+label { background: url($checkboxImageUrl) 0px -18px no-repeat; } diff --git a/public/sass/components/_gf-form.scss b/public/sass/components/_gf-form.scss index 95bbf6cb7ea..cd500052d9a 100644 --- a/public/sass/components/_gf-form.scss +++ b/public/sass/components/_gf-form.scss @@ -52,8 +52,6 @@ $gf-form-label-margin: 0.25rem; .gf-form-switch-wrapper { margin-right: $gf-form-label-margin; - padding: $input-padding-y $input-padding-x; - background-color: $input-bg; } .gf-form-checkbox { diff --git a/public/sass/components/_switch.scss b/public/sass/components/_switch.scss index be02ade9d77..01b2f535b48 100644 --- a/public/sass/components/_switch.scss +++ b/public/sass/components/_switch.scss @@ -65,77 +65,17 @@ input.cmn-toggle-round:checked + label:after { margin-left: $switch-width - $switch-height; } -/* ============================================================ - SWITCH 2 - ROUND FLAT -============================================================ */ -input.cmn-toggle-round-flat + label { - padding: 2px; - width: 120px; - height: 60px; - background-color: #dddddd; - -webkit-border-radius: 60px; - -moz-border-radius: 60px; - -ms-border-radius: 60px; - -o-border-radius: 60px; - border-radius: 60px; - -webkit-transition: background 0.4s; - -moz-transition: background 0.4s; - -o-transition: background 0.4s; - transition: background 0.4s; -} -input.cmn-toggle-round-flat + label:before, input.cmn-toggle-round-flat + label:after { - display: block; - position: absolute; - content: ""; -} -input.cmn-toggle-round-flat + label:before { - top: 2px; - left: 2px; - bottom: 2px; - right: 2px; - background-color: #fff; - -webkit-border-radius: 60px; - -moz-border-radius: 60px; - -ms-border-radius: 60px; - -o-border-radius: 60px; - border-radius: 60px; - -webkit-transition: background 0.4s; - -moz-transition: background 0.4s; - -o-transition: background 0.4s; - transition: background 0.4s; -} -input.cmn-toggle-round-flat + label:after { - top: 4px; - left: 4px; - bottom: 4px; - width: 52px; - background-color: #dddddd; - -webkit-border-radius: 52px; - -moz-border-radius: 52px; - -ms-border-radius: 52px; - -o-border-radius: 52px; - border-radius: 52px; - -webkit-transition: margin 0.4s, background 0.4s; - -moz-transition: margin 0.4s, background 0.4s; - -o-transition: margin 0.4s, background 0.4s; - transition: margin 0.4s, background 0.4s; -} -input.cmn-toggle-round-flat:checked + label { - background-color: #8ce196; -} -input.cmn-toggle-round-flat:checked + label:after { - margin-left: 60px; - background-color: #8ce196; -} - /* ============================================================ SWITCH 3 - YES NO ============================================================ */ input.cmn-toggle-yes-no + label { padding: 2px; - width: 120px; - height: 60px; + width: 5rem; + height: 2.6rem; + padding: $input-padding-y $input-padding-x; + background-color: $input-bg; } + input.cmn-toggle-yes-no + label:before, input.cmn-toggle-yes-no + label:after { display: block; position: absolute; @@ -144,53 +84,32 @@ input.cmn-toggle-yes-no + label:before, input.cmn-toggle-yes-no + label:after { bottom: 0; right: 0; color: #fff; - font-family: "Roboto Slab", serif; - font-size: 20px; + font-family: "Open Sans"; + font-size: $font-size-sm; text-align: center; - line-height: 60px; + line-height: 2.6rem; } + input.cmn-toggle-yes-no + label:before { - background-color: #dddddd; + @include buttonBackground($btn-inverse-bg, $btn-inverse-bg-hl); content: attr(data-off); - -webkit-transition: -webkit-transform 0.5s; - -moz-transition: -moz-transform 0.5s; - -o-transition: -o-transform 0.5s; transition: transform 0.5s; - -webkit-backface-visibility: hidden; - -moz-backface-visibility: hidden; - -ms-backface-visibility: hidden; - -o-backface-visibility: hidden; backface-visibility: hidden; } + input.cmn-toggle-yes-no + label:after { - background-color: #8ce196; + //@include buttonBackground($btn-success-bg, $btn-success-bg-hl); + @include buttonBackground($btn-secondary-bg, $btn-secondary-bg-hl); content: attr(data-on); - -webkit-transition: -webkit-transform 0.5s; - -moz-transition: -moz-transform 0.5s; - -o-transition: -o-transform 0.5s; transition: transform 0.5s; - -webkit-transform: rotateY(180deg); - -moz-transform: rotateY(180deg); - -ms-transform: rotateY(180deg); - -o-transform: rotateY(180deg); transform: rotateY(180deg); - -webkit-backface-visibility: hidden; - -moz-backface-visibility: hidden; - -ms-backface-visibility: hidden; - -o-backface-visibility: hidden; backface-visibility: hidden; } + input.cmn-toggle-yes-no:checked + label:before { - -webkit-transform: rotateY(180deg); - -moz-transform: rotateY(180deg); - -ms-transform: rotateY(180deg); - -o-transform: rotateY(180deg); transform: rotateY(180deg); } + input.cmn-toggle-yes-no:checked + label:after { - -webkit-transform: rotateY(0); - -moz-transform: rotateY(0); - -ms-transform: rotateY(0); - -o-transform: rotateY(0); transform: rotateY(0); } From ae255a7adf04509494150fdf0050d1e08a94768f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 21 Mar 2016 13:37:56 +0100 Subject: [PATCH 03/28] ux(): new checkbox tweaks --- .../app/plugins/panel/graph/styleEditor.html | 238 +++++++++--------- public/sass/_variables.dark.scss | 2 +- public/sass/components/_switch.scss | 155 ++++-------- 3 files changed, 168 insertions(+), 227 deletions(-) diff --git a/public/app/plugins/panel/graph/styleEditor.html b/public/app/plugins/panel/graph/styleEditor.html index e10071fc0e7..395d393c21a 100644 --- a/public/app/plugins/panel/graph/styleEditor.html +++ b/public/app/plugins/panel/graph/styleEditor.html @@ -3,146 +3,136 @@
Draw Modes
-
-
- - -
+
+ +
-
-
- - -
+
+ +
-
-
- -
-
- - -
+
+
+ +
+ +
-
-
-
-
Mode Options
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- - -
-
-
-
Misc options
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
+
+
+
+
Mode Options
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ + +
+
+
+
Misc options
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
-
-
Multiple Series
-
- -
-
- - -
+
+
Multiple Series
+
+ +
+ +
-
-
- -
-
- - -
+
+
+ +
+ +
-
-
- -
- -
-
-
+
+
+ +
+ +
+
+
-
-
Series specific overrides Regex match example: /server[0-3]/i
-
-
-
    -
  • - -
  • +
    +
    Series specific overrides Regex match example: /server[0-3]/i
    +
    +
    +
      +
    • + +
    • -
    • - alias or regex -
    • +
    • + alias or regex +
    • -
    • - -
    • +
    • + +
    • -
    • - - - Color: - - - {{option.name}}: {{option.value}} - -
    • +
    • + + + Color: + + + {{option.name}}: {{option.value}} + +
    • - -
    -
    -
    -
    + +
+
+
+
- -
+ +
diff --git a/public/sass/_variables.dark.scss b/public/sass/_variables.dark.scss index 84b01692069..b727c59fd33 100644 --- a/public/sass/_variables.dark.scss +++ b/public/sass/_variables.dark.scss @@ -124,7 +124,7 @@ $btn-primary-bg: $brand-primary; $btn-primary-bg-hl: lighten($brand-primary, 8%); $btn-secondary-bg: $blue-dark; -$btn-secondary-bg-hl: lighten($blue-dark, 3%); +$btn-secondary-bg-hl: lighten($blue-dark, 5%); $btn-success-bg: lighten($green, 3%); $btn-success-bg-hl: darken($green, 3%); diff --git a/public/sass/components/_switch.scss b/public/sass/components/_switch.scss index 01b2f535b48..b65639a5cc1 100644 --- a/public/sass/components/_switch.scss +++ b/public/sass/components/_switch.scss @@ -2,114 +2,65 @@ $switch-border-radius: 1rem; $switch-width: 3.5rem; $switch-height: 1.5rem; -/* ============================================================ - COMMON -============================================================ */ -.cmn-toggle { - position: absolute; - margin-left: -9999px; - visibility: hidden; -} -.cmn-toggle + label { - display: block; - position: relative; - cursor: pointer; - outline: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -/* ============================================================ - SWITCH 1 - ROUND -============================================================ */ -input.cmn-toggle-round + label { - padding: 2px; - width: $switch-width; - height: $switch-height; - background-color: $dark-1; - border-radius: $switch-border-radius; -} - -input.cmn-toggle-round + label:before, input.cmn-toggle-round + label:after { - display: block; - position: absolute; - top: 1px; - left: 1px; - bottom: 1px; - content: ""; -} - -input.cmn-toggle-round + label:before { - right: 1px; - background-color: $card-background; - border-radius: $switch-border-radius; - box-shadow: $card-shadow; - transition: background 0.4s; -} - -input.cmn-toggle-round + label:after { - width: $switch-height; - background-color: $dark-5; - border-radius: 100%; - box-shadow: $card-shadow; - transition: margin 0.4s; -} - -input.cmn-toggle-round:checked + label:before { - background-color: $blue; -} - -input.cmn-toggle-round:checked + label:after { - margin-left: $switch-width - $switch-height; -} - /* ============================================================ SWITCH 3 - YES NO ============================================================ */ -input.cmn-toggle-yes-no + label { - padding: 2px; - width: 5rem; - height: 2.6rem; - padding: $input-padding-y $input-padding-x; - background-color: $input-bg; -} -input.cmn-toggle-yes-no + label:before, input.cmn-toggle-yes-no + label:after { - display: block; - position: absolute; - top: 0; - left: 0; - bottom: 0; - right: 0; - color: #fff; - font-family: "Open Sans"; - font-size: $font-size-sm; - text-align: center; - line-height: 2.6rem; -} +.gf-form-switch { + position: relative; -input.cmn-toggle-yes-no + label:before { - @include buttonBackground($btn-inverse-bg, $btn-inverse-bg-hl); - content: attr(data-off); - transition: transform 0.5s; - backface-visibility: hidden; -} + input { + position: absolute; + margin-left: -9999px; + visibility: hidden; + display: none; + } -input.cmn-toggle-yes-no + label:after { - //@include buttonBackground($btn-success-bg, $btn-success-bg-hl); - @include buttonBackground($btn-secondary-bg, $btn-secondary-bg-hl); - content: attr(data-on); - transition: transform 0.5s; - transform: rotateY(180deg); - backface-visibility: hidden; -} + input + label { + display: block; + position: relative; + cursor: pointer; + outline: none; + user-select: none; + width: 5rem; + height: 2.65rem; + background-color: $page-bg; + } -input.cmn-toggle-yes-no:checked + label:before { - transform: rotateY(180deg); -} + input + label:before, input + label:after { + display: block; + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + color: #fff; + font-family: "Open Sans"; + font-size: $font-size-sm; + text-align: center; + line-height: 2.6rem; + } -input.cmn-toggle-yes-no:checked + label:after { - transform: rotateY(0); + input + label:before { + @include buttonBackground($input-bg, lighten($input-bg, 5%)); + content: attr(data-off); + transition: transform 0.5s; + backface-visibility: hidden; + } + + input + label:after { + @include buttonBackground($btn-secondary-bg, $btn-secondary-bg-hl); + content: attr(data-on); + transition: transform 0.5s; + transform: rotateY(180deg); + backface-visibility: hidden; + } + + input:checked + label:before { + transform: rotateY(180deg); + } + + input:checked + label:after { + transform: rotateY(0); + } } From fc983f97514bc451b976157c1107b375a3a36338 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 21 Mar 2016 14:08:18 +0100 Subject: [PATCH 04/28] ux(): checkbox v2 tweaks --- public/app/features/panel/partials/panelTime.html | 10 +++++++--- public/app/plugins/panel/graph/styleEditor.html | 15 +++++++++------ public/sass/components/_switch.scss | 6 ++++-- public/sass/utils/_widths.scss | 4 ++-- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/public/app/features/panel/partials/panelTime.html b/public/app/features/panel/partials/panelTime.html index 7fd398a9282..77a554faa86 100644 --- a/public/app/features/panel/partials/panelTime.html +++ b/public/app/features/panel/partials/panelTime.html @@ -9,7 +9,7 @@ + ng-change="ctrl.refresh()" ng-model-onblur>
@@ -20,14 +20,18 @@ Amount + ng-change="ctrl.refresh()" ng-model-onblur>
- + +
+ + +
diff --git a/public/app/plugins/panel/graph/styleEditor.html b/public/app/plugins/panel/graph/styleEditor.html index 395d393c21a..f1079341f6d 100644 --- a/public/app/plugins/panel/graph/styleEditor.html +++ b/public/app/plugins/panel/graph/styleEditor.html @@ -2,14 +2,14 @@
Draw Modes
- +
- +
@@ -27,25 +27,28 @@
Mode Options
-
+
-
+
-
+
- +
+ + +
diff --git a/public/sass/components/_switch.scss b/public/sass/components/_switch.scss index b65639a5cc1..74184a4fcde 100644 --- a/public/sass/components/_switch.scss +++ b/public/sass/components/_switch.scss @@ -8,6 +8,9 @@ $switch-height: 1.5rem; .gf-form-switch { position: relative; + max-width: 4.5rem; + flex-grow: 1; + min-width: 4.0rem; input { position: absolute; @@ -22,7 +25,7 @@ $switch-height: 1.5rem; cursor: pointer; outline: none; user-select: none; - width: 5rem; + width: 100%; height: 2.65rem; background-color: $page-bg; } @@ -35,7 +38,6 @@ $switch-height: 1.5rem; bottom: 0; right: 0; color: #fff; - font-family: "Open Sans"; font-size: $font-size-sm; text-align: center; line-height: 2.6rem; diff --git a/public/sass/utils/_widths.scss b/public/sass/utils/_widths.scss index bd6fc78ef90..b4bdbdb6ccc 100644 --- a/public/sass/utils/_widths.scss +++ b/public/sass/utils/_widths.scss @@ -6,13 +6,13 @@ // widths @for $i from 1 through 30 { .width-#{$i} { - width: ($spacer * $i) - $gf-form-margin; + width: ($spacer * $i) - $gf-form-margin !important; } } @for $i from 1 through 30 { .max-width-#{$i} { - max-width: ($spacer * $i) - $gf-form-margin; + max-width: ($spacer * $i) - $gf-form-margin !important; flex-grow: 1; } } From 98206ab49f704c66b00aeb3f7a186ec4a2677ea5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 21 Mar 2016 21:24:06 +0100 Subject: [PATCH 05/28] ux(): created new gf-form-switch directive clean/refactoring --- public/app/core/components/switch.ts | 47 +++++++++++++ public/app/core/core.ts | 2 + .../features/panel/partials/panelTime.html | 17 ++--- .../app/plugins/panel/graph/styleEditor.html | 66 +++++++------------ public/sass/components/_gf-form.scss | 12 ++-- 5 files changed, 86 insertions(+), 58 deletions(-) create mode 100644 public/app/core/components/switch.ts diff --git a/public/app/core/components/switch.ts b/public/app/core/components/switch.ts new file mode 100644 index 00000000000..72e54857e26 --- /dev/null +++ b/public/app/core/components/switch.ts @@ -0,0 +1,47 @@ +/// + +import config from 'app/core/config'; +import _ from 'lodash'; +import $ from 'jquery'; +import coreModule from 'app/core/core_module'; + +var template = ` + +
+ + +
+`; + +export class SwitchCtrl { + onChange: any; + + internalOnChange() { + return new Promise(resolve => { + setTimeout(() => { + this.onChange(); + resolve(); + }); + }); + } + +} + +export function switchDirective() { + return { + restrict: 'E', + controller: SwitchCtrl, + controllerAs: 'ctrl', + bindToController: true, + scope: { + checked: "=", + label: "@", + labelClass: "@", + switchClass: "@", + onChange: "&", + }, + template: template, + }; +} + +coreModule.directive('gfFormSwitch', switchDirective); diff --git a/public/app/core/core.ts b/public/app/core/core.ts index 2ab7ea01410..b0922af3f39 100644 --- a/public/app/core/core.ts +++ b/public/app/core/core.ts @@ -29,6 +29,7 @@ import {colorPicker} from './components/colorpicker'; import {navbarDirective} from './components/navbar/navbar'; import {arrayJoin} from './directives/array_join'; import {layoutSelector} from './components/layout_selector/layout_selector'; +import {switchDirective} from './components/switch'; import 'app/core/controllers/all'; import 'app/core/services/all'; import 'app/core/routes/routes'; @@ -44,5 +45,6 @@ export { searchDirective, colorPicker, layoutSelector, + switchDirective, infoPopover }; diff --git a/public/app/features/panel/partials/panelTime.html b/public/app/features/panel/partials/panelTime.html index 77a554faa86..4047558317f 100644 --- a/public/app/features/panel/partials/panelTime.html +++ b/public/app/features/panel/partials/panelTime.html @@ -23,15 +23,16 @@ ng-change="ctrl.refresh()" ng-model-onblur>
-
- - - - -
- - +
+
+ + +
+ +
diff --git a/public/app/plugins/panel/graph/styleEditor.html b/public/app/plugins/panel/graph/styleEditor.html index f1079341f6d..17a9d702329 100644 --- a/public/app/plugins/panel/graph/styleEditor.html +++ b/public/app/plugins/panel/graph/styleEditor.html @@ -1,27 +1,18 @@
Draw Modes
-
- -
- - -
-
-
- -
- - -
-
-
- -
- - -
-
+ + + + + +
Mode Options
@@ -43,13 +34,10 @@
-
- -
- - -
-
+ +
Misc options
@@ -75,20 +63,14 @@
Multiple Series
-
- -
- - -
-
-
- -
- - -
-
+ + + +
diff --git a/public/sass/components/_gf-form.scss b/public/sass/components/_gf-form.scss index cd500052d9a..cecbf6e5996 100644 --- a/public/sass/components/_gf-form.scss +++ b/public/sass/components/_gf-form.scss @@ -1,9 +1,7 @@ $gf-form-margin: 0.25rem; -$gf-form-label-margin: 0.25rem; .gf-form { margin-bottom: $gf-form-margin; - margin-right: $gf-form-margin; display: flex; flex-direction: row; align-items: center; @@ -38,20 +36,20 @@ $gf-form-label-margin: 0.25rem; .gf-form-label { padding: $input-padding-y $input-padding-x; + margin-right: $gf-form-margin; line-height: $input-line-height; flex-shrink: 0; background-color: $input-label-bg; display: block; font-size: $font-size-sm; - margin-right: $gf-form-label-margin; border: $input-btn-border-width solid transparent; @include border-radius($label-border-radius-sm); } .gf-form-switch-wrapper { - margin-right: $gf-form-label-margin; + margin-right: $gf-form-margin; } .gf-form-checkbox { @@ -71,6 +69,7 @@ $gf-form-label-margin: 0.25rem; display: block; width: 100%; padding: $input-padding-y $input-padding-x; + margin-right: $gf-form-margin; font-size: $font-size-base; line-height: $input-line-height; color: $input-color; @@ -113,6 +112,7 @@ $gf-form-label-margin: 0.25rem; } .gf-form-select-wrapper { + margin-right: $gf-form-margin; position: relative; background-color: $input-bg; @@ -143,10 +143,6 @@ $gf-form-label-margin: 0.25rem; } } -.gf-form-select-wrapper + .gf-form-select-wrapper { - margin-left: $gf-form-label-margin; -} - .gf-form-btn { padding: $input-padding-y $input-padding-x; line-height: $input-line-height; From 64312ceded9342850fd3533f0743a1f818277b3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 21 Mar 2016 21:36:30 +0100 Subject: [PATCH 06/28] ux(): updated http settings view with new checkboxes --- .../features/dashboard/partials/settings.html | 12 +++--------- .../plugins/partials/ds_http_settings.html | 18 ++++++++++++------ public/sass/components/_gf-form.scss | 7 +++---- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/public/app/features/dashboard/partials/settings.html b/public/app/features/dashboard/partials/settings.html index deccd22305b..8cf19141e38 100644 --- a/public/app/features/dashboard/partials/settings.html +++ b/public/app/features/dashboard/partials/settings.html @@ -41,15 +41,9 @@
On/Off Toggles
-
- -
-
- -
-
- -
+ + +
diff --git a/public/app/features/plugins/partials/ds_http_settings.html b/public/app/features/plugins/partials/ds_http_settings.html index 65c205714bc..c49de6967c9 100644 --- a/public/app/features/plugins/partials/ds_http_settings.html +++ b/public/app/features/plugins/partials/ds_http_settings.html @@ -29,12 +29,18 @@
-
- - Http Auth - - - Tip for with credentials +
+
+ +
+ + + +
diff --git a/public/sass/components/_gf-form.scss b/public/sass/components/_gf-form.scss index cecbf6e5996..f92e712eabf 100644 --- a/public/sass/components/_gf-form.scss +++ b/public/sass/components/_gf-form.scss @@ -48,10 +48,6 @@ $gf-form-margin: 0.25rem; @include border-radius($label-border-radius-sm); } -.gf-form-switch-wrapper { - margin-right: $gf-form-margin; -} - .gf-form-checkbox { flex-shrink: 0; padding: $input-padding-y $input-padding-x; @@ -150,4 +146,7 @@ $gf-form-margin: 0.25rem; flex-grow: 0; } +.gf-form-switch { + margin-right: $gf-form-margin; +} From e65fd45c65818c2bf56912cf219cd709dba03537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 23 Mar 2016 21:10:06 +0100 Subject: [PATCH 07/28] ux(): checkbox experiment --- public/sass/components/_switch.scss | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/public/sass/components/_switch.scss b/public/sass/components/_switch.scss index 74184a4fcde..400ded49a16 100644 --- a/public/sass/components/_switch.scss +++ b/public/sass/components/_switch.scss @@ -40,20 +40,35 @@ $switch-height: 1.5rem; color: #fff; font-size: $font-size-sm; text-align: center; - line-height: 2.6rem; + line-height: 2.8rem; + font-size: 150%; } input + label:before { @include buttonBackground($input-bg, lighten($input-bg, 5%)); - content: attr(data-off); - transition: transform 0.5s; + //content: attr(data-off); + font-family: 'FontAwesome'; + //content: "\f00c"; + + //content: "\f096"; // square-o + content: "\f046"; // check-square-o + color: darken($text-color-weak, 17%); + transition: transform 0.4s; backface-visibility: hidden; + text-shadow: 0px 0px 5px rgb(45, 45, 45); } input + label:after { - @include buttonBackground($btn-secondary-bg, $btn-secondary-bg-hl); - content: attr(data-on); - transition: transform 0.5s; + @include buttonBackground($input-bg, lighten($input-bg, 5%)); + //@include buttonBackground($btn-secondary-bg, $btn-secondary-bg-hl); + //content: attr(data-on); + //content: "\f00c"; + content: "\f046"; // check-square-o + color: #FF8600; + text-shadow: 0px 0px 5px rgb(45, 45, 45); + + font-family: 'FontAwesome'; + transition: transform 0.4s; transform: rotateY(180deg); backface-visibility: hidden; } From c2ef2ef287e55b167c5ed7c279d0242c51867401 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 23 Mar 2016 21:18:37 +0100 Subject: [PATCH 08/28] ux(): updated checkbox v3 experiment --- public/sass/components/_switch.scss | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/public/sass/components/_switch.scss b/public/sass/components/_switch.scss index 400ded49a16..2cc509b25ce 100644 --- a/public/sass/components/_switch.scss +++ b/public/sass/components/_switch.scss @@ -50,9 +50,9 @@ $switch-height: 1.5rem; font-family: 'FontAwesome'; //content: "\f00c"; - //content: "\f096"; // square-o - content: "\f046"; // check-square-o - color: darken($text-color-weak, 17%); + content: "\f096"; // square-o + //content: "\f046"; // check-square-o + color: darken($text-color-weak, 10%); transition: transform 0.4s; backface-visibility: hidden; text-shadow: 0px 0px 5px rgb(45, 45, 45); From b3b63f836af939891278c601ae724fe85ade8da2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 23 Mar 2016 22:28:38 +0100 Subject: [PATCH 09/28] ux(): checkbox v3 with hover style --- public/sass/components/_switch.scss | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/public/sass/components/_switch.scss b/public/sass/components/_switch.scss index 2cc509b25ce..c43ef01794d 100644 --- a/public/sass/components/_switch.scss +++ b/public/sass/components/_switch.scss @@ -31,6 +31,8 @@ $switch-height: 1.5rem; } input + label:before, input + label:after { + @include buttonBackground($input-bg, $input-bg); + display: block; position: absolute; top: 0; @@ -44,8 +46,14 @@ $switch-height: 1.5rem; font-size: 150%; } + &:hover { + input + label:before, input + label:after { + @include buttonBackground($input-bg, lighten($input-bg, 5%)); + color: lighten(#FF8600, 10%); + } + } + input + label:before { - @include buttonBackground($input-bg, lighten($input-bg, 5%)); //content: attr(data-off); font-family: 'FontAwesome'; //content: "\f00c"; @@ -59,7 +67,6 @@ $switch-height: 1.5rem; } input + label:after { - @include buttonBackground($input-bg, lighten($input-bg, 5%)); //@include buttonBackground($btn-secondary-bg, $btn-secondary-bg-hl); //content: attr(data-on); //content: "\f00c"; From ee7afcbe9e97e39fe96234302654fa85ee8d4eb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 23 Mar 2016 22:40:48 +0100 Subject: [PATCH 10/28] ux() some final tweaks --- public/sass/components/_switch.scss | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/public/sass/components/_switch.scss b/public/sass/components/_switch.scss index c43ef01794d..fd4a77ca3af 100644 --- a/public/sass/components/_switch.scss +++ b/public/sass/components/_switch.scss @@ -47,10 +47,18 @@ $switch-height: 1.5rem; } &:hover { - input + label:before, input + label:after { + input + label:before { + @include buttonBackground($input-bg, lighten($input-bg, 5%)); + color: $text-color; + text-shadow: 1px 1px 4px rgb(45, 45, 45); + } + + input + label:after { @include buttonBackground($input-bg, lighten($input-bg, 5%)); color: lighten(#FF8600, 10%); + text-shadow: 1px 1px 4px rgb(25, 25, 25); } + } input + label:before { @@ -63,7 +71,7 @@ $switch-height: 1.5rem; color: darken($text-color-weak, 10%); transition: transform 0.4s; backface-visibility: hidden; - text-shadow: 0px 0px 5px rgb(45, 45, 45); + text-shadow: 1px 1px 4px rgb(45, 45, 45); } input + label:after { @@ -72,7 +80,7 @@ $switch-height: 1.5rem; //content: "\f00c"; content: "\f046"; // check-square-o color: #FF8600; - text-shadow: 0px 0px 5px rgb(45, 45, 45); + text-shadow: 1px 1px 4px rgb(25, 25, 25); font-family: 'FontAwesome'; transition: transform 0.4s; From 14326b626e7a6e8c80a8a1b529b85f3600050212 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 28 Mar 2016 13:10:42 +0200 Subject: [PATCH 11/28] ux(): checkbox now works in dark and white theme --- pkg/api/api.go | 2 + public/app/core/components/switch.ts | 7 +- .../features/dashboard/partials/settings.html | 12 +-- .../features/plugins/partials/ds_edit.html | 89 ++++++++++--------- public/sass/_variables.dark.scss | 15 ++-- public/sass/_variables.light.scss | 4 + public/sass/components/_gf-form.scss | 13 --- public/sass/components/_switch.scss | 25 ++---- 8 files changed, 81 insertions(+), 86 deletions(-) diff --git a/pkg/api/api.go b/pkg/api/api.go index 06aee594d42..23a65c6a972 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -45,6 +45,8 @@ func Register(r *macaron.Macaron) { r.Get("/admin/orgs/edit/:id", reqGrafanaAdmin, Index) r.Get("/admin/stats", reqGrafanaAdmin, Index) + r.Get("/styleguide", reqSignedIn, Index) + r.Get("/plugins", reqSignedIn, Index) r.Get("/plugins/:id/edit", reqSignedIn, Index) r.Get("/plugins/:id/page/:page", reqSignedIn, Index) diff --git a/public/app/core/components/switch.ts b/public/app/core/components/switch.ts index 72e54857e26..dea9c0611cb 100644 --- a/public/app/core/components/switch.ts +++ b/public/app/core/components/switch.ts @@ -7,7 +7,7 @@ import coreModule from 'app/core/core_module'; var template = ` -
+
@@ -15,6 +15,11 @@ var template = ` export class SwitchCtrl { onChange: any; + checked: any; + + constructor() { + console.log('property: ' + this.checked, this); + } internalOnChange() { return new Promise(resolve => { diff --git a/public/app/features/dashboard/partials/settings.html b/public/app/features/dashboard/partials/settings.html index 8cf19141e38..3ab3a582e49 100644 --- a/public/app/features/dashboard/partials/settings.html +++ b/public/app/features/dashboard/partials/settings.html @@ -56,19 +56,19 @@
Title -
+
- - - +
diff --git a/public/app/features/plugins/partials/ds_edit.html b/public/app/features/plugins/partials/ds_edit.html index 1866fad50a0..6b8ae631a00 100644 --- a/public/app/features/plugins/partials/ds_edit.html +++ b/public/app/features/plugins/partials/ds_edit.html @@ -27,58 +27,59 @@
-
- Name - - - The name is used when you select the data source in panels. - The Default data source is preselected in new - panels. - +
+
+ Name + + + The name is used when you select the data source in panels. + The Default data source is preselected in new + panels. + +
+ +
- -
+
+ Type +
+ +
+
+
-
- Type -
- -
-
-
+ + + + - - - - +
+
Testing....
+
Test results
+
+
{{ctrl.testing.title}}
+
+
+
-
-
Testing....
-
Test results
-
-
{{ctrl.testing.title}}
-
-
-
- -
- - - +
+ + + - Cancel -
+ + Cancel +
- -
+ +
-
- -
+
+ +
diff --git a/public/sass/_variables.dark.scss b/public/sass/_variables.dark.scss index 337184b9824..18b2931373d 100644 --- a/public/sass/_variables.dark.scss +++ b/public/sass/_variables.dark.scss @@ -48,14 +48,17 @@ $critical: #ed2e18; // Scaffolding // ------------------------- -$body-bg: rgb(20,20,20); -$page-bg: $dark-2; -$body-color: $gray-4; -$text-color: $gray-4; -$text-color-strong: $white; -$text-color-weak: $gray-2; +$body-bg: rgb(20,20,20); +$page-bg: $dark-2; +$body-color: $gray-4; +$text-color: $gray-4; +$text-color-strong: $white; +$text-color-weak: $gray-2; +$text-color-faint: $gray-1; $text-color-emphasis: $gray-5; +$text-shadow-strong: 1px 1px 4px $black; +$text-shadow-faint: 1px 1px 4px rgb(45, 45, 45); // gradients $brand-gradient: linear-gradient(to right, rgba(255,213,0,0.7) 0%, rgba(255,68,0,0.7) 99%, rgba(255,68,0,0.7) 100%); diff --git a/public/sass/_variables.light.scss b/public/sass/_variables.light.scss index 9071472b9b3..8fef6ae72eb 100644 --- a/public/sass/_variables.light.scss +++ b/public/sass/_variables.light.scss @@ -60,8 +60,12 @@ $body-color: $gray-1; $text-color: $gray-1; $text-color-strong: $white; $text-color-weak: $gray-1; +$text-color-faint: $gray-3; $text-color-emphasis: $dark-5; +$text-shadow-strong: none; +$text-shadow-faint: none; + // gradients $brand-gradient: linear-gradient(to right, rgba(255,213,0,1.0) 0%, rgba(255,68,0,1.0) 99%, rgba(255,68,0,1.0) 100%); $page-gradient: linear-gradient(60deg, transparent 70%, darken($page-bg, 4%) 98%); diff --git a/public/sass/components/_gf-form.scss b/public/sass/components/_gf-form.scss index eaf17c6be80..083ef594f6d 100644 --- a/public/sass/components/_gf-form.scss +++ b/public/sass/components/_gf-form.scss @@ -141,18 +141,10 @@ $gf-form-margin: 0.25rem; } } -<<<<<<< HEAD -||||||| merged common ancestors -.gf-form-select-wrapper + .gf-form-select-wrapper { - margin-left: $gf-form-label-margin; -} - -======= .gf-form--v-stretch { align-items: stretch; } ->>>>>>> master .gf-form-btn { margin-right: $gf-form-margin; padding: $input-padding-y $input-padding-x; @@ -160,15 +152,11 @@ $gf-form-margin: 0.25rem; flex-shrink: 0; flex-grow: 0; } -<<<<<<< HEAD .gf-form-switch { margin-right: $gf-form-margin; } -||||||| merged common ancestors -======= - .natural-language-input { &input[type="number"] { font-size: $font-size-base; @@ -178,4 +166,3 @@ $gf-form-margin: 0.25rem; } } ->>>>>>> master diff --git a/public/sass/components/_switch.scss b/public/sass/components/_switch.scss index fd4a77ca3af..1f81bc2597e 100644 --- a/public/sass/components/_switch.scss +++ b/public/sass/components/_switch.scss @@ -50,40 +50,33 @@ $switch-height: 1.5rem; input + label:before { @include buttonBackground($input-bg, lighten($input-bg, 5%)); color: $text-color; - text-shadow: 1px 1px 4px rgb(45, 45, 45); + text-shadow: $text-shadow-faint; } input + label:after { @include buttonBackground($input-bg, lighten($input-bg, 5%)); - color: lighten(#FF8600, 10%); - text-shadow: 1px 1px 4px rgb(25, 25, 25); + color: lighten($orange, 10%); + text-shadow: $text-shadow-strong; } } input + label:before { - //content: attr(data-off); font-family: 'FontAwesome'; - //content: "\f00c"; - content: "\f096"; // square-o - //content: "\f046"; // check-square-o - color: darken($text-color-weak, 10%); - transition: transform 0.4s; + color: $text-color-faint; + //transition: transform 0.4s; backface-visibility: hidden; - text-shadow: 1px 1px 4px rgb(45, 45, 45); + text-shadow: $text-shadow-faint; } input + label:after { - //@include buttonBackground($btn-secondary-bg, $btn-secondary-bg-hl); - //content: attr(data-on); - //content: "\f00c"; content: "\f046"; // check-square-o - color: #FF8600; - text-shadow: 1px 1px 4px rgb(25, 25, 25); + color: $orange; + text-shadow: $text-shadow-strong; font-family: 'FontAwesome'; - transition: transform 0.4s; + //transition: transform 0.4s; transform: rotateY(180deg); backface-visibility: hidden; } From 70b66382ebabce0a39da70516ea48f22e496ad60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 28 Mar 2016 17:08:31 +0200 Subject: [PATCH 12/28] tech(): updated angularjs --- bower.json | 8 +- public/app/core/components/switch.ts | 9 +- public/sass/components/_switch.scss | 4 +- public/vendor/angular-mocks/.bower.json | 12 +- public/vendor/angular-mocks/angular-mocks.js | 286 +++++-- public/vendor/angular-mocks/bower.json | 4 +- public/vendor/angular-mocks/package.json | 2 +- public/vendor/angular-route/.bower.json | 12 +- public/vendor/angular-route/angular-route.js | 14 +- .../vendor/angular-route/angular-route.min.js | 16 +- .../angular-route/angular-route.min.js.map | 4 +- public/vendor/angular-route/bower.json | 4 +- public/vendor/angular-route/package.json | 2 +- public/vendor/angular-sanitize/.bower.json | 12 +- .../angular-sanitize/angular-sanitize.js | 2 +- .../angular-sanitize/angular-sanitize.min.js | 2 +- public/vendor/angular-sanitize/bower.json | 4 +- public/vendor/angular-sanitize/package.json | 2 +- public/vendor/angular/.bower.json | 10 +- public/vendor/angular/angular.js | 733 ++++++++++++------ public/vendor/angular/angular.min.js | 596 +++++++------- public/vendor/angular/angular.min.js.gzip | Bin 54457 -> 54974 bytes public/vendor/angular/angular.min.js.map | 6 +- public/vendor/angular/bower.json | 2 +- public/vendor/angular/package.json | 2 +- 25 files changed, 1073 insertions(+), 675 deletions(-) diff --git a/bower.json b/bower.json index 9e0b307c80c..557ee9c9f8f 100644 --- a/bower.json +++ b/bower.json @@ -14,10 +14,10 @@ ], "dependencies": { "jquery": "~2.1.4", - "angular": "~1.5.1", - "angular-route": "~1.5.1", - "angular-mocks": "~1.5.1", - "angular-sanitize": "~1.5.1", + "angular": "~1.5.3", + "angular-route": "~1.5.3", + "angular-mocks": "~1.5.3", + "angular-sanitize": "~1.5.3", "angular-bindonce": "~0.3.3" } } diff --git a/public/app/core/components/switch.ts b/public/app/core/components/switch.ts index dea9c0611cb..718837c7600 100644 --- a/public/app/core/components/switch.ts +++ b/public/app/core/components/switch.ts @@ -7,7 +7,7 @@ import coreModule from 'app/core/core_module'; var template = ` -
+
@@ -16,9 +16,12 @@ var template = ` export class SwitchCtrl { onChange: any; checked: any; + show: any; - constructor() { - console.log('property: ' + this.checked, this); + constructor($element) { + // hack to workaround animation + // happening on first show + this.show = true; } internalOnChange() { diff --git a/public/sass/components/_switch.scss b/public/sass/components/_switch.scss index 1f81bc2597e..4216029bab2 100644 --- a/public/sass/components/_switch.scss +++ b/public/sass/components/_switch.scss @@ -65,7 +65,7 @@ $switch-height: 1.5rem; font-family: 'FontAwesome'; content: "\f096"; // square-o color: $text-color-faint; - //transition: transform 0.4s; + transition: transform 0.4s; backface-visibility: hidden; text-shadow: $text-shadow-faint; } @@ -76,7 +76,7 @@ $switch-height: 1.5rem; text-shadow: $text-shadow-strong; font-family: 'FontAwesome'; - //transition: transform 0.4s; + transition: transform 0.4s; transform: rotateY(180deg); backface-visibility: hidden; } diff --git a/public/vendor/angular-mocks/.bower.json b/public/vendor/angular-mocks/.bower.json index 9831478983e..03fc650628a 100644 --- a/public/vendor/angular-mocks/.bower.json +++ b/public/vendor/angular-mocks/.bower.json @@ -1,20 +1,20 @@ { "name": "angular-mocks", - "version": "1.5.1-build.4601+sha.c966876", + "version": "1.5.3", "license": "MIT", "main": "./angular-mocks.js", "ignore": [], "dependencies": { - "angular": "1.5.1-build.4601+sha.c966876" + "angular": "1.5.3" }, "homepage": "https://github.com/angular/bower-angular-mocks", - "_release": "1.5.1-build.4601+sha.c966876", + "_release": "1.5.3", "_resolution": { "type": "version", - "tag": "v1.5.1-build.4601+sha.c966876", - "commit": "ff7c5c2ac686293829786d26d844391e45c37c11" + "tag": "v1.5.3", + "commit": "319557fe710cecc11e12c772cc1abb8098d29ccb" }, "_source": "git://github.com/angular/bower-angular-mocks.git", - "_target": "~1.5.1", + "_target": "~1.5.3", "_originalSource": "angular-mocks" } \ No newline at end of file diff --git a/public/vendor/angular-mocks/angular-mocks.js b/public/vendor/angular-mocks/angular-mocks.js index ff28e1a7892..a1fc2fcf7ae 100644 --- a/public/vendor/angular-mocks/angular-mocks.js +++ b/public/vendor/angular-mocks/angular-mocks.js @@ -1,5 +1,5 @@ /** - * @license AngularJS v1.5.1-build.4601+sha.c966876 + * @license AngularJS v1.5.3 * (c) 2010-2016 Google, Inc. http://angularjs.org * License: MIT */ @@ -134,12 +134,12 @@ angular.mock.$Browser = function() { }; angular.mock.$Browser.prototype = { -/** - * @name $browser#poll - * - * @description - * run all fns in pollFns - */ + /** + * @name $browser#poll + * + * @description + * run all fns in pollFns + */ poll: function poll() { angular.forEach(this.pollFns, function(pollFn) { pollFn(); @@ -552,7 +552,7 @@ angular.mock.$IntervalProvider = function() { * This directive should go inside the anonymous function but a bug in JSHint means that it would * not be enacted early enough to prevent the warning. */ -var R_ISO8061_STR = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?:\:?(\d\d)(?:\:?(\d\d)(?:\.(\d{3}))?)?)?(Z|([+-])(\d\d):?(\d\d)))?$/; +var R_ISO8061_STR = /^(-?\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?:\:?(\d\d)(?:\:?(\d\d)(?:\.(\d{3}))?)?)?(Z|([+-])(\d\d):?(\d\d)))?$/; function jsonStringToDate(string) { var match; @@ -578,7 +578,7 @@ function toInt(str) { return parseInt(str, 10); } -function padNumber(num, digits, trim) { +function padNumberInMock(num, digits, trim) { var neg = ''; if (num < 0) { neg = '-'; @@ -727,13 +727,13 @@ angular.mock.TzDate = function(offset, timestamp) { // provide this method only on browsers that already have it if (self.toISOString) { self.toISOString = function() { - return padNumber(self.origDate.getUTCFullYear(), 4) + '-' + - padNumber(self.origDate.getUTCMonth() + 1, 2) + '-' + - padNumber(self.origDate.getUTCDate(), 2) + 'T' + - padNumber(self.origDate.getUTCHours(), 2) + ':' + - padNumber(self.origDate.getUTCMinutes(), 2) + ':' + - padNumber(self.origDate.getUTCSeconds(), 2) + '.' + - padNumber(self.origDate.getUTCMilliseconds(), 3) + 'Z'; + return padNumberInMock(self.origDate.getUTCFullYear(), 4) + '-' + + padNumberInMock(self.origDate.getUTCMonth() + 1, 2) + '-' + + padNumberInMock(self.origDate.getUTCDate(), 2) + 'T' + + padNumberInMock(self.origDate.getUTCHours(), 2) + ':' + + padNumberInMock(self.origDate.getUTCMinutes(), 2) + ':' + + padNumberInMock(self.origDate.getUTCSeconds(), 2) + '.' + + padNumberInMock(self.origDate.getUTCMilliseconds(), 3) + 'Z'; }; } @@ -1328,7 +1328,8 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) { } // TODO(vojta): change params to: method, url, data, headers, callback - function $httpBackend(method, url, data, callback, headers, timeout, withCredentials) { + function $httpBackend(method, url, data, callback, headers, timeout, withCredentials, responseType) { + var xhr = new MockXhr(), expectation = expectations[0], wasExpected = false; @@ -1392,7 +1393,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) { // if $browser specified, we do auto flush all requests ($browser ? $browser.defer : responsesPush)(wrapResponse(definition)); } else if (definition.passThrough) { - $delegate(method, url, data, callback, headers, timeout, withCredentials); + $delegate(method, url, data, callback, headers, timeout, withCredentials, responseType); } else throw new Error('No response defined !'); return; } @@ -2095,10 +2096,12 @@ angular.mock.$RAFDecorator = ['$delegate', function($delegate) { /** * */ +var originalRootElement; angular.mock.$RootElementProvider = function() { - this.$get = function() { - return angular.element('
'); - }; + this.$get = ['$injector', function($injector) { + originalRootElement = angular.element('
').data('$injector', $injector); + return originalRootElement; + }]; }; /** @@ -2127,7 +2130,7 @@ angular.mock.$RootElementProvider = function() { * * myMod.controller('MyDirectiveController', ['$log', function($log) { * $log.info(this.name); - * })]; + * }]); * * * // In a test ... @@ -2137,7 +2140,7 @@ angular.mock.$RootElementProvider = function() { * var ctrl = $controller('MyDirectiveController', { /* no locals */ }, { name: 'Clark Kent' }); * expect(ctrl.name).toEqual('Clark Kent'); * expect($log.info.logs).toEqual(['Clark Kent']); - * }); + * })); * }); * * ``` @@ -2565,11 +2568,16 @@ angular.mock.$RootScopeDecorator = ['$delegate', function($delegate) { }]; -if (window.jasmine || window.mocha) { +!(function(jasmineOrMocha) { + + if (!jasmineOrMocha) { + return; + } var currentSpec = null, + injectorState = new InjectorState(), annotatedFunctions = [], - isSpecRunning = function() { + wasInjectorCreated = function() { return !!currentSpec; }; @@ -2581,48 +2589,6 @@ if (window.jasmine || window.mocha) { return angular.mock.$$annotate.apply(this, arguments); }; - - (window.beforeEach || window.setup)(function() { - annotatedFunctions = []; - currentSpec = this; - }); - - (window.afterEach || window.teardown)(function() { - var injector = currentSpec.$injector; - - annotatedFunctions.forEach(function(fn) { - delete fn.$inject; - }); - - angular.forEach(currentSpec.$modules, function(module) { - if (module && module.$$hashKey) { - module.$$hashKey = undefined; - } - }); - - currentSpec.$injector = null; - currentSpec.$modules = null; - currentSpec.$providerInjector = null; - currentSpec = null; - - if (injector) { - injector.get('$rootElement').off(); - injector.get('$rootScope').$destroy(); - } - - // clean up jquery's fragment cache - angular.forEach(angular.element.fragments, function(val, key) { - delete angular.element.fragments[key]; - }); - - MockXhr.$$lastInstance = null; - - angular.forEach(angular.callbacks, function(val, key) { - delete angular.callbacks[key]; - }); - angular.callbacks.counter = 0; - }); - /** * @ngdoc function * @name angular.mock.module @@ -2643,9 +2609,9 @@ if (window.jasmine || window.mocha) { * {@link auto.$provide $provide}.value, the key being the string name (or token) to associate * with the value on the injector. */ - window.module = angular.mock.module = function() { + var module = window.module = angular.mock.module = function() { var moduleFns = Array.prototype.slice.call(arguments, 0); - return isSpecRunning() ? workFn() : workFn; + return wasInjectorCreated() ? workFn() : workFn; ///////////////////// function workFn() { if (currentSpec.$injector) { @@ -2654,11 +2620,11 @@ if (window.jasmine || window.mocha) { var fn, modules = currentSpec.$modules || (currentSpec.$modules = []); angular.forEach(moduleFns, function(module) { if (angular.isObject(module) && !angular.isArray(module)) { - fn = function($provide) { + fn = ['$provide', function($provide) { angular.forEach(module, function(value, key) { $provide.value(key, value); }); - }; + }]; } else { fn = module; } @@ -2672,6 +2638,165 @@ if (window.jasmine || window.mocha) { } }; + module.$$beforeAllHook = (window.before || window.beforeAll); + module.$$afterAllHook = (window.after || window.afterAll); + + // purely for testing ngMock itself + module.$$currentSpec = function(to) { + if (arguments.length === 0) return to; + currentSpec = to; + }; + + /** + * @ngdoc function + * @name angular.mock.module.sharedInjector + * @description + * + * *NOTE*: This function is declared ONLY WHEN running tests with jasmine or mocha + * + * This function ensures a single injector will be used for all tests in a given describe context. + * This contrasts with the default behaviour where a new injector is created per test case. + * + * Use sharedInjector when you want to take advantage of Jasmine's `beforeAll()`, or mocha's + * `before()` methods. Call `module.sharedInjector()` before you setup any other hooks that + * will create (i.e call `module()`) or use (i.e call `inject()`) the injector. + * + * You cannot call `sharedInjector()` from within a context already using `sharedInjector()`. + * + * ## Example + * + * Typically beforeAll is used to make many assertions about a single operation. This can + * cut down test run-time as the test setup doesn't need to be re-run, and enabling focussed + * tests each with a single assertion. + * + * ```js + * describe("Deep Thought", function() { + * + * module.sharedInjector(); + * + * beforeAll(module("UltimateQuestion")); + * + * beforeAll(inject(function(DeepThought) { + * expect(DeepThought.answer).toBeUndefined(); + * DeepThought.generateAnswer(); + * })); + * + * it("has calculated the answer correctly", inject(function(DeepThought) { + * // Because of sharedInjector, we have access to the instance of the DeepThought service + * // that was provided to the beforeAll() hook. Therefore we can test the generated answer + * expect(DeepThought.answer).toBe(42); + * })); + * + * it("has calculated the answer within the expected time", inject(function(DeepThought) { + * expect(DeepThought.runTimeMillennia).toBeLessThan(8000); + * })); + * + * it("has double checked the answer", inject(function(DeepThought) { + * expect(DeepThought.absolutelySureItIsTheRightAnswer).toBe(true); + * })); + * + * }); + * + * ``` + */ + module.sharedInjector = function() { + if (!(module.$$beforeAllHook && module.$$afterAllHook)) { + throw Error("sharedInjector() cannot be used unless your test runner defines beforeAll/afterAll"); + } + + var initialized = false; + + module.$$beforeAllHook(function() { + if (injectorState.shared) { + injectorState.sharedError = Error("sharedInjector() cannot be called inside a context that has already called sharedInjector()"); + throw injectorState.sharedError; + } + initialized = true; + currentSpec = this; + injectorState.shared = true; + }); + + module.$$afterAllHook(function() { + if (initialized) { + injectorState = new InjectorState(); + module.$$cleanup(); + } else { + injectorState.sharedError = null; + } + }); + }; + + module.$$beforeEach = function() { + if (injectorState.shared && currentSpec && currentSpec != this) { + var state = currentSpec; + currentSpec = this; + angular.forEach(["$injector","$modules","$providerInjector", "$injectorStrict"], function(k) { + currentSpec[k] = state[k]; + state[k] = null; + }); + } else { + currentSpec = this; + originalRootElement = null; + annotatedFunctions = []; + } + }; + + module.$$afterEach = function() { + if (injectorState.cleanupAfterEach()) { + module.$$cleanup(); + } + }; + + module.$$cleanup = function() { + var injector = currentSpec.$injector; + + annotatedFunctions.forEach(function(fn) { + delete fn.$inject; + }); + + angular.forEach(currentSpec.$modules, function(module) { + if (module && module.$$hashKey) { + module.$$hashKey = undefined; + } + }); + + currentSpec.$injector = null; + currentSpec.$modules = null; + currentSpec.$providerInjector = null; + currentSpec = null; + + if (injector) { + // Ensure `$rootElement` is instantiated, before checking `originalRootElement` + var $rootElement = injector.get('$rootElement'); + var rootNode = $rootElement && $rootElement[0]; + var cleanUpNodes = !originalRootElement ? [] : [originalRootElement[0]]; + if (rootNode && (!originalRootElement || rootNode !== originalRootElement[0])) { + cleanUpNodes.push(rootNode); + } + angular.element.cleanData(cleanUpNodes); + + // Ensure `$destroy()` is available, before calling it + // (a mocked `$rootScope` might not implement it (or not even be an object at all)) + var $rootScope = injector.get('$rootScope'); + if ($rootScope && $rootScope.$destroy) $rootScope.$destroy(); + } + + // clean up jquery's fragment cache + angular.forEach(angular.element.fragments, function(val, key) { + delete angular.element.fragments[key]; + }); + + MockXhr.$$lastInstance = null; + + angular.forEach(angular.callbacks, function(val, key) { + delete angular.callbacks[key]; + }); + angular.callbacks.counter = 0; + }; + + (window.beforeEach || window.setup)(module.$$beforeEach); + (window.afterEach || window.teardown)(module.$$afterEach); + /** * @ngdoc function * @name angular.mock.inject @@ -2774,14 +2899,14 @@ if (window.jasmine || window.mocha) { window.inject = angular.mock.inject = function() { var blockFns = Array.prototype.slice.call(arguments, 0); var errorForStack = new Error('Declaration Location'); - return isSpecRunning() ? workFn.call(currentSpec) : workFn; + return wasInjectorCreated() ? workFn.call(currentSpec) : workFn; ///////////////////// function workFn() { var modules = currentSpec.$modules || []; var strictDi = !!currentSpec.$injectorStrict; - modules.unshift(function($injector) { + modules.unshift(['$injector', function($injector) { currentSpec.$providerInjector = $injector; - }); + }]); modules.unshift('ngMock'); modules.unshift('ng'); var injector = currentSpec.$injector; @@ -2822,7 +2947,7 @@ if (window.jasmine || window.mocha) { angular.mock.inject.strictDi = function(value) { value = arguments.length ? !!value : true; - return isSpecRunning() ? workFn() : workFn; + return wasInjectorCreated() ? workFn() : workFn; function workFn() { if (value !== currentSpec.$injectorStrict) { @@ -2834,7 +2959,16 @@ if (window.jasmine || window.mocha) { } } }; -} + + function InjectorState() { + this.shared = false; + this.sharedError = null; + + this.cleanupAfterEach = function() { + return !this.shared || this.sharedError; + }; + } +})(window.jasmine || window.mocha); })(window, window.angular); diff --git a/public/vendor/angular-mocks/bower.json b/public/vendor/angular-mocks/bower.json index ac8b75413db..4ce65bbc809 100644 --- a/public/vendor/angular-mocks/bower.json +++ b/public/vendor/angular-mocks/bower.json @@ -1,10 +1,10 @@ { "name": "angular-mocks", - "version": "1.5.1-build.4601+sha.c966876", + "version": "1.5.3", "license": "MIT", "main": "./angular-mocks.js", "ignore": [], "dependencies": { - "angular": "1.5.1-build.4601+sha.c966876" + "angular": "1.5.3" } } diff --git a/public/vendor/angular-mocks/package.json b/public/vendor/angular-mocks/package.json index eda7287688f..42d78038650 100644 --- a/public/vendor/angular-mocks/package.json +++ b/public/vendor/angular-mocks/package.json @@ -1,6 +1,6 @@ { "name": "angular-mocks", - "version": "1.5.1-build.4601+sha.c966876", + "version": "1.5.3", "description": "AngularJS mocks for testing", "main": "angular-mocks.js", "scripts": { diff --git a/public/vendor/angular-route/.bower.json b/public/vendor/angular-route/.bower.json index 43ecb04633b..0abe0215778 100644 --- a/public/vendor/angular-route/.bower.json +++ b/public/vendor/angular-route/.bower.json @@ -1,20 +1,20 @@ { "name": "angular-route", - "version": "1.5.1-build.4601+sha.c966876", + "version": "1.5.3", "license": "MIT", "main": "./angular-route.js", "ignore": [], "dependencies": { - "angular": "1.5.1-build.4601+sha.c966876" + "angular": "1.5.3" }, "homepage": "https://github.com/angular/bower-angular-route", - "_release": "1.5.1-build.4601+sha.c966876", + "_release": "1.5.3", "_resolution": { "type": "version", - "tag": "v1.5.1-build.4601+sha.c966876", - "commit": "967fdabf084ac9f37c6b984d8893ebfebde5fc02" + "tag": "v1.5.3", + "commit": "750e4833612071d30993c8e4a547a6982eba3b84" }, "_source": "git://github.com/angular/bower-angular-route.git", - "_target": "~1.5.1", + "_target": "~1.5.3", "_originalSource": "angular-route" } \ No newline at end of file diff --git a/public/vendor/angular-route/angular-route.js b/public/vendor/angular-route/angular-route.js index cde0787fecf..3c9a4e8595e 100644 --- a/public/vendor/angular-route/angular-route.js +++ b/public/vendor/angular-route/angular-route.js @@ -1,5 +1,5 @@ /** - * @license AngularJS v1.5.1-build.4601+sha.c966876 + * @license AngularJS v1.5.3 * (c) 2010-2016 Google, Inc. http://angularjs.org * License: MIT */ @@ -22,7 +22,11 @@ */ /* global -ngRouteModule */ var ngRouteModule = angular.module('ngRoute', ['ng']). - provider('$route', $RouteProvider), + provider('$route', $RouteProvider). + // Ensure `$route` will be instantiated in time to capture the initial + // `$locationChangeSuccess` event. This is necessary in case `ngView` is + // included in an asynchronously loaded template. + run(['$route', angular.noop]), $routeMinErr = angular.$$minErr('ngRoute'); /** @@ -218,9 +222,9 @@ function $RouteProvider() { path = path .replace(/([().])/g, '\\$1') - .replace(/(\/)?:(\w+)([\?\*])?/g, function(_, slash, key, option) { - var optional = option === '?' ? option : null; - var star = option === '*' ? option : null; + .replace(/(\/)?:(\w+)(\*\?|[\?\*])?/g, function(_, slash, key, option) { + var optional = (option === '?' || option === '*?') ? '?' : null; + var star = (option === '*' || option === '*?') ? '*' : null; keys.push({ name: key, optional: !!optional }); slash = slash || ''; return '' diff --git a/public/vendor/angular-route/angular-route.min.js b/public/vendor/angular-route/angular-route.min.js index d4888631eca..5d2e84f9498 100644 --- a/public/vendor/angular-route/angular-route.min.js +++ b/public/vendor/angular-route/angular-route.min.js @@ -1,15 +1,15 @@ /* - AngularJS v1.5.1-build.4601+sha.c966876 + AngularJS v1.5.3 (c) 2010-2016 Google, Inc. http://angularjs.org License: MIT */ (function(r,d,C){'use strict';function x(s,h,g){return{restrict:"ECA",terminal:!0,priority:400,transclude:"element",link:function(a,c,b,f,y){function k(){n&&(g.cancel(n),n=null);l&&(l.$destroy(),l=null);m&&(n=g.leave(m),n.then(function(){n=null}),m=null)}function z(){var b=s.current&&s.current.locals;if(d.isDefined(b&&b.$template)){var b=a.$new(),f=s.current;m=y(b,function(b){g.enter(b,null,m||c).then(function(){!d.isDefined(u)||u&&!a.$eval(u)||h()});k()});l=f.scope=b;l.$emit("$viewContentLoaded"); l.$eval(v)}else k()}var l,m,n,u=b.autoscroll,v=b.onload||"";a.$on("$routeChangeSuccess",z);z()}}}function A(d,h,g){return{restrict:"ECA",priority:-400,link:function(a,c){var b=g.current,f=b.locals;c.html(f.$template);var y=d(c.contents());if(b.controller){f.$scope=a;var k=h(b.controller,f);b.controllerAs&&(a[b.controllerAs]=k);c.data("$ngControllerController",k);c.children().data("$ngControllerController",k)}a[b.resolveAs||"$resolve"]=f;y(a)}}}r=d.module("ngRoute",["ng"]).provider("$route",function(){function s(a, -c){return d.extend(Object.create(a),c)}function h(a,d){var b=d.caseInsensitiveMatch,f={originalPath:a,regexp:a},g=f.keys=[];a=a.replace(/([().])/g,"\\$1").replace(/(\/)?:(\w+)([\?\*])?/g,function(a,d,b,c){a="?"===c?c:null;c="*"===c?c:null;g.push({name:b,optional:!!a});d=d||"";return""+(a?"":d)+"(?:"+(a?d:"")+(c&&"(.+?)"||"([^/]+)")+(a||"")+")"+(a||"")}).replace(/([\/$\*])/g,"\\$1");f.regexp=new RegExp("^"+a+"$",b?"i":"");return f}var g={};this.when=function(a,c){var b=d.copy(c);d.isUndefined(b.reloadOnSearch)&& -(b.reloadOnSearch=!0);d.isUndefined(b.caseInsensitiveMatch)&&(b.caseInsensitiveMatch=this.caseInsensitiveMatch);g[a]=d.extend(b,a&&h(a,b));if(a){var f="/"==a[a.length-1]?a.substr(0,a.length-1):a+"/";g[f]=d.extend({redirectTo:a},h(f,b))}return this};this.caseInsensitiveMatch=!1;this.otherwise=function(a){"string"===typeof a&&(a={redirectTo:a});this.when(null,a);return this};this.$get=["$rootScope","$location","$routeParams","$q","$injector","$templateRequest","$sce",function(a,c,b,f,h,k,r){function l(b){var e= -t.current;(x=(p=n())&&e&&p.$$route===e.$$route&&d.equals(p.pathParams,e.pathParams)&&!p.reloadOnSearch&&!v)||!e&&!p||a.$broadcast("$routeChangeStart",p,e).defaultPrevented&&b&&b.preventDefault()}function m(){var w=t.current,e=p;if(x)w.params=e.params,d.copy(w.params,b),a.$broadcast("$routeUpdate",w);else if(e||w)v=!1,(t.current=e)&&e.redirectTo&&(d.isString(e.redirectTo)?c.path(u(e.redirectTo,e.params)).search(e.params).replace():c.url(e.redirectTo(e.pathParams,c.path(),c.search())).replace()),f.when(e).then(function(){if(e){var a= -d.extend({},e.resolve),b,c;d.forEach(a,function(b,e){a[e]=d.isString(b)?h.get(b):h.invoke(b,null,null,e)});d.isDefined(b=e.template)?d.isFunction(b)&&(b=b(e.params)):d.isDefined(c=e.templateUrl)&&(d.isFunction(c)&&(c=c(e.params)),d.isDefined(c)&&(e.loadedTemplateUrl=r.valueOf(c),b=k(c)));d.isDefined(b)&&(a.$template=b);return f.all(a)}}).then(function(c){e==t.current&&(e&&(e.locals=c,d.copy(e.params,b)),a.$broadcast("$routeChangeSuccess",e,w))},function(b){e==t.current&&a.$broadcast("$routeChangeError", -e,w,b)})}function n(){var a,b;d.forEach(g,function(f,g){var q;if(q=!b){var h=c.path();q=f.keys;var l={};if(f.regexp)if(h=f.regexp.exec(h)){for(var k=1,n=h.length;k + * **Note:** Angular does not make a copy of the `data` parameter before it is passed into the `transformRequest` pipeline. + * That means changes to the properties of `data` are not local to the transform function (since Javascript passes objects by reference). + * For example, when calling `$http.get(url, $scope.myObject)`, modifications to the object's properties in a transformRequest + * function will be reflected on the scope and in any templates where the object is data-bound. + * To prevent his, transform functions should have no side-effects. + * If you need to modify properties, it is recommended to make a copy of the data, or create new object to return. + *
+ * * ### Default Transformations * * The `$httpProvider` provider and `$http` service expose `defaults.transformRequest` and @@ -10614,26 +10778,35 @@ function $HttpProvider() { * * ## Caching * - * To enable caching, set the request configuration `cache` property to `true` (to use default - * cache) or to a custom cache object (built with {@link ng.$cacheFactory `$cacheFactory`}). - * When the cache is enabled, `$http` stores the response from the server in the specified - * cache. The next time the same request is made, the response is served from the cache without - * sending a request to the server. + * {@link ng.$http `$http`} responses are not cached by default. To enable caching, you must + * set the config.cache value or the default cache value to TRUE or to a cache object (created + * with {@link ng.$cacheFactory `$cacheFactory`}). If defined, the value of config.cache takes + * precedence over the default cache value. * - * Note that even if the response is served from cache, delivery of the data is asynchronous in - * the same way that real requests are. + * In order to: + * * cache all responses - set the default cache value to TRUE or to a cache object + * * cache a specific response - set config.cache value to TRUE or to a cache object * - * If there are multiple GET requests for the same URL that should be cached using the same - * cache, but the cache is not populated yet, only one request to the server will be made and - * the remaining requests will be fulfilled using the response from the first request. + * If caching is enabled, but neither the default cache nor config.cache are set to a cache object, + * then the default `$cacheFactory($http)` object is used. * - * You can change the default cache to a new object (built with - * {@link ng.$cacheFactory `$cacheFactory`}) by updating the - * {@link ng.$http#defaults `$http.defaults.cache`} property. All requests who set - * their `cache` property to `true` will now use this cache object. + * The default cache value can be set by updating the + * {@link ng.$http#defaults `$http.defaults.cache`} property or the + * {@link $httpProvider#defaults `$httpProvider.defaults.cache`} property. + * + * When caching is enabled, {@link ng.$http `$http`} stores the response from the server using + * the relevant cache object. The next time the same request is made, the response is returned + * from the cache without sending a request to the server. + * + * Take note that: + * + * * Only GET and JSONP requests are cached. + * * The cache key is the request URL including search parameters; headers are not considered. + * * Cached responses are returned asynchronously, in the same way as responses from the server. + * * If multiple identical requests are made using the same cache, which is not yet populated, + * one request will be made to the server and remaining requests will return the same response. + * * A cache-control header on the response does not affect if or how responses are cached. * - * If you set the default cache to `false` then only requests that specify their own custom - * cache object will be cached. * * ## Interceptors * @@ -10803,7 +10976,7 @@ function $HttpProvider() { * transform function or an array of such functions. The transform function takes the http * response body, headers and status and returns its transformed (typically deserialized) version. * See {@link ng.$http#overriding-the-default-transformations-per-request - * Overriding the Default TransformationjqLiks} + * Overriding the Default Transformations} * - **paramSerializer** - `{string|function(Object):string}` - A function used to * prepare the string representation of request parameters (specified as an object). * If specified as string, it is interpreted as function registered with the @@ -10811,10 +10984,9 @@ function $HttpProvider() { * by registering it as a {@link auto.$provide#service service}. * The default serializer is the {@link $httpParamSerializer $httpParamSerializer}; * alternatively, you can use the {@link $httpParamSerializerJQLike $httpParamSerializerJQLike} - * - **cache** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the - * GET request, otherwise if a cache instance built with - * {@link ng.$cacheFactory $cacheFactory}, this cache will be used for - * caching. + * - **cache** – `{boolean|Object}` – A boolean value or object created with + * {@link ng.$cacheFactory `$cacheFactory`} to enable or disable caching of the HTTP response. + * See {@link $http#caching $http Caching} for more information. * - **timeout** – `{number|Promise}` – timeout in milliseconds, or {@link ng.$q promise} * that should abort the request when resolved. * - **withCredentials** - `{boolean}` - whether to set the `withCredentials` flag on the @@ -13725,8 +13897,10 @@ AST.prototype = { primary = this.arrayDeclaration(); } else if (this.expect('{')) { primary = this.object(); - } else if (this.constants.hasOwnProperty(this.peek().text)) { - primary = copy(this.constants[this.consume().text]); + } else if (this.selfReferential.hasOwnProperty(this.peek().text)) { + primary = copy(this.selfReferential[this.consume().text]); + } else if (this.options.literals.hasOwnProperty(this.peek().text)) { + primary = { type: AST.Literal, value: this.options.literals[this.consume().text]}; } else if (this.peek().identifier) { primary = this.identifier(); } else if (this.peek().constant) { @@ -13878,15 +14052,7 @@ AST.prototype = { return false; }, - - /* `undefined` is not a constant, it is an identifier, - * but using it as an identifier is not supported - */ - constants: { - 'true': { type: AST.Literal, value: true }, - 'false': { type: AST.Literal, value: false }, - 'null': { type: AST.Literal, value: null }, - 'undefined': {type: AST.Literal, value: undefined }, + selfReferential: { 'this': {type: AST.ThisExpression }, '$locals': {type: AST.LocalsExpression } } @@ -14576,7 +14742,7 @@ ASTInterpreter.prototype = { forEach(ast.body, function(expression) { expressions.push(self.recurse(expression.expression)); }); - var fn = ast.body.length === 0 ? function() {} : + var fn = ast.body.length === 0 ? noop : ast.body.length === 1 ? expressions[0] : function(scope, locals) { var lastValue; @@ -14717,7 +14883,7 @@ ASTInterpreter.prototype = { return context ? {value: locals} : locals; }; case AST.NGValueParameter: - return function(scope, locals, assign, inputs) { + return function(scope, locals, assign) { return context ? {value: assign} : assign; }; } @@ -14931,7 +15097,7 @@ var Parser = function(lexer, $filter, options) { this.lexer = lexer; this.$filter = $filter; this.options = options; - this.ast = new AST(this.lexer); + this.ast = new AST(lexer, options); this.astCompiler = options.csp ? new ASTInterpreter(this.ast, $filter) : new ASTCompiler(this.ast, $filter); }; @@ -15008,16 +15174,39 @@ function getValueOf(value) { function $ParseProvider() { var cacheDefault = createMap(); var cacheExpensive = createMap(); + var literals = { + 'true': true, + 'false': false, + 'null': null, + 'undefined': undefined + }; + + /** + * @ngdoc method + * @name $parseProvider#addLiteral + * @description + * + * Configure $parse service to add literal values that will be present as literal at expressions. + * + * @param {string} literalName Token for the literal value. The literal name value must be a valid literal name. + * @param {*} literalValue Value for this literal. All literal values must be primitives or `undefined`. + * + **/ + this.addLiteral = function(literalName, literalValue) { + literals[literalName] = literalValue; + }; this.$get = ['$filter', function($filter) { var noUnsafeEval = csp().noUnsafeEval; var $parseOptions = { csp: noUnsafeEval, - expensiveChecks: false + expensiveChecks: false, + literals: copy(literals) }, $parseOptionsExpensive = { csp: noUnsafeEval, - expensiveChecks: true + expensiveChecks: true, + literals: copy(literals) }; var runningChecksEnabled = false; @@ -15266,15 +15455,15 @@ function $ParseProvider() { * [Kris Kowal's Q](https://github.com/kriskowal/q). * * $q can be used in two fashions --- one which is more similar to Kris Kowal's Q or jQuery's Deferred - * implementations, and the other which resembles ES6 promises to some degree. + * implementations, and the other which resembles ES6 (ES2015) promises to some degree. * * # $q constructor * * The streamlined ES6 style promise is essentially just using $q as a constructor which takes a `resolver` - * function as the first argument. This is similar to the native Promise implementation from ES6 Harmony, + * function as the first argument. This is similar to the native Promise implementation from ES6, * see [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). * - * While the constructor-style use is supported, not all of the supporting methods from ES6 Harmony promises are + * While the constructor-style use is supported, not all of the supporting methods from ES6 promises are * available yet. * * It can be used like so: @@ -16627,7 +16816,7 @@ function $RootScopeProvider() { dirty, ttl = TTL, next, current, target = this, watchLog = [], - logIdx, logMsg, asyncTask; + logIdx, asyncTask; beginPhase('$digest'); // Check for changes to browser url that happened in sync before the call to $digest @@ -18412,6 +18601,10 @@ function $SceProvider() { function $SnifferProvider() { this.$get = ['$window', '$document', function($window, $document) { var eventSupport = {}, + // Chrome Packaged Apps are not allowed to access `history.pushState`. They can be detected by + // the presence of `chrome.app.runtime` (see https://developer.chrome.com/apps/api_index) + isChromePackagedApp = $window.chrome && $window.chrome.app && $window.chrome.app.runtime, + hasHistoryPushState = !isChromePackagedApp && $window.history && $window.history.pushState, android = toInt((/android (\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]), boxee = /Boxee/i.test(($window.navigator || {}).userAgent), @@ -18456,7 +18649,7 @@ function $SnifferProvider() { // so let's not use the history API also // We are purposefully using `!(android < 4)` to cover the case when `android` is undefined // jshint -W018 - history: !!($window.history && $window.history.pushState && !(android < 4) && !boxee), + history: !!(hasHistoryPushState && !(android < 4) && !boxee), // jshint +W018 hasEvent: function(event) { // IE9 implements 'input' event it's so fubared that we rather pretend that it doesn't have @@ -18482,7 +18675,7 @@ function $SnifferProvider() { }]; } -var $compileMinErr = minErr('$compile'); +var $templateRequestMinErr = minErr('$compile'); /** * @ngdoc provider @@ -18578,7 +18771,7 @@ function $TemplateRequestProvider() { function handleError(resp) { if (!ignoreRequestError) { - throw $compileMinErr('tpload', 'Failed to load template: {0} (HTTP status: {1} {2})', + throw $templateRequestMinErr('tpload', 'Failed to load template: {0} (HTTP status: {1} {2})', tpl, resp.status, resp.statusText); } return $q.reject(resp); @@ -19500,7 +19693,7 @@ function currencyFilter($locale) { * Formats a number as text. * * If the input is null or undefined, it will just be returned. - * If the input is infinite (Infinity/-Infinity) the Infinity symbol '∞' is returned. + * If the input is infinite (Infinity or -Infinity), the Infinity symbol '∞' or '-∞' is returned, respectively. * If the input is not a number an empty string is returned. * * @@ -19636,18 +19829,37 @@ function roundNumber(parsedNumber, fractionSize, minFrac, maxFrac) { var digit = digits[roundAt]; if (roundAt > 0) { - digits.splice(roundAt); + // Drop fractional digits beyond `roundAt` + digits.splice(Math.max(parsedNumber.i, roundAt)); + + // Set non-fractional digits beyond `roundAt` to 0 + for (var j = roundAt; j < digits.length; j++) { + digits[j] = 0; + } } else { // We rounded to zero so reset the parsedNumber + fractionLen = Math.max(0, fractionLen); parsedNumber.i = 1; - digits.length = roundAt = fractionSize + 1; - for (var i=0; i < roundAt; i++) digits[i] = 0; + digits.length = Math.max(1, roundAt = fractionSize + 1); + digits[0] = 0; + for (var i = 1; i < roundAt; i++) digits[i] = 0; } - if (digit >= 5) digits[roundAt - 1]++; + if (digit >= 5) { + if (roundAt - 1 < 0) { + for (var k = 0; k > roundAt; k--) { + digits.unshift(0); + parsedNumber.i++; + } + digits.unshift(1); + parsedNumber.i++; + } else { + digits[roundAt - 1]++; + } + } // Pad out with zeros to get the required fraction length - for (; fractionLen < fractionSize; fractionLen++) digits.push(0); + for (; fractionLen < Math.max(0, fractionSize); fractionLen++) digits.push(0); // Do any carrying, e.g. a digit was rounded up to 10 @@ -19719,7 +19931,7 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) { // format the integer digits with grouping separators var groups = []; - if (digits.length > pattern.lgSize) { + if (digits.length >= pattern.lgSize) { groups.unshift(digits.splice(-pattern.lgSize).join('')); } while (digits.length > pattern.gSize) { @@ -19746,11 +19958,15 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) { } } -function padNumber(num, digits, trim) { +function padNumber(num, digits, trim, negWrap) { var neg = ''; - if (num < 0) { - neg = '-'; - num = -num; + if (num < 0 || (negWrap && num <= 0)) { + if (negWrap) { + num = -num + 1; + } else { + num = -num; + neg = '-'; + } } num = '' + num; while (num.length < digits) num = ZERO_CHAR + num; @@ -19761,7 +19977,7 @@ function padNumber(num, digits, trim) { } -function dateGetter(name, size, offset, trim) { +function dateGetter(name, size, offset, trim, negWrap) { offset = offset || 0; return function(date) { var value = date['get' + name](); @@ -19769,14 +19985,15 @@ function dateGetter(name, size, offset, trim) { value += offset; } if (value === 0 && offset == -12) value = 12; - return padNumber(value, size, trim); + return padNumber(value, size, trim, negWrap); }; } -function dateStrGetter(name, shortForm) { +function dateStrGetter(name, shortForm, standAlone) { return function(date, formats) { var value = date['get' + name](); - var get = uppercase(shortForm ? ('SHORT' + name) : name); + var propPrefix = (standAlone ? 'STANDALONE' : '') + (shortForm ? 'SHORT' : ''); + var get = uppercase(propPrefix + name); return formats[get][value]; }; @@ -19831,13 +20048,14 @@ function longEraGetter(date, formats) { } var DATE_FORMATS = { - yyyy: dateGetter('FullYear', 4), - yy: dateGetter('FullYear', 2, 0, true), - y: dateGetter('FullYear', 1), + yyyy: dateGetter('FullYear', 4, 0, false, true), + yy: dateGetter('FullYear', 2, 0, true, true), + y: dateGetter('FullYear', 1, 0, false, true), MMMM: dateStrGetter('Month'), MMM: dateStrGetter('Month', true), MM: dateGetter('Month', 2, 1), M: dateGetter('Month', 1, 1), + LLLL: dateStrGetter('Month', false, true), dd: dateGetter('Date', 2), d: dateGetter('Date', 1), HH: dateGetter('Hours', 2), @@ -19863,7 +20081,7 @@ var DATE_FORMATS = { GGGG: longEraGetter }; -var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZEwG']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z|G+|w+))(.*)/, +var DATE_FORMATS_SPLIT = /((?:[^yMLdHhmsaZEwG']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|L+|d+|H+|h+|m+|s+|a|Z|G+|w+))(.*)/, NUMBER_STRING = /^\-?\d+$/; /** @@ -19883,6 +20101,7 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZEwG']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+| * * `'MMM'`: Month in year (Jan-Dec) * * `'MM'`: Month in year, padded (01-12) * * `'M'`: Month in year (1-12) + * * `'LLLL'`: Stand-alone month in year (January-December) * * `'dd'`: Day in month, padded (01-31) * * `'d'`: Day in month (1-31) * * `'EEEE'`: Day in Week,(Sunday-Saturday) @@ -21564,8 +21783,8 @@ var ngFormDirective = formDirectiveFactory(true); ngModelMinErr: false, */ -// Regex code is obtained from SO: https://stackoverflow.com/questions/3143070/javascript-regex-iso-datetime#answer-3143231 -var ISO_DATE_REGEXP = /\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)/; +// Regex code was initially obtained from SO prior to modification: https://stackoverflow.com/questions/3143070/javascript-regex-iso-datetime#answer-3143231 +var ISO_DATE_REGEXP = /^\d{4,}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+(?:[+-][0-2]\d:[0-5]\d|Z)$/; // See valid URLs in RFC3987 (http://tools.ietf.org/html/rfc3987) // Note: We are being more lenient, because browsers are too. // 1. Scheme @@ -21581,12 +21800,18 @@ var ISO_DATE_REGEXP = /\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0- var URL_REGEXP = /^[a-z][a-z\d.+-]*:\/*(?:[^:@]+(?::[^@]+)?@)?(?:[^\s:/?#]+|\[[a-f\d:]+\])(?::\d+)?(?:\/[^?#]*)?(?:\?[^#]*)?(?:#.*)?$/i; var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i; var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))([eE][+-]?\d+)?\s*$/; -var DATE_REGEXP = /^(\d{4})-(\d{2})-(\d{2})$/; -var DATETIMELOCAL_REGEXP = /^(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/; -var WEEK_REGEXP = /^(\d{4})-W(\d\d)$/; -var MONTH_REGEXP = /^(\d{4})-(\d\d)$/; +var DATE_REGEXP = /^(\d{4,})-(\d{2})-(\d{2})$/; +var DATETIMELOCAL_REGEXP = /^(\d{4,})-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/; +var WEEK_REGEXP = /^(\d{4,})-W(\d\d)$/; +var MONTH_REGEXP = /^(\d{4,})-(\d\d)$/; var TIME_REGEXP = /^(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/; +var PARTIAL_VALIDATION_EVENTS = 'keydown wheel mousedown'; +var PARTIAL_VALIDATION_TYPES = createMap(); +forEach('date,datetime-local,month,time,week'.split(','), function(type) { + PARTIAL_VALIDATION_TYPES[type] = true; +}); + var inputType = { /** @@ -21942,7 +22167,7 @@ var inputType = { }]);
- +
@@ -22663,7 +22888,7 @@ function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) { if (!$sniffer.android) { var composing = false; - element.on('compositionstart', function(data) { + element.on('compositionstart', function() { composing = true; }); @@ -22673,6 +22898,8 @@ function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) { }); } + var timeout; + var listener = function(ev) { if (timeout) { $browser.defer.cancel(timeout); @@ -22702,8 +22929,6 @@ function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) { if ($sniffer.hasEvent('input')) { element.on('input', listener); } else { - var timeout; - var deferListener = function(ev, input, origValue) { if (!timeout) { timeout = $browser.defer(function() { @@ -22735,6 +22960,26 @@ function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) { // or form autocomplete on newer browser, we need "change" event to catch it element.on('change', listener); + // Some native input types (date-family) have the ability to change validity without + // firing any input/change events. + // For these event types, when native validators are present and the browser supports the type, + // check for validity changes on various DOM events. + if (PARTIAL_VALIDATION_TYPES[type] && ctrl.$$hasNativeValidators && type === attr.type) { + element.on(PARTIAL_VALIDATION_EVENTS, function(ev) { + if (!timeout) { + var validity = this[VALIDITY_STATE_PROPERTY]; + var origBadInput = validity.badInput; + var origTypeMismatch = validity.typeMismatch; + timeout = $browser.defer(function() { + timeout = null; + if (validity.badInput !== origBadInput || validity.typeMismatch !== origTypeMismatch) { + listener(ev); + } + }); + } + }); + } + ctrl.$render = function() { // Workaround for Firefox validation #12102. var value = ctrl.$isEmpty(ctrl.$viewValue) ? '' : ctrl.$viewValue; @@ -25061,7 +25306,7 @@ forEach( */ -var ngIfDirective = ['$animate', function($animate) { +var ngIfDirective = ['$animate', '$compile', function($animate, $compile) { return { multiElement: true, transclude: 'element', @@ -25077,7 +25322,7 @@ var ngIfDirective = ['$animate', function($animate) { if (!childScope) { $transclude(function(clone, newScope) { childScope = newScope; - clone[clone.length++] = document.createComment(' end ngIf: ' + $attr.ngIf + ' '); + clone[clone.length++] = $compile.$$createComment('end ngIf', $attr.ngIf); // Note: We only need the first/last node of the cloned nodes. // However, we need to keep the reference to the jqlite wrapper as it might be changed later // by a directive with templateUrl when its template arrives. @@ -25876,9 +26121,9 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$ }; ngModelSet = function($scope, newValue) { if (isFunction(parsedNgModel($scope))) { - invokeModelSetter($scope, {$$$p: ctrl.$modelValue}); + invokeModelSetter($scope, {$$$p: newValue}); } else { - parsedNgModelAssign($scope, ctrl.$modelValue); + parsedNgModelAssign($scope, newValue); } }; } else if (!parsedNgModel.assign) { @@ -25903,7 +26148,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$ * the `$viewValue` are different from last time. * * Since `ng-model` does not do a deep watch, `$render()` is only invoked if the values of - * `$modelValue` and `$viewValue` are actually different from their previous value. If `$modelValue` + * `$modelValue` and `$viewValue` are actually different from their previous values. If `$modelValue` * or `$viewValue` are objects (rather than a string or number) then `$render()` will not be * invoked if you only change a property on the objects. */ @@ -26255,7 +26500,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$ setValidity(name, undefined); validatorPromises.push(promise.then(function() { setValidity(name, true); - }, function(error) { + }, function() { allValid = false; setValidity(name, false); })); @@ -26729,7 +26974,7 @@ var ngModelDirective = ['$rootScope', function($rootScope) { }); } - element.on('blur', function(ev) { + element.on('blur', function() { if (modelCtrl.$touched) return; if ($rootScope.$$phase) { @@ -27412,8 +27657,8 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) { var key = (optionValues === optionValuesKeys) ? index : optionValuesKeys[index]; var value = optionValues[key]; - var locals = getLocals(optionValues[key], key); - var selectValue = getTrackByValueFn(optionValues[key], locals); + var locals = getLocals(value, key); + var selectValue = getTrackByValueFn(value, locals); watchedArray.push(selectValue); // Only need to watch the displayFn if there is a specific label expression @@ -27538,14 +27783,20 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) { var option = options.getOptionFromViewValue(value); if (option && !option.disabled) { + // Don't update the option when it is already selected. + // For example, the browser will select the first option by default. In that case, + // most properties are set automatically - except the `selected` attribute, which we + // set always + if (selectElement[0].value !== option.selectValue) { removeUnknownOption(); removeEmptyOption(); selectElement[0].value = option.selectValue; option.element.selected = true; - option.element.setAttribute('selected', 'selected'); } + + option.element.setAttribute('selected', 'selected'); } else { if (value === null || providedEmptyOption) { removeUnknownOption(); @@ -28390,7 +28641,7 @@ var ngPluralizeDirective = ['$locale', '$interpolate', '$log', function($locale, */ -var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { +var ngRepeatDirective = ['$parse', '$animate', '$compile', function($parse, $animate, $compile) { var NG_REMOVED = '$$NG_REMOVED'; var ngRepeatMinErr = minErr('ngRepeat'); @@ -28425,7 +28676,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { $$tlb: true, compile: function ngRepeatCompile($element, $attr) { var expression = $attr.ngRepeat; - var ngRepeatEndComment = document.createComment(' end ngRepeat: ' + expression + ' '); + var ngRepeatEndComment = $compile.$$createComment('end ngRepeat', expression); var match = expression.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+track\s+by\s+([\s\S]+?))?\s*$/); @@ -29142,7 +29393,7 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) { */ -var ngSwitchDirective = ['$animate', function($animate) { +var ngSwitchDirective = ['$animate', '$compile', function($animate, $compile) { return { require: 'ngSwitch', @@ -29183,7 +29434,7 @@ var ngSwitchDirective = ['$animate', function($animate) { selectedTransclude.transclude(function(caseElement, selectedScope) { selectedScopes.push(selectedScope); var anchor = selectedTransclude.element; - caseElement[caseElement.length++] = document.createComment(' end ngSwitchWhen: '); + caseElement[caseElement.length++] = $compile.$$createComment('end ngSwitchWhen'); var block = { clone: caseElement }; selectedElements.push(block); @@ -29477,7 +29728,7 @@ function chromeHack(optionElement) { * added `
Type -
- +
+
- - + +
diff --git a/public/sass/components/_drop.scss b/public/sass/components/_drop.scss index 34c53557d45..0af497f46f2 100644 --- a/public/sass/components/_drop.scss +++ b/public/sass/components/_drop.scss @@ -15,11 +15,7 @@ $easing: cubic-bezier(0, 0, 0.265, 1.00); display: block; } - &.drop-open.drop-help.drop-out-of-bounds, - &.drop-open-transitionend.drop-help.drop-out-of-bounds { - display: none; - } -} + } .drop-element, .drop-element * { box-sizing: border-box; @@ -38,6 +34,12 @@ $easing: cubic-bezier(0, 0, 0.265, 1.00); } } +.drop-hide-out-of-bounds { + &.drop-open.drop-help.drop-out-of-bounds, + &.drop-open-transitionend.drop-help.drop-out-of-bounds { + display: none; + } +} @include drop-theme("help", $popover-help-bg, $popover-help-color); @include drop-theme("popover", $popover-bg, $popover-color); diff --git a/public/sass/components/_old_stuff.scss b/public/sass/components/_old_stuff.scss index eae5eb558ce..bb53b657862 100644 --- a/public/sass/components/_old_stuff.scss +++ b/public/sass/components/_old_stuff.scss @@ -1,9 +1,9 @@ -div.editor-row { +.editor-row { vertical-align: top; } -div.editor-row div.section { +.section { margin-right: 20px; vertical-align: top; display: inline-block; From 0c21d2c047d9483487b6c95ec9f4457b7634acb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 29 Mar 2016 11:07:55 +0200 Subject: [PATCH 22/28] fix(ux): css fix for tabbed view caused edit views in dashboard to create horizontal scrollbar --- public/sass/components/_tabbed_view.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/sass/components/_tabbed_view.scss b/public/sass/components/_tabbed_view.scss index c72dd1d4388..6c8a42a8059 100644 --- a/public/sass/components/_tabbed_view.scss +++ b/public/sass/components/_tabbed_view.scss @@ -1,7 +1,7 @@ .tabbed-view { background-color: $page-bg; background-image: $page-gradient; - margin: -($panel-margin*2); + margin: (-$panel-margin*2) (-$panel-margin); margin-bottom: $spacer*2; padding: $spacer*3; From 32c8f495ab9741af847192743692c92802a04d4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 29 Mar 2016 12:32:40 +0200 Subject: [PATCH 23/28] ux(): redesign of axis & grid forms --- .../app/core/directives/dropdown_typeahead.js | 114 ++++++++ .../app/plugins/panel/graph/axisEditor.html | 245 +++++++----------- public/sass/components/_gf-form.scss | 18 +- 3 files changed, 228 insertions(+), 149 deletions(-) diff --git a/public/app/core/directives/dropdown_typeahead.js b/public/app/core/directives/dropdown_typeahead.js index ae825c31fca..2dc5111874e 100644 --- a/public/app/core/directives/dropdown_typeahead.js +++ b/public/app/core/directives/dropdown_typeahead.js @@ -119,4 +119,118 @@ function (_, $, coreModule) { } }; }); + + coreModule.default.directive('dropdownTypeahead2', function($compile) { + + var inputTemplate = ''; + + var buttonTemplate = ''; + + return { + scope: { + menuItems: "=dropdownTypeahead2", + dropdownTypeaheadOnSelect: "&dropdownTypeaheadOnSelect", + model: '=ngModel' + }, + link: function($scope, elem, attrs) { + var $input = $(inputTemplate); + var $button = $(buttonTemplate); + $input.appendTo(elem); + $button.appendTo(elem); + + if (attrs.linkText) { + $button.html(attrs.linkText); + } + + if (attrs.ngModel) { + $scope.$watch('model', function(newValue) { + _.each($scope.menuItems, function(item) { + _.each(item.submenu, function(subItem) { + if (subItem.value === newValue) { + $button.html(subItem.text); + } + }); + }); + }); + } + + var typeaheadValues = _.reduce($scope.menuItems, function(memo, value, index) { + if (!value.submenu) { + value.click = 'menuItemSelected(' + index + ')'; + memo.push(value.text); + } else { + _.each(value.submenu, function(item, subIndex) { + item.click = 'menuItemSelected(' + index + ',' + subIndex + ')'; + memo.push(value.text + ' ' + item.text); + }); + } + return memo; + }, []); + + $scope.menuItemSelected = function(index, subIndex) { + var menuItem = $scope.menuItems[index]; + var payload = {$item: menuItem}; + if (menuItem.submenu && subIndex !== void 0) { + payload.$subItem = menuItem.submenu[subIndex]; + } + $scope.dropdownTypeaheadOnSelect(payload); + }; + + $input.attr('data-provide', 'typeahead'); + $input.typeahead({ + source: typeaheadValues, + minLength: 1, + items: 10, + updater: function (value) { + var result = {}; + _.each($scope.menuItems, function(menuItem) { + _.each(menuItem.submenu, function(submenuItem) { + if (value === (menuItem.text + ' ' + submenuItem.text)) { + result.$subItem = submenuItem; + result.$item = menuItem; + } + }); + }); + + if (result.$item) { + $scope.$apply(function() { + $scope.dropdownTypeaheadOnSelect(result); + }); + } + + $input.trigger('blur'); + return ''; + } + }); + + $button.click(function() { + $button.hide(); + $input.show(); + $input.focus(); + }); + + $input.keyup(function() { + elem.toggleClass('open', $input.val() === ''); + }); + + $input.blur(function() { + $input.hide(); + $input.val(''); + $button.show(); + $button.focus(); + // clicking the function dropdown menu wont + // work if you remove class at once + setTimeout(function() { + elem.removeClass('open'); + }, 200); + }); + + $compile(elem.contents())($scope); + } + }; + }); }); diff --git a/public/app/plugins/panel/graph/axisEditor.html b/public/app/plugins/panel/graph/axisEditor.html index d9b7b4599e0..a0ab07e288e 100644 --- a/public/app/plugins/panel/graph/axisEditor.html +++ b/public/app/plugins/panel/graph/axisEditor.html @@ -1,157 +1,106 @@ +
+
+
Left Y
-
-
-
-
    -
  • - Left Y -
  • -
  • - Unit -
  • - -
  • - Scale type -
  • -
  • - -
  • -
  • - Label -
  • -
  • - -
  • -
-
+ +
+ +
-
-
    -
  • - -
  • -
  • - Y-Max -
  • -
  • - -
  • -
  • - Y-Min -
  • -
  • - -
  • -
-
+
+ +
+ +
-
-
    -
  • - Right Y -
  • -
  • - Unit -
  • - -
  • - Scale type -
  • -
  • - -
  • -
  • - Label -
  • -
  • - -
  • -
-
+
+
+ + +
+
+ + +
-
-
    -
  • - -
  • -
  • - Y-Max -
  • -
  • - -
  • -
  • - Y-Min -
  • -
  • - -
  • -
-
+
+ +
-
-
-
-
    -
  • - Show Axis -
  • -
  • - X-Axis  - - -
  • -
  • - Y-Axis  - - -
  • -
-
+
+
Right Y
+ +
+ +
-
-
    -
  • - Thresholds -
  • -
  • - Level 1 -
  • -
  • - -
  • -
  • - -
  • -
  • - Level 2 -
  • -
  • - +
    + +
    + +
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    +
+
+ +
+
+
    +
  • + Show Axis +
  • +
  • + X-Axis  + + +
  • +
  • + Y-Axis  + + +
  • +
+
+
+
+
    +
  • + Thresholds +
  • +
  • + Level 1 +
  • +
  • + +
  • +
  • + +
  • +
  • + Level 2 +
  • +
  • +
  • @@ -186,7 +135,7 @@
  • + ng-model="ctrl.panel.legend.sideWidth" ng-change="ctrl.render()" ng-model-onblur>
@@ -231,7 +180,7 @@
  • + ng-model="ctrl.panel.decimals" ng-change="ctrl.render()" ng-model-onblur>
  • diff --git a/public/sass/components/_gf-form.scss b/public/sass/components/_gf-form.scss index 083ef594f6d..12e1fd2f32f 100644 --- a/public/sass/components/_gf-form.scss +++ b/public/sass/components/_gf-form.scss @@ -112,7 +112,6 @@ $gf-form-margin: 0.25rem; margin-right: $gf-form-margin; position: relative; background-color: $input-bg; - margin-right: $gf-form-margin; select.gf-form-input { text-indent: .01px; @@ -166,3 +165,20 @@ $gf-form-margin: 0.25rem; } } +.gf-form-dropdown-typeahead { + margin-right: $gf-form-margin; + position: relative; + background-color: $input-bg; + padding-right: $input-padding-x; + + &:after { + position: absolute; + top: 35%; + right: $input-padding-x/2; + background-color: transparent; + color: $input-color; + font: normal normal normal $font-size-sm/1 FontAwesome; + content: '\f0d7'; + pointer-events: none; + } +} From 4871a8f43e2244aa47194c125e93f540e042e098 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 29 Mar 2016 14:54:33 +0200 Subject: [PATCH 24/28] refactor(graph): changed how graph stores panel yaxis options --- public/app/features/dashboard/dashboardSrv.js | 45 ++++- .../app/plugins/panel/graph/axisEditor.html | 171 ++++++++---------- public/app/plugins/panel/graph/graph.js | 35 ++-- public/app/plugins/panel/graph/module.ts | 40 ++-- .../plugins/panel/graph/specs/graph_specs.ts | 24 ++- public/test/specs/dashboardSrv-specs.js | 30 ++- 6 files changed, 196 insertions(+), 149 deletions(-) diff --git a/public/app/features/dashboard/dashboardSrv.js b/public/app/features/dashboard/dashboardSrv.js index fbd950e60b6..00610624867 100644 --- a/public/app/features/dashboard/dashboardSrv.js +++ b/public/app/features/dashboard/dashboardSrv.js @@ -212,7 +212,7 @@ function (angular, $, _, moment) { var i, j, k; var oldVersion = this.schemaVersion; var panelUpgrades = []; - this.schemaVersion = 11; + this.schemaVersion = 12; if (oldVersion === this.schemaVersion) { return; @@ -409,6 +409,49 @@ function (angular, $, _, moment) { }); } + if (oldVersion < 12) { + // update graph yaxes changes + panelUpgrades.push(function(panel) { + if (panel.type !== 'graph') { return; } + if (!panel.yaxes) { + panel.yaxes = [ + { + show: panel['y-axis'], + min: panel.grid.leftMin, + max: panel.grid.leftMax, + logBase: panel.grid.leftLogBase, + format: panel.y_formats[0], + label: panel.leftYAxisLabel, + }, + { + show: panel['y-axis'], + min: panel.grid.rightMin, + max: panel.grid.rightMax, + logBase: panel.grid.rightLogBase, + format: panel.y_formats[1], + label: panel.rightYAxisLabel, + } + ]; + + panel.xaxis = { + show: panel['x-axis'], + }; + + delete panel.grid.leftMin; + delete panel.grid.leftMax; + delete panel.grid.leftLogBase; + delete panel.grid.rightMin; + delete panel.grid.rightMax; + delete panel.grid.rightLogBase; + delete panel.y_formats; + delete panel.leftYAxisLabel; + delete panel.rightYAxisLabel; + delete panel['y-axis']; + delete panel['x-axis']; + } + }); + } + if (panelUpgrades.length === 0) { return; } diff --git a/public/app/plugins/panel/graph/axisEditor.html b/public/app/plugins/panel/graph/axisEditor.html index a0ab07e288e..184c762943d 100644 --- a/public/app/plugins/panel/graph/axisEditor.html +++ b/public/app/plugins/panel/graph/axisEditor.html @@ -1,116 +1,87 @@
    -
    -
    Left Y
    +
    - -
    - -
    -
    -
    - -
    - +
    Left Y
    +
    Right Y
    + + + +
    +
    + +
    -
    -
    -
    - - + +
    + +
    + +
    -
    - - + +
    +
    + + +
    +
    + + +
    +
    + +
    + +
    -
    -
    - -
    -
    Right Y
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    -
    - - -
    -
    - - -
    -
    -
    - - -
    +
    X-Axis
    +
    -
    -
    -
      -
    • - Show Axis -
    • -
    • - X-Axis  - - -
    • -
    • - Y-Axis  - - -
    • -
    -
    -
    -
    -
      -
    • - Thresholds -
    • -
    • - Level 1 -
    • -
    • - -
    • -
    • - -
    • -
    • - Level 2 -
    • -
    • - -
    • -
    • - -
    • -
    • - -
    • -
    -
    +
    +
    Thresholds
    +
    +
    + +
    +
    + +
    + +
    +
    +
    + + +
    +
    + +
    + +
    +
    + + + + + + + + + + + + + + + +
    diff --git a/public/app/plugins/panel/graph/graph.js b/public/app/plugins/panel/graph/graph.js index 0f53852cec0..0443a294eed 100755 --- a/public/app/plugins/panel/graph/graph.js +++ b/public/app/plugins/panel/graph/graph.js @@ -115,7 +115,7 @@ function (angular, $, moment, _, kbn, GraphTooltip) { for (var i = 0; i < data.length; i++) { var series = data[i]; var axis = yaxis[series.yaxis - 1]; - var formater = kbn.valueFormats[panel.y_formats[series.yaxis - 1]]; + var formater = kbn.valueFormats[panel.yaxes[series.yaxis - 1].format]; // decimal override if (_.isNumber(panel.decimals)) { @@ -132,18 +132,18 @@ function (angular, $, moment, _, kbn, GraphTooltip) { } // add left axis labels - if (panel.leftYAxisLabel) { + if (panel.yaxes[0].label) { var yaxisLabel = $("
    ") - .text(panel.leftYAxisLabel) + .text(panel.yaxes[0].label) .appendTo(elem); yaxisLabel.css("margin-top", yaxisLabel.width() / 2); } // add right axis labels - if (panel.rightYAxisLabel) { + if (panel.yaxes[1].label) { var rightLabel = $("
    ") - .text(panel.rightYAxisLabel) + .text(panel.yaxes[1].label) .appendTo(elem); rightLabel.css("margin-top", rightLabel.width() / 2); @@ -151,7 +151,7 @@ function (angular, $, moment, _, kbn, GraphTooltip) { } function processOffsetHook(plot, gridMargin) { - if (panel.leftYAxisLabel) { gridMargin.left = 20; } + if (panel.yaxis) { gridMargin.left = 20; } if (panel.rightYAxisLabel) { gridMargin.right = 20; } } @@ -217,7 +217,7 @@ function (angular, $, moment, _, kbn, GraphTooltip) { for (var i = 0; i < data.length; i++) { var series = data[i]; - series.data = series.getFlotPairs(series.nullPointMode || panel.nullPointMode, panel.y_formats); + series.data = series.getFlotPairs(series.nullPointMode || panel.nullPointMode); // if hidden remove points and disable stack if (ctrl.hiddenSeries[series.alias]) { @@ -340,11 +340,11 @@ function (angular, $, moment, _, kbn, GraphTooltip) { function configureAxisOptions(data, options) { var defaults = { position: 'left', - show: panel['y-axis'], - min: panel.grid.leftMin, + show: panel.yaxes[0].show, + min: panel.yaxes[0].min, index: 1, - logBase: panel.grid.leftLogBase || 1, - max: panel.percentage && panel.stack ? 100 : panel.grid.leftMax, + logBase: panel.yaxes[0].logBase || 1, + max: panel.percentage && panel.stack ? 100 : panel.yaxes[0].max, }; options.yaxes.push(defaults); @@ -352,18 +352,19 @@ function (angular, $, moment, _, kbn, GraphTooltip) { if (_.findWhere(data, {yaxis: 2})) { var secondY = _.clone(defaults); secondY.index = 2, - secondY.logBase = panel.grid.rightLogBase || 1, + secondY.show = panel.yaxes[1].show; + secondY.logBase = panel.yaxes[1].logBase || 1, secondY.position = 'right'; - secondY.min = panel.grid.rightMin; - secondY.max = panel.percentage && panel.stack ? 100 : panel.grid.rightMax; + secondY.min = panel.yaxes[1].min; + secondY.max = panel.percentage && panel.stack ? 100 : panel.yaxes[1].max; options.yaxes.push(secondY); applyLogScale(options.yaxes[1], data); - configureAxisMode(options.yaxes[1], panel.percentage && panel.stack ? "percent" : panel.y_formats[1]); + configureAxisMode(options.yaxes[1], panel.percentage && panel.stack ? "percent" : panel.yaxes[1].format); } applyLogScale(options.yaxes[0], data); - configureAxisMode(options.yaxes[0], panel.percentage && panel.stack ? "percent" : panel.y_formats[0]); + configureAxisMode(options.yaxes[0], panel.percentage && panel.stack ? "percent" : panel.yaxes[0].format); } function applyLogScale(axis, data) { @@ -456,7 +457,7 @@ function (angular, $, moment, _, kbn, GraphTooltip) { url += panel['x-axis'] ? '' : '&hideAxes=true'; url += panel['y-axis'] ? '' : '&hideYAxis=true'; - switch(panel.y_formats[0]) { + switch(panel.yaxes[0].format) { case 'bytes': url += '&yUnitSystem=binary'; break; diff --git a/public/app/plugins/panel/graph/module.ts b/public/app/plugins/panel/graph/module.ts index 29c2dccbac2..43fbddd9b24 100644 --- a/public/app/plugins/panel/graph/module.ts +++ b/public/app/plugins/panel/graph/module.ts @@ -17,20 +17,28 @@ var panelDefaults = { datasource: null, // sets client side (flot) or native graphite png renderer (png) renderer: 'flot', - // Show/hide the x-axis - 'x-axis' : true, - // Show/hide y-axis - 'y-axis' : true, - // y axis formats, [left axis,right axis] - y_formats : ['short', 'short'], - // grid options + yaxes: [ + { + label: null, + show: true, + logBase: 1, + min: null, + max: null, + format: 'short' + }, + { + label: null, + show: true, + logBase: 1, + min: null, + max: null, + format: 'short' + } + ], + xaxis: { + show: true + }, grid : { - leftLogBase: 1, - leftMax: null, - rightMax: null, - leftMin: null, - rightMin: null, - rightLogBase: 1, threshold1: null, threshold2: null, threshold1Color: 'rgba(216, 200, 27, 0.27)', @@ -115,8 +123,8 @@ class GraphCtrl extends MetricsPanelCtrl { } onInitEditMode() { - this.addEditorTab('Axes & Grid', 'public/app/plugins/panel/graph/axisEditor.html', 2); - this.addEditorTab('Display Styles', 'public/app/plugins/panel/graph/styleEditor.html', 3); + this.addEditorTab('Axes', 'public/app/plugins/panel/graph/axisEditor.html', 2); + this.addEditorTab('Display', 'public/app/plugins/panel/graph/styleEditor.html', 3); this.logScales = { 'linear': 1, @@ -135,7 +143,7 @@ class GraphCtrl extends MetricsPanelCtrl { } setUnitFormat(axis, subItem) { - this.panel.y_formats[axis] = subItem.value; + axis.format = subItem.value; this.render(); } diff --git a/public/app/plugins/panel/graph/specs/graph_specs.ts b/public/app/plugins/panel/graph/specs/graph_specs.ts index 28b38101004..1a708696680 100644 --- a/public/app/plugins/panel/graph/specs/graph_specs.ts +++ b/public/app/plugins/panel/graph/specs/graph_specs.ts @@ -31,7 +31,21 @@ describe('grafanaGraph', function() { panel: { legend: {}, grid: { }, - y_formats: [], + yaxes: [ + { + min: null, + max: null, + format: 'short', + logBase: 1 + }, + { + min: null, + max: null, + format: 'short', + logBase: 1 + } + ], + xaxis: {}, seriesOverrides: [], tooltip: { shared: true @@ -151,13 +165,7 @@ describe('grafanaGraph', function() { graphScenario('when logBase is log 10', function(ctx) { ctx.setup(function(ctrl) { - ctrl.panel.grid = { - leftMax: null, - rightMax: null, - leftMin: null, - rightMin: null, - leftLogBase: 10, - }; + ctrl.panel.yaxes[0].logBase = 10; }); it('should apply axis transform and ticks', function() { diff --git a/public/test/specs/dashboardSrv-specs.js b/public/test/specs/dashboardSrv-specs.js index 86f54f274fb..e02495c1236 100644 --- a/public/test/specs/dashboardSrv-specs.js +++ b/public/test/specs/dashboardSrv-specs.js @@ -122,7 +122,10 @@ define([ { panels: [ { - type: 'graphite', legend: true, aliasYAxis: { test: 2 }, grid: { min: 1, max: 10 }, + type: 'graph', legend: true, aliasYAxis: { test: 2 }, + y_formats: ['kbyte', 'ms'], + grid: {min: 1, max: 10, rightMin: 5, rightMax: 15, leftLogBase: 1, rightLogBase: 2}, + leftYAxisLabel: 'left label', targets: [{refId: 'A'}, {}], }, { @@ -172,11 +175,6 @@ define([ expect(graph.legend.show).to.be(true); }); - it('update grid options', function() { - expect(graph.grid.leftMin).to.be(1); - expect(graph.grid.leftMax).to.be(10); - }); - it('move aliasYAxis to series override', function() { expect(graph.seriesOverrides[0].alias).to.be("test"); expect(graph.seriesOverrides[0].yaxis).to.be(2); @@ -193,8 +191,24 @@ define([ expect(table.styles[1].thresholds[1]).to.be("300"); }); + it('graph grid to yaxes options', function() { + expect(graph.yaxes[0].min).to.be(1); + expect(graph.yaxes[0].max).to.be(10); + expect(graph.yaxes[0].format).to.be('kbyte'); + expect(graph.yaxes[0].label).to.be('left label'); + expect(graph.yaxes[0].logBase).to.be(1); + expect(graph.yaxes[1].min).to.be(5); + expect(graph.yaxes[1].max).to.be(15); + expect(graph.yaxes[1].format).to.be('ms'); + expect(graph.yaxes[1].logBase).to.be(2); + + expect(graph.grid.rightMax).to.be(undefined); + expect(graph.grid.rightLogBase).to.be(undefined); + expect(graph.y_formats).to.be(undefined); + }); + it('dashboard schema version should be set to latest', function() { - expect(model.schemaVersion).to.be(11); + expect(model.schemaVersion).to.be(12); }); }); @@ -248,6 +262,8 @@ define([ rows: [{ panels: [{ type: 'graph', + grid: {}, + yaxes: [{}, {}], targets: [{ "alias": "$tag_datacenter $tag_source $col", "column": "value", From d545902acc23e02a5861e4c7c54990f1affda0d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 29 Mar 2016 15:53:41 +0200 Subject: [PATCH 25/28] ux(): updated and polished legend option forms --- public/app/core/components/switch.ts | 10 +- .../app/plugins/panel/graph/axisEditor.html | 160 ------------------ public/app/plugins/panel/graph/module.ts | 5 +- public/app/plugins/panel/graph/tab_axes.html | 70 ++++++++ .../{styleEditor.html => tab_display.html} | 12 +- .../app/plugins/panel/graph/tab_legend.html | 74 ++++++++ 6 files changed, 159 insertions(+), 172 deletions(-) delete mode 100644 public/app/plugins/panel/graph/axisEditor.html create mode 100644 public/app/plugins/panel/graph/tab_axes.html rename public/app/plugins/panel/graph/{styleEditor.html => tab_display.html} (95%) create mode 100644 public/app/plugins/panel/graph/tab_legend.html diff --git a/public/app/core/components/switch.ts b/public/app/core/components/switch.ts index e0971c02f9b..1dddae20d49 100644 --- a/public/app/core/components/switch.ts +++ b/public/app/core/components/switch.ts @@ -7,10 +7,10 @@ import coreModule from 'app/core/core_module'; import Drop from 'tether-drop'; var template = ` - +
    - - + +
    `; @@ -18,10 +18,12 @@ export class SwitchCtrl { onChange: any; checked: any; show: any; + id: any; /** @ngInject */ - constructor() { + constructor($scope) { this.show = true; + this.id = $scope.$id; } internalOnChange() { diff --git a/public/app/plugins/panel/graph/axisEditor.html b/public/app/plugins/panel/graph/axisEditor.html deleted file mode 100644 index 184c762943d..00000000000 --- a/public/app/plugins/panel/graph/axisEditor.html +++ /dev/null @@ -1,160 +0,0 @@ -
    -
    - -
    Left Y
    -
    Right Y
    - - - -
    -
    - -
    -
    - -
    - -
    - -
    -
    - -
    -
    - - -
    -
    - - -
    -
    - -
    - - -
    -
    -
    - -
    -
    X-Axis
    - -
    -
    - -
    -
    Thresholds
    -
    -
    - - -
    -
    - -
    - -
    -
    -
    - - -
    -
    - -
    - -
    -
    - - - - - - - - - - - - - - - - -
    -
    - -
    -
    -
    -
      -
    • - Legend -
    • -
    • - -
    • -
    • - -
    • -
    • - -
    • -
    • - Side width -
    • -
    • - -
    • -
    -
    -
    -
    -
      -
    • - Hide series -
    • -
    • - -
    • -
    • - -
    • -
    -
    -
    - -
    -
      -
    • - Values -
    • -
    • - -
    • -
    • - -
    • -
    • - -
    • -
    • - -
    • -
    • - -
    • -
    • - Decimals -
    • -
    • - -
    • -
    -
    -
    -
    -
    diff --git a/public/app/plugins/panel/graph/module.ts b/public/app/plugins/panel/graph/module.ts index 43fbddd9b24..c99f9070af3 100644 --- a/public/app/plugins/panel/graph/module.ts +++ b/public/app/plugins/panel/graph/module.ts @@ -123,8 +123,9 @@ class GraphCtrl extends MetricsPanelCtrl { } onInitEditMode() { - this.addEditorTab('Axes', 'public/app/plugins/panel/graph/axisEditor.html', 2); - this.addEditorTab('Display', 'public/app/plugins/panel/graph/styleEditor.html', 3); + this.addEditorTab('Axes', 'public/app/plugins/panel/graph/tab_axes.html', 2); + this.addEditorTab('Legend', 'public/app/plugins/panel/graph/tab_legend.html', 3); + this.addEditorTab('Display', 'public/app/plugins/panel/graph/tab_display.html', 4); this.logScales = { 'linear': 1, diff --git a/public/app/plugins/panel/graph/tab_axes.html b/public/app/plugins/panel/graph/tab_axes.html new file mode 100644 index 00000000000..e7e35055d5c --- /dev/null +++ b/public/app/plugins/panel/graph/tab_axes.html @@ -0,0 +1,70 @@ +
    +
    + +
    Left Y
    +
    Right Y
    + + + +
    +
    + +
    +
    + +
    + +
    + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    + +
    + + +
    +
    +
    + +
    +
    X-Axis
    + +
    +
    + +
    +
    Thresholds
    +
    +
    + + +
    +
    + +
    + +
    +
    +
    + + +
    +
    + +
    + +
    +
    +
    +
    diff --git a/public/app/plugins/panel/graph/styleEditor.html b/public/app/plugins/panel/graph/tab_display.html similarity index 95% rename from public/app/plugins/panel/graph/styleEditor.html rename to public/app/plugins/panel/graph/tab_display.html index 17a9d702329..5c021dae8e1 100644 --- a/public/app/plugins/panel/graph/styleEditor.html +++ b/public/app/plugins/panel/graph/tab_display.html @@ -1,5 +1,5 @@ -
    -
    +
    +
    Draw Modes
    -
    +
    Mode Options
    @@ -39,7 +39,7 @@ checked="ctrl.panel.steppedLine" on-change="ctrl.render()">
    -
    +
    Misc options
    @@ -61,7 +61,7 @@
    -
    +
    Multiple Series
    -
    +
    Series specific overrides Regex match example: /server[0-3]/i
    diff --git a/public/app/plugins/panel/graph/tab_legend.html b/public/app/plugins/panel/graph/tab_legend.html new file mode 100644 index 00000000000..ac9e11dcaf0 --- /dev/null +++ b/public/app/plugins/panel/graph/tab_legend.html @@ -0,0 +1,74 @@ +
    +
    +
    Options
    + + + + + + + +
    + + +
    +
    + +
    +
    Values
    + +
    + + + + + +
    + +
    + + + + + +
    + +
    + + + +
    + + +
    +
    +
    + +
    +
    Hide series
    + + + + +
    +
    From 2f3627e74b261d55f7700c035220a1c1a4030096 Mon Sep 17 00:00:00 2001 From: woodsaj Date: Tue, 29 Mar 2016 22:53:02 +0800 Subject: [PATCH 26/28] add missing ngInject comment. fixes #4501 --- public/app/features/plugins/import_list/import_list.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/public/app/features/plugins/import_list/import_list.ts b/public/app/features/plugins/import_list/import_list.ts index 8eb726b81c0..6c82d3faa92 100644 --- a/public/app/features/plugins/import_list/import_list.ts +++ b/public/app/features/plugins/import_list/import_list.ts @@ -10,6 +10,7 @@ export class DashImportListCtrl { plugin: any; datasource: any; + /** @ngInject */ constructor($scope, private $http, private backendSrv, private $rootScope) { this.dashboards = []; From 2ee9376df22d6c640f4357047d377c430ae2882d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 29 Mar 2016 20:49:42 +0200 Subject: [PATCH 27/28] ux(): form tweaks --- public/app/plugins/panel/graph/tab_axes.html | 52 ++++++++++---------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/public/app/plugins/panel/graph/tab_axes.html b/public/app/plugins/panel/graph/tab_axes.html index e7e35055d5c..81ab3deeb31 100644 --- a/public/app/plugins/panel/graph/tab_axes.html +++ b/public/app/plugins/panel/graph/tab_axes.html @@ -41,30 +41,32 @@
    X-Axis
    -
    -
    -
    Thresholds
    -
    -
    - - -
    -
    - -
    - -
    -
    -
    - - -
    -
    - -
    - -
    -
    -
    +
    +
    Thresholds
    +
    +
    + + +
    +
    + +
    + +
    +
    +
    +
    +
    + + +
    +
    + +
    + +
    +
    +
    +
    From 3dbfd494144a7fb65a838219fce0e7802ffc96f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 29 Mar 2016 22:23:29 +0200 Subject: [PATCH 28/28] ux(): templating forms polish --- public/app/features/dashboard/dashboardSrv.js | 9 +++- .../features/dashboard/submenu/submenu.html | 4 +- public/app/features/templating/editorCtrl.js | 7 +++ .../features/templating/partials/editor.html | 48 +++++++++++-------- 4 files changed, 44 insertions(+), 24 deletions(-) diff --git a/public/app/features/dashboard/dashboardSrv.js b/public/app/features/dashboard/dashboardSrv.js index 00610624867..b3194868d97 100644 --- a/public/app/features/dashboard/dashboardSrv.js +++ b/public/app/features/dashboard/dashboardSrv.js @@ -401,11 +401,18 @@ function (angular, $, _, moment) { }); } - if (oldVersion < 11) { + if (oldVersion < 12) { // update template variables _.each(this.templating.list, function(templateVariable) { if (templateVariable.refresh) { templateVariable.refresh = 1; } if (!templateVariable.refresh) { templateVariable.refresh = 0; } + if (templateVariable.hideVariable) { + templateVariable.hide = 2; + } else if (templateVariable.hideLabel) { + templateVariable.hide = 1; + } else { + templateVariable.hide = 0; + } }); } diff --git a/public/app/features/dashboard/submenu/submenu.html b/public/app/features/dashboard/submenu/submenu.html index 21a9744b359..464d8c4cecf 100644 --- a/public/app/features/dashboard/submenu/submenu.html +++ b/public/app/features/dashboard/submenu/submenu.html @@ -1,7 +1,7 @@