sw2at-ui 0.0.13 → 0.0.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/VERSION +1 -1
  4. data/app/assets/javascripts/swat/app/app.coffee +8 -1
  5. data/app/assets/javascripts/swat/app/controllers/management/configuration.coffee +2 -2
  6. data/app/assets/javascripts/swat/app/controllers/management/confirmation.coffee +21 -0
  7. data/app/assets/javascripts/swat/app/controllers/management/console.coffee +33 -0
  8. data/app/assets/javascripts/swat/app/directives/components/custom-dropdown.coffee +35 -0
  9. data/app/assets/javascripts/swat/app/directives/components.coffee +1 -0
  10. data/app/assets/javascripts/swat/app/factories/configuration/confirmation_dialog.coffee +10 -0
  11. data/app/assets/javascripts/swat/app/factories/helpers.coffee +9 -2
  12. data/app/assets/javascripts/swat/app/factories/summary/fails_graph.coffee +1 -0
  13. data/app/assets/javascripts/swat/app/services/configuration.coffee +1 -0
  14. data/app/assets/javascripts/swat/app/services/console.coffee +8 -0
  15. data/app/assets/javascripts/swat/bower_components.coffee +1 -0
  16. data/app/assets/javascripts/swat/lib/highcharts-exporting.js +23 -0
  17. data/app/assets/javascripts/swat/lib/highcharts.src.js +324 -18634
  18. data/app/assets/stylesheets/swat/application.scss +29 -3
  19. data/app/assets/stylesheets/swat/boostrap_vars.scss +872 -0
  20. data/app/assets/stylesheets/swat/components/dropdown.scss +124 -0
  21. data/app/assets/stylesheets/swat/configuration.scss +3 -23
  22. data/app/assets/stylesheets/swat/confirmation.scss +60 -0
  23. data/app/assets/stylesheets/swat/console.scss +68 -0
  24. data/app/assets/stylesheets/swat/header.scss +1 -0
  25. data/app/assets/stylesheets/swat/swat_theme.scss +5 -7
  26. data/app/assets/stylesheets/swat/vars.scss +21 -11
  27. data/app/controllers/swat/api/console_controller.rb +17 -0
  28. data/app/controllers/swat/pages/components_controller.rb +6 -0
  29. data/app/models/concerns/root_revision_ext.rb +31 -0
  30. data/app/models/revision_cleaner.rb +57 -0
  31. data/app/views/swat/pages/components/custom_dropdown.slim +16 -0
  32. data/app/views/swat/pages/management/configuration.slim +3 -3
  33. data/app/views/swat/pages/management/confirmation.slim +13 -0
  34. data/app/views/swat/pages/management/console.slim +6 -0
  35. data/app/views/swat/pages/management/partials/_action_bar.slim +26 -0
  36. data/app/views/swat/pages/management/partials/_stats.slim +4 -0
  37. data/app/views/swat/shared/_nav.slim +6 -6
  38. data/config/routes.rb +14 -13
  39. data/lib/swat/engine.rb +2 -0
  40. data/lib/swat/ui/rspec_commands.rb +3 -2
  41. data/spec/models/calculator_spec.rb +1 -1
  42. data/spec/models/full_revision_spec.rb +14 -0
  43. data/spec/models/revision_cleaner_spec.rb +27 -0
  44. data/spec/models/revision_stats_spec.rb +0 -0
  45. data/spec/spec_helper.rb +1 -0
  46. data/sw2at-ui.gemspec +27 -6
  47. metadata +27 -6
