caseflow 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 46d897006bb989bb7eb63c21d4edb1fb24430b81
4
+ data.tar.gz: 22a7df4b8f00ccb4192e31881c36c459d80d2d4e
5
+ SHA512:
6
+ metadata.gz: 1576cc07f39c82e763801ac325a1c7167c1c9c7a01591c99295430d966cadf95042a64dfb7c889627ecbff62943f163f408649e8867fcb8007785fc513644b07
7
+ data.tar.gz: a45324f9e9735db247cd304b744d1c0b9223cbac4e71430adfbad58ba7dd4053084c0d647db0503a19e029a4af0722079cf1068b85055d6a604bdcc003655fc9
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.0
5
+ before_install: gem install bundler -v 1.12.5
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in caseflow.gemspec
4
+ gemspec
@@ -0,0 +1,35 @@
1
+ # Caseflow
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/caseflow`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'caseflow'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install caseflow
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/department-of-veterans-affairs/caseflow-commons.
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1 @@
1
+ <svg width="60" height="50" class="cf-icon-found" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 50" aria-labelledby="title"><title>found</title><path fill="#2e8540" d="M57 13.3L29.9 41.7 24.8 47c-.7.7-1.6 1.1-2.5 1.1-.9 0-1.9-.4-2.5-1.1l-5.1-5.3L1 27.5c-.7-.7-1-1.7-1-2.7s.4-2 1-2.7l5.1-5.3c.7-.7 1.6-1.1 2.5-1.1.9 0 1.9.4 2.5 1.1l11 11.6L46.8 2.7c.7-.7 1.6-1.1 2.5-1.1.9 0 1.9.4 2.5 1.1L57 8c.7.7 1 1.7 1 2.7 0 1-.4 1.9-1 2.6z"/></svg>
@@ -0,0 +1,23 @@
1
+ // This is a manifest file that'll be compiled into stats.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file.
9
+ //
10
+ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require d3
14
+ //= require moment
15
+ //= require moment-timezone
16
+ //= require_tree ./stats
17
+
18
+ // Offset data for the Eastern time zone
19
+ moment.tz.add("America/New_York|EST EDT EWT EPT|50 40 40 40|01010101010101010101010101010101010101010101010102301010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-261t0 1nX0 11B0 1nX0 11B0 1qL0 1a10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 RB0 8x40 iv0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|21e6")
20
+
21
+ $(function() {
22
+ window.StatsPanelToggle.bind();
23
+ });
@@ -0,0 +1,172 @@
1
+ window.Dashboard = (function(d3, moment) {
2
+ // private
3
+ var data, interval, index, maxIndex, dateStrings, charts, values, rates, times, dates, tables, x, y, bars
4
+
5
+ function init(opts) {
6
+ data = opts.data
7
+ interval = opts.interval
8
+
9
+ index = 0
10
+ maxIndex = data.length - 1
11
+ dateStrings = data.map(function (d, i) {
12
+ var date = moment.unix(d.key).tz('America/New_York')
13
+ var str = ''
14
+ switch (interval) {
15
+ case 'hourly': str += date.format('HH:mm') + '–' + date.add(59, 'm').format('HH:mm z'); break
16
+ case 'daily': str += date.format('MMMM D'); break
17
+ case 'weekly': str += 'the week of ' + date.format('MMMM D'); break
18
+ case 'monthly': str += date.format(i < 12 ? 'MMMM' : 'MMMM YYYY'); break
19
+ default: str += date.format('X')
20
+ }
21
+
22
+ if (i === 0) { str += ' (so far)'}
23
+
24
+ return str
25
+ })
26
+
27
+ charts = d3.selectAll('.data-chart')
28
+ .call(setDataByKey)
29
+ .append('svg')
30
+ values = d3.selectAll('.data-value')
31
+ .call(setDataByKey)
32
+ rates = d3.selectAll('.data-rate')
33
+ .call(setDataByKey)
34
+ times = d3.selectAll('.data-time')
35
+ .call(setDataByKey)
36
+ tables = d3.select('.data-table')
37
+ .call(setDataByKey)
38
+ dates = d3.selectAll('.data-date')
39
+
40
+ x = d3.scaleBand()
41
+ .domain(d3.range(0, data.length))
42
+ .paddingInner(0.1)
43
+
44
+ y = d3.local()
45
+ charts.property(y, function (d) {
46
+ var max
47
+
48
+ switch (d.key) {
49
+ default: max = d3.max(d.values)
50
+ }
51
+
52
+ max = max > 1 ? max : 1
53
+
54
+ return d3.scaleLinear()
55
+ .domain([0, max])
56
+ })
57
+
58
+ charts.append('g').append('title').text('Historical Data')
59
+
60
+ bars = charts.selectAll('.bar')
61
+ .data(function (d) { return d.values })
62
+ .enter().append('rect')
63
+ .attr('class', 'bar')
64
+ .attr('title', function (d, i) { return dateStrings[i] + ': ' + d })
65
+
66
+ resize()
67
+
68
+ d3.select(window)
69
+ .on('resize', resize)
70
+ .on('keydown', function () {
71
+ switch (d3.event.keyCode || d3.event.detail.keyCode) {
72
+ case 37: index += 1; d3.event.preventDefault(); break // left
73
+ case 39: index -= 1; d3.event.preventDefault(); break // right
74
+ }
75
+
76
+ if (index > maxIndex) { index = 0 }
77
+ else if (index < 0) { index = maxIndex }
78
+
79
+ update()
80
+ })
81
+
82
+ charts.on('mousemove', function () {
83
+ index = maxIndex - Math.max(Math.floor((d3.event.offsetX) / x.step()), 0)
84
+ update()
85
+ })
86
+ }
87
+
88
+ function resize() {
89
+ var testNode = d3.select('.data-chart').node()
90
+ var width = testNode.offsetWidth - 2
91
+ var height = testNode.offsetHeight - 2
92
+
93
+ x.range([width, 0])
94
+
95
+ charts
96
+ .attr('width', width)
97
+ .attr('height', height)
98
+ .each(function () { y.get(this).range([2, height / 2]) })
99
+
100
+ bars
101
+ .attr('x', function (d, i) { return x(i) })
102
+ .attr('y', function (d) { return height - y.get(this)(d || 0) })
103
+ .attr('width', x.bandwidth())
104
+ .attr('height', function (d) { return y.get(this)(d || 0) })
105
+
106
+ update()
107
+ }
108
+
109
+ function update() {
110
+ values.text(function (d) { return d.values[index] })
111
+ rates.html(function (d) { return rateFormat(d.values[index]) })
112
+ times.html(function (d) { return timeFormat(d.values[index]) })
113
+ dates.text('for ' + dateStrings[index])
114
+ bars.attr('opacity', function (d, i) { return i === index ? 0.67 : 0.33 })
115
+
116
+ rows = tables.selectAll('tr')
117
+ .data(function (d) { return d.values[index] })
118
+
119
+ var enterRows = rows.enter().append('tr')
120
+ enterRows.append('td').attr('class', 'id')
121
+ enterRows.append('td').attr('class', 'count')
122
+
123
+ rows.exit().remove()
124
+
125
+ rows = rows.merge(enterRows)
126
+
127
+ rows.each(function (d) {
128
+ var row = d3.select(this);
129
+
130
+ row.select('.id').text(d.id)
131
+ row.select('.count').text(d.count + (d.count === 1 ? ' Download' : ' Downloads'))
132
+ })
133
+ }
134
+
135
+ function setDataByKey(sel) {
136
+ return sel.datum(function () {
137
+ var mapper,
138
+ key = d3.select(this).attr('data-key'),
139
+ keys = key.split('/'),
140
+ isRate = false
141
+
142
+ if (keys.length === 2) {
143
+ isRate = true
144
+ mapper = function (d) { return d.value[keys[1]] === 0 ? null : d.value[keys[0]] / d.value[keys[1]] }
145
+ } else {
146
+ mapper = function (d) { return d.value[key] }
147
+ }
148
+
149
+ return {
150
+ key: key,
151
+ isRate: isRate,
152
+ values: data.map(mapper)
153
+ }
154
+ })
155
+ }
156
+
157
+ var format = d3.format('.2f')
158
+ function rateFormat(n) {
159
+ return (n === null ? '??' : Math.round(n * 100)) +
160
+ ' <span class="cf-stat-unit">%</span>'
161
+ }
162
+ function timeFormat(seconds) {
163
+ return !seconds ? '?? <span class="cf-stat-unit">sec</span>' :
164
+ seconds > 60 ? format(seconds / 60) + ' <span class="cf-stat-unit">min</span>' :
165
+ format(seconds) + ' <span class="cf-stat-unit">sec</span>'
166
+ }
167
+
168
+ // public
169
+ return {
170
+ init: init
171
+ }
172
+ })(d3, moment)
@@ -0,0 +1,19 @@
1
+ window.StatsPanelToggle = (function($) {
2
+ // private
3
+
4
+ function switchActive(e) {
5
+ var current = $(e.currentTarget).children('.cf-stat-option.active').first();
6
+ var next = current.next()
7
+ if (next.length === 0) { next = current.siblings().first(); }
8
+
9
+ current.removeClass('active');
10
+ next.addClass('active');
11
+ }
12
+
13
+ // public
14
+ return {
15
+ bind: function() {
16
+ $('.cf-stat-panel.-toggle').on('click', switchActive);
17
+ }
18
+ };
19
+ })($);
@@ -0,0 +1,19 @@
1
+ @font-face {
2
+ font-family: 'Source Sans Pro';
3
+ font-style: normal;
4
+ font-weight: 400;
5
+ src: local('Source Sans Pro'),
6
+ local('SourceSansPro-Regular'),
7
+ asset-url('source-sans-pro.woff2') format('woff2'),
8
+ asset-url('source-sans-pro.woff') format('woff');
9
+ }
10
+
11
+ @font-face {
12
+ font-family: 'Merriweather';
13
+ font-style: normal;
14
+ font-weight: 400;
15
+ src: local('Merriweather'),
16
+ local('Merriweather-Regular'),
17
+ asset-url('merriweather.woff2') format('woff2'),
18
+ asset-url('merriweather.woff') format('woff');
19
+ }
@@ -0,0 +1,54 @@
1
+ .cf-stats {
2
+ margin-top: 20px;
3
+ }
4
+
5
+ .cf-stats-section {
6
+ @include outer-container;
7
+ margin-bottom: 1em;
8
+ }
9
+
10
+ .cf-stats-table {
11
+ margin-top: 0;
12
+ }
13
+
14
+ .cf-stat-panel {
15
+ @include span-columns(4);
16
+ position: relative;
17
+ border: 1px solid $color-gray-lighter;
18
+ padding: 1em;
19
+ padding-bottom: 6em;
20
+ overflow: hidden;
21
+
22
+ &.-toggle .cf-stat-option {
23
+ display: none;
24
+ &.active { display: block; }
25
+ }
26
+ }
27
+
28
+ .cf-stat-title {
29
+ color: $color-gray;
30
+ font-weight: 400;
31
+ margin: 0;
32
+ }
33
+
34
+ .cf-stat-figure {
35
+ font-size: 6rem;
36
+ font-weight: bold;
37
+ color: $color-gray;
38
+ line-height: .9;
39
+ }
40
+
41
+ .cf-stat-unit {
42
+ font-size: 1.6rem;
43
+ font-weight: normal;
44
+ color: $color-gray;
45
+ margin-left: -0.5em;
46
+ }
47
+
48
+ .data-chart svg {
49
+ position: absolute;
50
+ bottom: 0;
51
+ left: 0;
52
+
53
+ * { pointer-events: none; }
54
+ }
@@ -0,0 +1,79 @@
1
+ .cf-tab-navigation {
2
+ @include unstyled-list;
3
+
4
+ margin-top: 2em;
5
+ position: relative;
6
+ width: 100%;
7
+ border-bottom: 1px solid $color-primary;
8
+
9
+ li {
10
+ display: inline-block;
11
+ margin-right: -1px;
12
+ }
13
+ }
14
+
15
+ .cf-tab {
16
+ @extend .usa-button-unstyled;
17
+
18
+ display: inline-block;
19
+ margin: 0 -3.5px 0 0;
20
+ padding: 15px 1.5em;
21
+ color: $color-gray;
22
+ background-color: $color-white;
23
+ border: 1px solid $color-gray-light;
24
+ border-bottom: 0;
25
+ border-left-width: 0;
26
+ font-weight: normal;
27
+ white-space: nowrap;
28
+
29
+ &::before { content: ''; }
30
+ &::after { margin: 0; }
31
+ &:first-child { border-left-width: 1px; }
32
+
33
+ &:hover {
34
+ color: $color-gray-dark;
35
+ background-color: $color-white;
36
+ text-decoration: none;
37
+ }
38
+
39
+ &:disabled:hover {
40
+ color: $color-gray;
41
+ }
42
+
43
+ &:focus {
44
+ outline: -webkit-focus-ring-color auto 5px;
45
+
46
+ svg path {
47
+ fill: $color-primary;
48
+ }
49
+ }
50
+
51
+ &.cf-active {
52
+ position: relative;
53
+ color: $color-primary;
54
+ border-color: $color-primary;
55
+ border-top-width: 4px;
56
+ border-left-width: 1px;
57
+ padding-top: 13px;
58
+ right: 1px;
59
+ top: 1px;
60
+ margin-right: -4.5px;
61
+
62
+ svg path { fill: $color-primary; }
63
+ }
64
+
65
+ svg {
66
+ margin-right: 0.25em;
67
+ margin-left: -0.4em;
68
+ path { fill: $color-gray; }
69
+ }
70
+ }
71
+
72
+ .cf-tab-content {
73
+ border: 1px solid $color-gray-lighter;
74
+ border-top: 0;
75
+ padding-top: 1px;
76
+ max-height: 600px;
77
+ overflow-y: scroll;
78
+ }
79
+