stackview_acorn_tester 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +291 -0
- data/Rakefile +37 -0
- data/app/assets/javascripts/rails_stackview/auto_init.js +15 -0
- data/app/assets/javascripts/rails_stackview/browser.js +161 -0
- data/app/assets/javascripts/rails_stackview/plain.js +128 -0
- data/app/assets/javascripts/rails_stackview.js +11 -0
- data/app/assets/stylesheets/rails_stackview/_plain.scss +119 -0
- data/app/assets/stylesheets/rails_stackview/browser.scss +116 -0
- data/app/assets/stylesheets/rails_stackview.scss +10 -0
- data/app/controllers/stackview_data_controller.rb +91 -0
- data/app/fetch_adapters/rails_stackview/db_window_fetcher.rb +88 -0
- data/app/fetch_adapters/rails_stackview/mock_fetcher.rb +27 -0
- data/app/models/stackview_call_number.rb +2 -0
- data/app/views/rails_stackview/browser.html.erb +42 -0
- data/config/routes.rb +2 -0
- data/db/migrate/20150602210254_create_stackview_call_numbers.rb +34 -0
- data/lib/rails_stackview/engine.rb +7 -0
- data/lib/rails_stackview/version.rb +3 -0
- data/lib/rails_stackview.rb +20 -0
- data/lib/tasks/rails_stackview_tasks.rake +4 -0
- data/test/controllers/stackview_data_controller_test.rb +55 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +17 -0
- data/test/dummy/app/assets/stylesheets/application.css +20 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/controllers/demo_controller.rb +14 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/demo/index.html.erb +14 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/bin/setup +29 -0
- data/test/dummy/config/application.rb +26 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +41 -0
- data/test/dummy/config/environments/production.rb +79 -0
- data/test/dummy/config/environments/test.rb +42 -0
- data/test/dummy/config/initializers/assets.rb +11 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +67 -0
- data/test/dummy/config/secrets.yml +22 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/public/404.html +67 -0
- data/test/dummy/public/422.html +67 -0
- data/test/dummy/public/500.html +66 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/test_fixture.yaml +433 -0
- data/test/fetch_adapters/db_window_fetcher_test.rb +106 -0
- data/test/fixtures/stackview_call_numbers.yml +473 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/rails_stackview_test.rb +7 -0
- data/test/test_helper.rb +42 -0
- data/vendor/assets/README.md +16 -0
- data/vendor/assets/images/stackview/bookEnd-next.png +0 -0
- data/vendor/assets/images/stackview/bookEnd-prev.png +0 -0
- data/vendor/assets/images/stackview/gloss.png +0 -0
- data/vendor/assets/images/stackview/highGloss.png +0 -0
- data/vendor/assets/images/stackview/icon-globe.png +0 -0
- data/vendor/assets/images/stackview/icon-note.png +0 -0
- data/vendor/assets/images/stackview/nav.png +0 -0
- data/vendor/assets/images/stackview/placeholder.gif +0 -0
- data/vendor/assets/images/stackview/ribbonTab.png +0 -0
- data/vendor/assets/images/stackview/serials-edge.png +0 -0
- data/vendor/assets/images/stackview/serials.png +0 -0
- data/vendor/assets/images/stackview/superGloss.png +0 -0
- data/vendor/assets/javascripts/jquery.stackview.js +21 -0
- data/vendor/assets/javascripts/stackview/jquery.easing.1.3.js +205 -0
- data/vendor/assets/javascripts/stackview/jquery.stackview.base.js +561 -0
- data/vendor/assets/javascripts/stackview/jquery.stackview.infinite.js +46 -0
- data/vendor/assets/javascripts/stackview/jquery.stackview.ministack.js +33 -0
- data/vendor/assets/javascripts/stackview/jquery.stackview.navigation.js +71 -0
- data/vendor/assets/javascripts/stackview/jquery.stackview.stackcache.js +74 -0
- data/vendor/assets/javascripts/stackview/jquery.stackview.templates.js +31 -0
- data/vendor/assets/javascripts/stackview/microtemplating.js +40 -0
- data/vendor/assets/javascripts/stackview/types/book.js +184 -0
- data/vendor/assets/javascripts/stackview/types/my_plain.js +183 -0
- data/vendor/assets/javascripts/stackview/types/serial.js +40 -0
- data/vendor/assets/javascripts/stackview/types/soundrecording.js +42 -0
- data/vendor/assets/javascripts/stackview/types/videofilm.js +56 -0
- data/vendor/assets/javascripts/stackview/types/webpage.js +42 -0
- data/vendor/assets/stackview.sha +1 -0
- data/vendor/assets/stylesheets/stackview/_book.scss +66 -0
- data/vendor/assets/stylesheets/stackview/_heatmap.scss +154 -0
- data/vendor/assets/stylesheets/stackview/_ministack.scss +43 -0
- data/vendor/assets/stylesheets/stackview/_mixins.scss +100 -0
- data/vendor/assets/stylesheets/stackview/_navigation.scss +52 -0
- data/vendor/assets/stylesheets/stackview/_plain.scss +71 -0
- data/vendor/assets/stylesheets/stackview/_serial.scss +50 -0
- data/vendor/assets/stylesheets/stackview/_soundrecording.scss +83 -0
- data/vendor/assets/stylesheets/stackview/_videofilm.scss +74 -0
- data/vendor/assets/stylesheets/stackview/_webpage.scss +82 -0
- data/vendor/assets/stylesheets/stackview/jquery.stackview.scss +171 -0
- metadata +233 -0
@@ -0,0 +1,119 @@
|
|
1
|
+
|
2
|
+
.stack-plain {
|
3
|
+
box-sizing: content-box;
|
4
|
+
position: relative;
|
5
|
+
|
6
|
+
> a {
|
7
|
+
box-sizing: content-box;
|
8
|
+
|
9
|
+
min-height: 40px;
|
10
|
+
|
11
|
+
position:relative;
|
12
|
+
width: 100%;
|
13
|
+
|
14
|
+
border-radius: 3px 0 0 3px;
|
15
|
+
border-width:1px;
|
16
|
+
border-style:solid;
|
17
|
+
text-shadow:none;
|
18
|
+
font-size:11px;
|
19
|
+
padding:0 10px 0 0;
|
20
|
+
|
21
|
+
// disable background image inherited
|
22
|
+
&, &:hover, &:active, &:focus {
|
23
|
+
background-image: none;
|
24
|
+
}
|
25
|
+
|
26
|
+
font-family: monospace;
|
27
|
+
}
|
28
|
+
|
29
|
+
.spine-year {
|
30
|
+
@include rotate(-90deg);
|
31
|
+
}
|
32
|
+
|
33
|
+
.label-container {
|
34
|
+
//Makes it easier to keep the spine-text away from the date label
|
35
|
+
//with another container, sorry.
|
36
|
+
display: block;
|
37
|
+
margin: 0;
|
38
|
+
padding: 3px 28px 4px 4px;
|
39
|
+
max-width: 100%;
|
40
|
+
}
|
41
|
+
|
42
|
+
.spine-text {
|
43
|
+
position: static;
|
44
|
+
|
45
|
+
// Make it look kind of like a printed label
|
46
|
+
background-color: #f9fceb;
|
47
|
+
color: rgb(34, 34, 34);
|
48
|
+
border-color: rgb(34, 34, 34);
|
49
|
+
border-radius: 4px;
|
50
|
+
padding: 4px 0 2px 4px;
|
51
|
+
|
52
|
+
display: inline-block;
|
53
|
+
max-width: 100%;
|
54
|
+
}
|
55
|
+
|
56
|
+
|
57
|
+
|
58
|
+
.plain-title, .plain-format, .plain-author {
|
59
|
+
box-sizing: border-box !important;
|
60
|
+
max-width: 100%;
|
61
|
+
overflow: hidden;
|
62
|
+
text-overflow: ellipsis;
|
63
|
+
white-space:nowrap;
|
64
|
+
padding-right: 7px;
|
65
|
+
line-height: 16px;
|
66
|
+
}
|
67
|
+
|
68
|
+
.plain-title {
|
69
|
+
font-size: 13px;
|
70
|
+
float: left;
|
71
|
+
}
|
72
|
+
.plain-format {
|
73
|
+
float: left;
|
74
|
+
clear: left;
|
75
|
+
&:empty {
|
76
|
+
clear: none;
|
77
|
+
}
|
78
|
+
padding-right: 30px;
|
79
|
+
}
|
80
|
+
.plain-author {
|
81
|
+
float: right;
|
82
|
+
}
|
83
|
+
|
84
|
+
.plain-top {
|
85
|
+
content:'';
|
86
|
+
display:block;
|
87
|
+
position:absolute;
|
88
|
+
top:-5px;
|
89
|
+
left:4px;
|
90
|
+
right:-5px;
|
91
|
+
height:3px;
|
92
|
+
border-width:1px;
|
93
|
+
border-style:solid;
|
94
|
+
@include skew(-70deg, 0);
|
95
|
+
border-radius:0 5px 0 5px;
|
96
|
+
z-index:2;
|
97
|
+
}
|
98
|
+
|
99
|
+
.plain-edge {
|
100
|
+
content:'';
|
101
|
+
display:block;
|
102
|
+
position:absolute;
|
103
|
+
top:-3px;
|
104
|
+
bottom:1px;
|
105
|
+
right:-8px;
|
106
|
+
width:6px;
|
107
|
+
@include skew(0, -20deg);
|
108
|
+
border-width:0 1px 1px 0;
|
109
|
+
border-style:solid;
|
110
|
+
}
|
111
|
+
|
112
|
+
}
|
113
|
+
|
114
|
+
|
115
|
+
|
116
|
+
|
117
|
+
|
118
|
+
|
119
|
+
|
@@ -0,0 +1,116 @@
|
|
1
|
+
$rails-shelfbrowse-hide-browse-breakpoint: 565px !default;
|
2
|
+
|
3
|
+
.shelfbrowser {
|
4
|
+
display: block;
|
5
|
+
width: 100%;
|
6
|
+
max-width: 1340px;
|
7
|
+
overflow: hidden;
|
8
|
+
margin-right: auto;
|
9
|
+
margin-left: auto;
|
10
|
+
|
11
|
+
position: relative;
|
12
|
+
box-sizing: border-box;
|
13
|
+
|
14
|
+
|
15
|
+
|
16
|
+
// we prefer no ribbon
|
17
|
+
.stackview .ribbon {
|
18
|
+
display: none;
|
19
|
+
}
|
20
|
+
|
21
|
+
.stackview .stack-navigation {
|
22
|
+
top: 55px; // not sure why it ended up 5px by default.
|
23
|
+
}
|
24
|
+
|
25
|
+
.shelfbrowser-browse-column, .shelfbrowser-info-column {
|
26
|
+
display: block;
|
27
|
+
}
|
28
|
+
|
29
|
+
.shelfbrowser-browse-column {
|
30
|
+
width: 55%;
|
31
|
+
@media screen and (min-width: 925px) {
|
32
|
+
width: 60%;
|
33
|
+
}
|
34
|
+
// on Very small screens, this column is it.
|
35
|
+
@media screen and (max-width: $rails-shelfbrowse-hide-browse-breakpoint) {
|
36
|
+
width: 100%;
|
37
|
+
}
|
38
|
+
|
39
|
+
float: left;
|
40
|
+
|
41
|
+
// Does weird with our columns, but we're leaving in for now
|
42
|
+
padding-left: 8px;
|
43
|
+
|
44
|
+
.stackview {
|
45
|
+
overflow-y: hidden;
|
46
|
+
|
47
|
+
|
48
|
+
// Trying to do this made IE unhappy.
|
49
|
+
//position: absolute;
|
50
|
+
//height: 100%;
|
51
|
+
//width: 100%;
|
52
|
+
|
53
|
+
// Stackview does not like box-styling: border-box.
|
54
|
+
// Bootstrap applies it to everything, we apply it to
|
55
|
+
// some things above here on purpose, as it makes things better.
|
56
|
+
// But we need to return actual contents of the .stackview to
|
57
|
+
// content-box.
|
58
|
+
box-sizing: content-box;
|
59
|
+
* {
|
60
|
+
box-sizing: inherit;
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
}
|
65
|
+
|
66
|
+
.shelfbrowser-info-column {
|
67
|
+
box-sizing: border-box;
|
68
|
+
width: 45%;
|
69
|
+
@media screen and (min-width: 925px) {
|
70
|
+
padding-right: 48px;
|
71
|
+
width: 40%;
|
72
|
+
}
|
73
|
+
// Hide entirely on very small sizes
|
74
|
+
@media screen and (max-width: $rails-shelfbrowse-hide-browse-breakpoint) {
|
75
|
+
display: none;
|
76
|
+
}
|
77
|
+
|
78
|
+
float: left;
|
79
|
+
overflow-y: auto;
|
80
|
+
|
81
|
+
padding: 0 16px 16px 16px;
|
82
|
+
|
83
|
+
.shelfbrowse-header {
|
84
|
+
border-bottom: 1px solid #eeeeee;
|
85
|
+
margin-bottom: 16px;
|
86
|
+
}
|
87
|
+
|
88
|
+
.stack-item-panel {
|
89
|
+
overflow-x: hidden;
|
90
|
+
}
|
91
|
+
|
92
|
+
.shelfbrowser-back-btn a {
|
93
|
+
display: block;
|
94
|
+
text-align: right;
|
95
|
+
}
|
96
|
+
|
97
|
+
}
|
98
|
+
|
99
|
+
.active-item {
|
100
|
+
margin-left: 10px;
|
101
|
+
// Make the old item nudge in just a bit before
|
102
|
+
// new item nudges out.
|
103
|
+
transition-delay: 40ms;
|
104
|
+
}
|
105
|
+
|
106
|
+
li.stack-item {
|
107
|
+
// For browsers that support CSS transitions, make
|
108
|
+
// pull out of active item awesome.
|
109
|
+
transition-property: margin-left;
|
110
|
+
transition-duration: 120ms;
|
111
|
+
transition-timing-function: ease-in;
|
112
|
+
|
113
|
+
}
|
114
|
+
|
115
|
+
}
|
116
|
+
|
@@ -0,0 +1,10 @@
|
|
1
|
+
/*
|
2
|
+
* CSS manifest file for rails_stackview, we make an scss file using
|
3
|
+
* imports, so our custom rails_stackview CSS, like the plain type
|
4
|
+
* definition, can use mixins defined in jquery.stackview
|
5
|
+
*
|
6
|
+
* Includes vendored stackview CSS and any of our own custom CSS
|
7
|
+
*/
|
8
|
+
@import 'stackview/jquery.stackview';
|
9
|
+
@import 'rails_stackview/browser';
|
10
|
+
@import 'rails_stackview/plain';
|
@@ -0,0 +1,91 @@
|
|
1
|
+
class StackviewDataController < ApplicationController
|
2
|
+
|
3
|
+
ApplicationController::ActionController::Parameters.permit_all_parameters = true
|
4
|
+
ApplicationController::ActionController::Parameters.action_on_unpermitted_parameters = :raise
|
5
|
+
|
6
|
+
# stackview doesn't like it if certain things are blank
|
7
|
+
DefaultStackviewDocAttributes = {
|
8
|
+
"measurement_height_numeric" => 23,
|
9
|
+
"shelfrank" => 1,
|
10
|
+
"measurement_page_numeric" => 100
|
11
|
+
}
|
12
|
+
ß
|
13
|
+
# config for different call number types; we don't
|
14
|
+
# fully support call number types yet, but are building for it.
|
15
|
+
# with the exception of the 'test' type
|
16
|
+
class_attribute :_config_for_types
|
17
|
+
self._config_for_types = {
|
18
|
+
'default' => {
|
19
|
+
:fetch_adapter => lambda { RailsStackview::DbWindowFetcher.new },
|
20
|
+
# By default, automatic link to Blacklight catalog_path if present
|
21
|
+
:link => lambda do |hash|
|
22
|
+
if self.respond_to?(:catalog_path)
|
23
|
+
catalog_path(hash["system_id"])
|
24
|
+
else
|
25
|
+
hash["link"]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
},
|
29
|
+
'test' => {
|
30
|
+
:fetch_adapter => lambda { RailsStackview::MockFetcher.new }
|
31
|
+
},
|
32
|
+
'lc' => {
|
33
|
+
# defaults are good.
|
34
|
+
}
|
35
|
+
}
|
36
|
+
def self.set_config_for_type(type, attributes)
|
37
|
+
type = type.to_s
|
38
|
+
config = (self._config_for_types[type] ||= {})
|
39
|
+
config.merge! attributes
|
40
|
+
|
41
|
+
return config
|
42
|
+
end
|
43
|
+
def self.config_for_type(type)
|
44
|
+
type = type.to_s
|
45
|
+
|
46
|
+
config = self._config_for_types[type]
|
47
|
+
unless config
|
48
|
+
raise ArgumentError, "No config found for #{type}"
|
49
|
+
end
|
50
|
+
default = _config_for_types['default']
|
51
|
+
|
52
|
+
return config.reverse_merge(default)
|
53
|
+
end
|
54
|
+
def config_for_type(type)
|
55
|
+
self.class.config_for_type(type)
|
56
|
+
end
|
57
|
+
# mostly for testing
|
58
|
+
def self.remove_config_for_type(type)
|
59
|
+
type = type.to_s
|
60
|
+
_config_for_types.delete(type)
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
def fetch
|
66
|
+
config = config_for_type( params[:call_number_type] )
|
67
|
+
|
68
|
+
fetch_adapter = config[:fetch_adapter].call
|
69
|
+
|
70
|
+
# Make sure defaults are covered
|
71
|
+
docs = fetch_adapter.fetch(params).collect do |d|
|
72
|
+
d = d.reverse_merge DefaultStackviewDocAttributes
|
73
|
+
# stackview doens't like shelfrank's over 100
|
74
|
+
d["shelfrank"] = [d["shelfrank"], 100].min
|
75
|
+
|
76
|
+
d
|
77
|
+
end
|
78
|
+
|
79
|
+
# add in URLs
|
80
|
+
url_proc = config[:link] || (lambda {|doc| doc["link"]})
|
81
|
+
docs.each do |doc|
|
82
|
+
doc["link"] = self.instance_exec(doc, &url_proc)
|
83
|
+
end
|
84
|
+
|
85
|
+
result = {'docs' => docs}
|
86
|
+
result['start'] = "-1" if docs.empty?
|
87
|
+
|
88
|
+
render :json => result
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module RailsStackview
|
2
|
+
|
3
|
+
# Fetches from the stackview_call_numbers table with ActiveRecord
|
4
|
+
#
|
5
|
+
# * Assumes a windowing `search_type:loc_sort_order` in stackview, which
|
6
|
+
# sends query=[X TO Y] in params.
|
7
|
+
#
|
8
|
+
# * Additionally assumes we get an `origin_sort_key` in params,
|
9
|
+
# which will used as the "zero point" for stackview's query ranges.
|
10
|
+
# It must be an actual normalized sort_key -- if it does not exist in the DB,
|
11
|
+
# we'll just browse from that point in sort order though.
|
12
|
+
#
|
13
|
+
# We use this origin_sortkey to try and avoid very deep offsets in our
|
14
|
+
# SQL, which get expensive, although if the user pages a LOT they can
|
15
|
+
# still get there. If this is not good enough, we'll have to contribute
|
16
|
+
# features to stackview to provide alternate windowing based on sortkeys
|
17
|
+
# alone.
|
18
|
+
#
|
19
|
+
# Create a path to the StackviewDataController using 'lc' call_number_type,
|
20
|
+
# which uses this fetcher, specifying the origin_sort_key as a query param:
|
21
|
+
#
|
22
|
+
# stackview_data_path("lc", :origin_sort_key => some_sort_key)
|
23
|
+
class DbWindowFetcher
|
24
|
+
|
25
|
+
def fetch(params)
|
26
|
+
@origin_sort_key = params["origin_sort_key"]
|
27
|
+
@sort_key_type = params["sort_key_type"] || "lc"
|
28
|
+
|
29
|
+
unless @origin_sort_key.present?
|
30
|
+
raise ArgumentError, "`origin_sort_key` param required, specifying where to start the browse"
|
31
|
+
end
|
32
|
+
|
33
|
+
(first, last) = RailsStackview.parse_query_range(params["query"])
|
34
|
+
unless first < last
|
35
|
+
raise ArgumentError, "beginning of range must be less than end: #{params["query"]}"
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
# Fetch the AR models, then turn em into hashes, which include all
|
40
|
+
# columns in the db, excluding some we don't want.
|
41
|
+
#
|
42
|
+
# Plus we need to turn our single creator into an array, cause
|
43
|
+
# that's what stackview wants.
|
44
|
+
results = fetch_records(first, last).collect do |record|
|
45
|
+
record.attributes.except('id').reject {|k, v| v.blank? }.
|
46
|
+
merge("creator" => (record["creator"].present? ? [record['creator']] : record['creator']))
|
47
|
+
end
|
48
|
+
|
49
|
+
# Mark the thing at 0 index as origin:true, so it can be auto-selected
|
50
|
+
# by browser.
|
51
|
+
if (first..last).cover?(0)
|
52
|
+
origin_index = [first.abs, results.length - 1].min
|
53
|
+
results[origin_index]["is_origin_item"] = true
|
54
|
+
end
|
55
|
+
|
56
|
+
return results
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
# Returns ActiveRecord StackviewCallNumber objects.
|
61
|
+
def fetch_records(first, last)
|
62
|
+
if first >= 0 && last >= 0 # all positive
|
63
|
+
positive_fetch(first, last)
|
64
|
+
elsif first < 0 && last >= 0# cross zero-boundary
|
65
|
+
# have to do half first and half last
|
66
|
+
negative_fetch(first, -1) + positive_fetch(0, last)
|
67
|
+
else # all negative
|
68
|
+
negative_fetch(first, last)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def positive_fetch(first, last)
|
73
|
+
StackviewCallNumber.where("sort_key >= ?", @origin_sort_key).
|
74
|
+
where(:sort_key_type => @sort_key_type).
|
75
|
+
order("sort_key ASC").
|
76
|
+
offset(first).limit(last - first + 1)
|
77
|
+
end
|
78
|
+
|
79
|
+
def negative_fetch(first, last)
|
80
|
+
StackviewCallNumber.where("sort_key < ?", @origin_sort_key).
|
81
|
+
where(:sort_key_type => @sort_key_type).
|
82
|
+
order("sort_key DESC").
|
83
|
+
offset(last.abs - 1).limit(last - first + 1).
|
84
|
+
reverse
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module RailsStackview
|
2
|
+
# A mock fetcher that just returns fake data, useful for testing, both manual and
|
3
|
+
# automated testing.
|
4
|
+
#
|
5
|
+
# Assumes 'loc_sort_order' style fetching, with query=[X TO Y] in params.
|
6
|
+
#
|
7
|
+
# Returns the designated number of records, with titles and other attributes
|
8
|
+
# including the 'i' index
|
9
|
+
class MockFetcher
|
10
|
+
def fetch(params)
|
11
|
+
first, last = RailsStackview.parse_query_range(params["query"])
|
12
|
+
|
13
|
+
return first.upto(last).collect do |i|
|
14
|
+
{
|
15
|
+
'title' => "item #{i}",
|
16
|
+
'system_id' => "doc_#{i}",
|
17
|
+
'creator' => ["author #{i}"],
|
18
|
+
'pub_date' => "2000",
|
19
|
+
'measurement_page_numeric' => rand(1..500),
|
20
|
+
'measurement_height_numeric' => ((25 + i*2) % 50),
|
21
|
+
'shelfrank' => ((i*10) % 100),
|
22
|
+
'link' => "http://example.org"
|
23
|
+
}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
<div class="shelfbrowser">
|
2
|
+
<%= content_tag "div",
|
3
|
+
{
|
4
|
+
:class => "shelfbrowser-browse-column",
|
5
|
+
:data => {
|
6
|
+
:stackview_browser_item_path => (respond_to?(:stackview_browser_item_path) ?
|
7
|
+
stackview_browser_item_path :
|
8
|
+
"")
|
9
|
+
}
|
10
|
+
} do %>
|
11
|
+
<%= content_tag "div", "",
|
12
|
+
:class => "shelfbrowser-stackview",
|
13
|
+
:data => {
|
14
|
+
:stackview_init => {
|
15
|
+
:id => 0,
|
16
|
+
:url => stackview_data_path(
|
17
|
+
local_assigns[:call_number_type] || "lc",
|
18
|
+
:origin_sort_key => "local_assigns[:origin_sort_key]"
|
19
|
+
),
|
20
|
+
:search_type => "loc_sort_order"
|
21
|
+
}
|
22
|
+
}
|
23
|
+
%>
|
24
|
+
<% end %>
|
25
|
+
|
26
|
+
<div class="shelfbrowser-info-column">
|
27
|
+
<div class="shelfbrowse-header">
|
28
|
+
<%# cheesy way to provide a 'back' button, our users requested it %>
|
29
|
+
<% if request.referer %>
|
30
|
+
<p class="shelfbrowser-back-btn">
|
31
|
+
<%= link_to "« Back to Catalog", request.referer %>
|
32
|
+
</p>
|
33
|
+
<% end %>
|
34
|
+
|
35
|
+
<h2>Virtual Shelf Browse!!!!!!!</h2>
|
36
|
+
</div>
|
37
|
+
|
38
|
+
<div class="stack-item-panel"></div>
|
39
|
+
</div>
|
40
|
+
|
41
|
+
</div>
|
42
|
+
|
data/config/routes.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
class CreateStackviewCallNumbers < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :stackview_call_numbers do |t|
|
4
|
+
# these are what we want to assemble items in a sequence,
|
5
|
+
t.string :sort_key, :null => false, :length => 100
|
6
|
+
t.string :sort_key_display
|
7
|
+
t.string :sort_key_type, :null => false, :length => 100
|
8
|
+
|
9
|
+
# and be able to link back to external systems
|
10
|
+
t.string :system_id, :null => false, :length => 100
|
11
|
+
|
12
|
+
|
13
|
+
# These are what stackview wants or can use
|
14
|
+
|
15
|
+
t.string :title, :null => false
|
16
|
+
t.string :creator
|
17
|
+
t.string :format
|
18
|
+
|
19
|
+
t.integer :measurement_page_numeric
|
20
|
+
t.integer :measurement_height_numeric
|
21
|
+
t.integer :shelfrank
|
22
|
+
|
23
|
+
t.string :pub_date
|
24
|
+
|
25
|
+
# record created_at for bookkeeping
|
26
|
+
|
27
|
+
t.column :created_at, :datetime
|
28
|
+
|
29
|
+
# indexes
|
30
|
+
t.index :system_id
|
31
|
+
t.index :sort_key
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "rails_stackview/engine"
|
2
|
+
|
3
|
+
module RailsStackview
|
4
|
+
|
5
|
+
|
6
|
+
# Utility methods
|
7
|
+
|
8
|
+
# Parses [XX TO YY] to ints.
|
9
|
+
#
|
10
|
+
# first, last = RailsStackview.parse_query_range("[-10 TO 50]")
|
11
|
+
# # first == -10 ; last == 50
|
12
|
+
#
|
13
|
+
# Raises an ArgumentError if input string isn't in expected format.
|
14
|
+
def self.parse_query_range(str)
|
15
|
+
unless str =~ /\[(\-?\d+) TO (\-?\d+)\]/
|
16
|
+
raise ArgumentError, "expect a query in the form `[\d+ TO \d+]`"
|
17
|
+
end
|
18
|
+
return [$1.to_i, $2.to_i]
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
class StackviewDataControllerTest < ActionController::TestCase
|
5
|
+
test "fetch with test adapter" do
|
6
|
+
get :fetch, :call_number_type => "test", :query => "[-5 TO 5]"
|
7
|
+
|
8
|
+
assert_response :success
|
9
|
+
assert_equal "application/json", response.content_type
|
10
|
+
|
11
|
+
parsed_response = JSON.parse( response.body )
|
12
|
+
|
13
|
+
assert_kind_of Array, (docs = parsed_response["docs"])
|
14
|
+
|
15
|
+
assert_equal 11, docs.length
|
16
|
+
end
|
17
|
+
|
18
|
+
test "configured :link filter" do
|
19
|
+
StackviewDataController.set_config_for_type("test",
|
20
|
+
:link => lambda do |hash|
|
21
|
+
"http://example.org/to_doc/#{hash['system_id']}"
|
22
|
+
end
|
23
|
+
)
|
24
|
+
|
25
|
+
get :fetch, :call_number_type => "test", :query => "[1 TO 10]"
|
26
|
+
|
27
|
+
docs = JSON.parse( response.body )["docs"]
|
28
|
+
|
29
|
+
docs.each do |doc|
|
30
|
+
assert_equal "http://example.org/to_doc/#{doc['system_id']}", doc['link']
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class StackviewDataControllerConfigTest < ActionController::TestCase
|
35
|
+
|
36
|
+
test "has and can look up config for `lc`" do
|
37
|
+
config = StackviewDataController.config_for_type('lc')
|
38
|
+
assert_present config
|
39
|
+
|
40
|
+
assert_present config[:fetch_adapter]
|
41
|
+
end
|
42
|
+
|
43
|
+
test "can set config" do
|
44
|
+
StackviewDataController.set_config_for_type("just_testing", :foo => :bar)
|
45
|
+
|
46
|
+
config = StackviewDataController.config_for_type('just_testing')
|
47
|
+
assert_present config
|
48
|
+
|
49
|
+
assert_equal :bar, config[:foo]
|
50
|
+
|
51
|
+
StackviewDataController.remove_config_for_type("just_testing")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
== README
|
2
|
+
|
3
|
+
This README would normally document whatever steps are necessary to get the
|
4
|
+
application up and running.
|
5
|
+
|
6
|
+
Things you may want to cover:
|
7
|
+
|
8
|
+
* Ruby version
|
9
|
+
|
10
|
+
* System dependencies
|
11
|
+
|
12
|
+
* Configuration
|
13
|
+
|
14
|
+
* Database creation
|
15
|
+
|
16
|
+
* Database initialization
|
17
|
+
|
18
|
+
* How to run the test suite
|
19
|
+
|
20
|
+
* Services (job queues, cache servers, search engines, etc.)
|
21
|
+
|
22
|
+
* Deployment instructions
|
23
|
+
|
24
|
+
* ...
|
25
|
+
|
26
|
+
|
27
|
+
Please feel free to use a different markup language if you do not plan to run
|
28
|
+
<tt>rake doc:app</tt>.
|
data/test/dummy/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.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_self
|
14
|
+
//
|
15
|
+
//= require jquery
|
16
|
+
//
|
17
|
+
//= require rails_stackview
|