@@ -0,0 +1,124 @@
1
+ #swat {
2
+ $dropdownBg: #f5f5f5;
3
+ $triangleColor: #858484;
4
+ $dropdownBorder: #D9D9DA;
5
+ $mainFont: Calibri;
6
+ $defaultFontSize: 16px;
7
+ $greenColor: #AAD46F;
8
+ $dropdownBoxShadow: rgba(0,0,0,0.1);
9
+ $fontColor: #7a7a7a;
10
+
11
+
12
+ .custom-dropdown {
13
+ position: relative;
14
+ height: 44px;
15
+
16
+ select {
17
+ width: 100%;
18
+ box-shadow: none;
19
+ opacity: 0.001;
20
+ position: absolute;
21
+ z-index: 10;
22
+ height: 39px;
23
+ & + label.selected {
24
+ position: absolute;
25
+ width: 100%;
26
+ color: #7a7a7a;
27
+ text-transform: none;
28
+ font-size: 16px;
29
+ z-index: 5;
30
+ height: 39px;
31
+ padding-top: 8px;
32
+ box-shadow: none;
33
+ background-color: rgb(250, 250, 250);
34
+ }
35
+ border: 0;
36
+ box-shadow: none;
37
+ & option {
38
+ padding: 7px;
39
+ }
40
+ }
41
+
42
+ .icon {
43
+ z-index: 999;
44
+ position: absolute;
45
+ right: 0px;
46
+ top: 0px;
47
+ background-color: rgba(184, 184, 184, 0.2);
48
+ height: 37px;
49
+ width: 37px;
50
+ padding: 10px 13px;
51
+
52
+ .value {
53
+ height: 24px;
54
+ overflow: hidden;
55
+ }
56
+ }
57
+
58
+ select:focus + label.selected {
59
+ border-color: #8cc63e;
60
+ outline: 0;
61
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(140, 198, 62, 0.6);
62
+ &:after {
63
+ right: 0;
64
+ }
65
+ }
66
+
67
+ select.gl-disabled + label.selected {
68
+ background: #F8F8F8;
69
+ }
70
+
71
+
72
+ .gl-dropdown:active {
73
+ box-shadow: none;
74
+ }
75
+
76
+ ul.dropdown-menu {
77
+ padding: 0;
78
+ top: 45px;
79
+ font-family: $mainFont;
80
+ font-size: $defaultFontSize;
81
+ max-height: 300px;
82
+ width: 400px;
83
+ overflow: auto;
84
+ overflow-x: hidden;
85
+
86
+ li {
87
+ width: 390px;
88
+ padding-top: 5px;
89
+
90
+ a {
91
+ display: block;
92
+ padding: 5px 0 5px 30px;
93
+ text-decoration: none;
94
+ color: $fontColor;
95
+ font-weight: normal;
96
+ transition: all 0.3s ease-out;
97
+ cursor: pointer;
98
+ }
99
+
100
+ &:hover {
101
+ background-color: $dropdownBg;
102
+ }
103
+ &.active {
104
+ a{
105
+ background: $greenColor;
106
+ color: white;
107
+ }
108
+ }
109
+ }
110
+ }
111
+ .custom-dropdown-items.up {
112
+ top: auto;
113
+ bottom: 3px;
114
+ }
115
+ &.up .dropdown-menu {
116
+ top: auto!important;
117
+ bottom: 45px;
118
+ }
119
+ }
120
+ .up .custom-dropdown .custom-dropdown-items{
121
+ top: auto;
122
+ bottom: 3px;
123
+ }
124
+ }
@@ -3,32 +3,12 @@
3
3
  #swat {
4
4
 
5
5
  #configuration {
6
+ .pattern {
6
7
 
7
- .title {
8
-
9
- }
10
- .configuration-info-container {
11
- display: block;
12
- width: 100%;
13
8
  }
14
- #configuration-info {
15
- background: $whiteColor;
16
- border: 1px solid $containerBorder;
17
- margin: 20px;
18
- padding: 28px 38px;
19
- width: 800px;
20
- margin: auto;
21
-
22
- .heading {
23
- text-align: left;
24
- margin: 0;
25
- color: rgba(60, 56, 55, 0.68);
26
- }
27
-
28
- table {
29
- margin-bottom: 18px;
30
- }
31
9
 
10
+ .tags {
11
+ color: $lightBlueColor
32
12
  }
33
13
  }
34
14
 
@@ -0,0 +1,60 @@
1
+ @import "vars";
2
+
3
+ .modal-content {
4
+ background: none !important;
5
+ box-shadow: none !important;
6
+ border: none !important;
7
+ }
8
+
9
+ #confirmation-modal {
10
+
11
+ margin: 50px;
12
+ border: 1px solid rgb(219, 217, 217);
13
+ border-radius: 1px;
14
+ box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
15
+
16
+ .modal-title {
17
+ padding: 10px;
18
+ margin: 0;
19
+ color: rgb(209, 66, 66);
20
+ background-color: rgb(242, 206, 206);
21
+ text-align: center;
22
+ }
23
+
24
+ .modal-body {
25
+ padding: 20px;
26
+ background: #f0f0f0;
27
+ display: inline-block;
28
+ width: 100%;
29
+
30
+ .message {
31
+ display: inline-block;
32
+ margin: 0 0px 15px 0;
33
+ font-size: 19px;
34
+ color: rgb(88, 81, 81);
35
+ width: 100%;
36
+ }
37
+
38
+ .confirmation-modal-footer {
39
+ button {
40
+ width: 200px;
41
+ &.yes {
42
+ float: left;
43
+ }
44
+ &.no {
45
+ float: right;
46
+ }
47
+ }
48
+ }
49
+ }
50
+
51
+ .loader {
52
+ background: url("/assets/swat/loading-green.gif") no-repeat;
53
+ width: 50px;
54
+ height: 50px;
55
+ display: inline-block;
56
+ float: left;
57
+ margin-left: 16px;
58
+ }
59
+
60
+ }
@@ -0,0 +1,68 @@
1
+ @import "vars";
2
+
3
+ #swat {
4
+
5
+ #console {
6
+
7
+ .nav-tabs {
8
+ width: $infoWidgetWidth;
9
+ margin: auto;
10
+
11
+ span.label {
12
+ padding: 9px 15px 0px 21px;
13
+ display: inline-block;
14
+ }
15
+ }
16
+
17
+ .info-widget {
18
+ .heading {
19
+ padding-bottom: 5px;
20
+
21
+ &:not(:first-child) {
22
+ margin-top: 17px;
23
+ border-top: 1px solid lightgray;
24
+ padding-top: 12px;
25
+ }
26
+
27
+ span {
28
+ cursor: pointer;
29
+ }
30
+ }
31
+
32
+ .action-bar {
33
+
34
+ display: inline-block;
35
+ width: 100%;
36
+ margin-bottom: 5px;
37
+
38
+ .custom-dropdown {
39
+ width: 250px;
40
+ float: left;
41
+ margin-right: 20px;
42
+ }
43
+
44
+ button {
45
+ height: 38px;
46
+ }
47
+ }
48
+ }
49
+
50
+ table.info {
51
+ margin-bottom: 0;
52
+ tr {
53
+ td.name {
54
+ width: 340px;
55
+ }
56
+ td.input {
57
+ input {
58
+
59
+ }
60
+ }
61
+ td.action {
62
+
63
+ }
64
+ }
65
+ }
66
+ }
67
+
68
+ }
@@ -27,6 +27,7 @@
27
27
  line-height: 15px;
28
28
  cursor: pointer;
29
29
  margin-left: 0;
30
+ transition: background-color 0.35s linear;
30
31
 
31
32
  &:hover {
32
33
  background: rgba(255, 255, 255, 0.31);
@@ -5,13 +5,11 @@ html, body {
5
5
  min-height: 100%;
6
6
  }
7
7
 
8
- body {
9
- overflow-y: scroll;
10
- }
11
-
12
8
  #swat {
13
9
  height: 100%;
14
10
  min-height: 100%;
11
+ overflow-y: scroll;
12
+ color: $defaultFontColor;
15
13
 
16
14
  .controls {
17
15
  float: right;
@@ -28,8 +26,8 @@ body {
28
26
  }
29
27
  }
30
28
 
31
-
32
29
  #container {
30
+
33
31
  background: $containerBg;
34
32
  margin: 0px 15px 0 15px;
35
33
  border: 1px solid $containerBorder;
@@ -96,7 +94,7 @@ body {
96
94
  width: 100%;
97
95
  .revision-name {
98
96
  padding-left: 10px;
99
- color: black;
97
+ color: $defaultFontColor;
100
98
  }
101
99
  .revision-status {
102
100
  float: left;
@@ -284,7 +282,7 @@ body {
284
282
  margin-left: 12px;
285
283
  margin-right: 12px;
286
284
  span.label {
287
- color: $blackColor;
285
+ color: $defaultFontColor;
288
286
  font-size: 15px;
289
287
  }
290
288
  }
@@ -1,19 +1,15 @@
1
- $greyBg: #9f9f9f;
1
+ @import "boostrap_vars";
2
+
3
+ // Application Colors
4
+
2
5
  $greenMain: greenyellow;
3
6
 
4
7
  $blackColor: black;
5
8
  $whiteColor: white;
6
- $lightBlueColor: #C2CAF2;
9
+ $defaultFontColor: #464646;
7
10
 
8
11
  $disabledLinkColor: rgba(198, 198, 197, 0.68);
9
12
 
10
- $footerSize: 45px;
11
- $negativeFooterSize: -$footerSize;
12
-
13
- $commandWidth: 400px;
14
- $copyIconWidth: 30px;
15
- $commandTextWidth: $commandWidth - $copyIconWidth;
16
-
17
13
  $greenBtnBg: rgb(124, 222, 124);
18
14
  $greenBtnBgHover: rgb(169, 222, 157);
19
15
  $greenBtnColor: green;
@@ -35,7 +31,6 @@ $backtraceSpecColor: #ff5860;
35
31
 
36
32
  $successTitleColor: #50ce5f;
37
33
  $failedTitleColor: #ff5246;
38
-
39
34
  $failedCaseColor: #3F3F3F;
40
35
 
41
36
  $commandBg: $blackColor;
@@ -46,9 +41,24 @@ $failedTestCaseColor: red;
46
41
  $failedTestCaseBgHover: #ffd7e5;
47
42
 
48
43
  $passedTestCaseCommandColor: rgb(129, 192, 129);
49
- $passedTestCaseBg: lightgreen;
44
+ $passedTestCaseBg: rgba(144, 238, 144, 0.73);
50
45
  $passedTestCaseColor: green;
51
46
  $passedTestCaseBgHover: #ffd7e5;
52
47
 
53
48
  $greyBg: rgb(236, 236, 236);
49
+ $lightGreyBg: #F4F3F3;
54
50
  $lightBlueColor: #5967AB;
51
+ $infoLabelColor: #46B444;
52
+
53
+ // Sizes
54
+ $footerSize: 45px;
55
+ $negativeFooterSize: -$footerSize;
56
+
57
+ $commandWidth: 400px;
58
+ $copyIconWidth: 30px;
59
+ $commandTextWidth: $commandWidth - $copyIconWidth;
60
+ $infoWidgetWidth: 800px;
61
+
62
+ // Boostrap Overrides
63
+ $input-border-focus: $infoLabelColor;
64
+
@@ -0,0 +1,17 @@
1
+ module Swat
2
+ module Api
3
+ class ConsoleController < Swat::ApplicationController
4
+
5
+
6
+ def show
7
+ render json: Revision::Root.stats
8
+ end
9
+
10
+ def clean
11
+ result = RevisionCleaner.new.clean_by(params[:attribute], params[:value])
12
+ render json: { result: result }
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,6 @@
1
+ module Swat
2
+ module Pages
3
+ class ComponentsController < BasePagesController
4
+ end
5
+ end
6
+ end
@@ -11,4 +11,35 @@ module RootRevisionExt
11
11
  attrs
12
12
  end
13
13
 
14
+ module ClassMethods
15
+
16
+ def stats
17
+ all_revisions = all
18
+
19
+ branches_stats = all_revisions.count_by_rule(&:branch)
20
+ users_stats = all_revisions.count_by_rule(&:user)
21
+ periods_stats = all_revisions.count_by_rule{|x| period(x.time) }
22
+
23
+ branches = branches_stats.keys
24
+ users = users_stats.keys
25
+ periods = periods_stats.keys
26
+
27
+ {
28
+ branches: branches,
29
+ users: users,
30
+ periods: periods,
31
+ stats: {
32
+ branches: branches_stats,
33
+ users: users_stats,
34
+ periods: periods_stats,
35
+ }
36
+ }
37
+ end
38
+
39
+ def period(timestamp)
40
+ Time.at(timestamp).strftime('%m/%d/%Y')
41
+ end
42
+
43
+ end
44
+
14
45
  end
@@ -0,0 +1,57 @@
1
+ class RevisionCleaner
2
+
3
+ def clean_by(attribute, value)
4
+ @paths = []
5
+
6
+ if attribute.to_sym == :branch
7
+ @paths = branch_paths(value)
8
+ end
9
+
10
+ if attribute.to_sym == :user
11
+ @paths = user_paths(value)
12
+ end
13
+
14
+ if attribute.to_sym == :period
15
+ @paths = period_paths(value)
16
+ end
17
+
18
+ @paths.each do |path|
19
+ Fire::Model.connection.delete(path)
20
+ end
21
+
22
+ true
23
+ end
24
+
25
+ def period_paths(period)
26
+ res = []
27
+ all_revisions = Revision::Root.all
28
+ revisions = all_revisions.select{|rev| Revision::Root.period(rev.time) == period }
29
+
30
+ revisions.each do |rev|
31
+ res << rev.path
32
+ res << rev.path.gsub(Revision.collection_name, TestCase.collection_name)
33
+ end
34
+
35
+ res
36
+ end
37
+
38
+ def branch_paths(branch)
39
+ res = []
40
+ res << [ Revision.collection_name, Fire::Model.path_value_param(branch) ]*Fire::Model::LEVEL_SEPARATOR
41
+ res << [ TestCase.collection_name, Fire::Model.path_value_param(branch) ]*Fire::Model::LEVEL_SEPARATOR
42
+ end
43
+
44
+ def user_paths(user)
45
+ res = []
46
+ all_revisions = Revision::Root.all
47
+ revisions = all_revisions.select{|rev| rev.user == user }
48
+
49
+ revisions.each do |rev|
50
+ res << rev.path
51
+ res << rev.path.gsub(Revision.collection_name, TestCase.collection_name)
52
+ end
53
+
54
+ res
55
+ end
56
+
57
+ end
@@ -0,0 +1,16 @@
1
+ .custom-dropdown dropdown=""
2
+ select.form-control [
3
+ name="{{id}}"
4
+ id="{{id}}"
5
+ ng-class="{'gl-disabled': glDisabled}"
6
+ ng-disabled="glDisabled"
7
+ ng-model="model"
8
+ ng-options="value as value for value in selectOptions"
9
+ ng-change="selectOption(model)"
10
+ tabindex="{{glTabIndex}}"
11
+ ]
12
+ option ng-if="!placeholder && !!emptyOption"
13
+ label.selected.form-control for="{{id}}"
14
+ i.icon.fa.fa-angle-down
15
+ .value
16
+ | {{ model }}
@@ -1,9 +1,9 @@
1
1
  #configuration
2
2
  span.loader ng-class="{ true: 'invisible' }[(configPromise && configPromise.$resolved)]"
3
3
  h1.title Configuration
4
- .configuration-info-container
5
- #configuration-info
6
- div ng-if="config"
4
+ .configuration-info-container.info-widget-container ng-if="config"
5
+ #configuration-info.info-widget
6
+ div
7
7
  h2.heading Firebase
8
8
  table.info.firebase
9
9
  tbody
@@ -0,0 +1,13 @@
1
+ #confirmation-modal
2
+ h4.modal-title
3
+ | Confirmation
4
+ .close ng-click="cancel()"
5
+
6
+ .modal-body
7
+ span.message ng-bind-html="helpers.renderHtml(message)"
8
+
9
+ .confirmation-modal-footer
10
+ span.loader ng-if="waitingAction"
11
+ .controls ng-if="!waitingAction"
12
+ button.btn.btn-success.yes ng-click="ok()" ng-disabled="waitingAction" Yes
13
+ button.btn.btn-default.no ng-click="cancel()" ng-disabled="waitingAction" No
@@ -0,0 +1,6 @@
1
+ #console
2
+ span.loader ng-class="{ true: 'invisible' }[(consoleDataPromise && consoleDataPromise.$resolved)]"
3
+ h1.title Console
4
+ .info-widget-container
5
+ .info-widget ng-if="(consoleDataPromise && consoleDataPromise.$resolved)"
6
+ = render partial: 'swat/pages/management/partials/stats'
@@ -0,0 +1,26 @@
1
+ h3.heading
2
+ span (data-toggle="collapse" data-target="##{objects}-stats")
3
+ | Clean #{ objects }
4
+
5
+ .action-bar(class=object)
6
+ custom-dropdown(model="clean.#{object}.name" options="consoleData.#{objects}")
7
+ button.btn.action.btn-danger(ng-disabled="helpers.isEmpty(clean.#{object}.name)" ng-click="remove('#{object}')")
8
+ | Remove revisions by #{ object }
9
+
10
+ .in(id="#{objects}-stats")
11
+ table.info
12
+ tr ng-repeat="(metric, count) in consoleData.stats.#{objects}"
13
+ td.name
14
+ | {{ metric }}
15
+ td.value
16
+ strong
17
+ | {{ consoleData.stats.#{objects}[metric] }}
18
+ | &nbsp; revisions
19
+ tr
20
+ td.name
21
+ strong
22
+ | Total
23
+ td.value
24
+ strong
25
+ | {{ consoleData.#{objects}.length }} #{ objects }, {{ sum(consoleData.stats.#{objects}) }}
26
+ | &nbsp; revisions
@@ -0,0 +1,4 @@
1
+ - [ [ :branch, :branches ], [ :user, :users ], [ :period, :periods ] ].each do |(object, objects)|
2
+ = render partial: 'swat/pages/management/partials/action_bar', locals: { object: object, objects: objects }
3
+
4
+
@@ -10,13 +10,13 @@
10
10
  | Configuration
11
11
 
12
12
  li
13
- a.revisions href="#" title="Run new revision" ng-disabled="true"
14
- | Run
13
+ a.revisions href="#" ui-sref="console" title="Open console"
14
+ | Console
15
15
 
16
16
  li
17
- a.revisions href="#" title="Open console" ng-disabled="true"
18
- | Console
17
+ a.revisions href="#" title="Manage SWAT Daemon" ng-disabled="true"
18
+ | Daemon
19
19
 
20
20
  li
21
- a.revisions href="#" title="Read about us" ng-disabled="true"
22
- | About Us
21
+ a.revisions href="#" title="Help" ng-disabled="true"
22
+ | Help
data/config/routes.rb CHANGED
@@ -12,6 +12,9 @@ Swat::Engine.routes.draw do
12
12
  put 'revision/name/:name', to: 'revisions#set_name'
13
13
 
14
14
  get 'configuration', to: 'configuration#show'
15
+
16
+ delete 'console/clean/:attribute/:value', to: 'console#clean'
17
+ get 'console', to: 'console#show'
15
18
  end
16
19
 
17
20
  # Helper Methods
@@ -22,6 +25,14 @@ Swat::Engine.routes.draw do
22
25
  end
23
26
  end
24
27
 
28
+ def declare_namespace(name, pages)
29
+ namespace name do
30
+ pages.each do |p|
31
+ get p, to: p
32
+ end
33
+ end
34
+ end
35
+
25
36
  # Angular States
26
37
  namespace :info do
27
38
  level_paths.each do |path|
@@ -31,19 +42,9 @@ Swat::Engine.routes.draw do
31
42
 
32
43
  # Angular Pages
33
44
  namespace :pages do
34
- namespace :revisions do
35
- pages = [ :index, :show, :summary, :name ]
36
- pages.each do |p|
37
- get p, to: p
38
- end
39
- end
40
-
41
- namespace :management do
42
- pages = [ :console, :configuration, :about ]
43
- pages.each do |p|
44
- get p, to: p
45
- end
46
- end
45
+ declare_namespace :revisions, [ :index, :show, :summary, :name ]
46
+ declare_namespace :management, [ :console, :configuration, :about, :confirmation ]
47
+ declare_namespace :components, [ :custom_dropdown ]
47
48
  end
48
49
 
49
50
  end
data/lib/swat/engine.rb CHANGED
@@ -7,6 +7,8 @@ module Swat
7
7
  require 'time_difference'
8
8
  require 'tarvit-helpers'
9
9
 
10
+ require 'tarvit-helpers/extensions/counter'
11
+
10
12
  class Engine < ::Rails::Engine
11
13
  isolate_namespace Swat
12
14
  end