volt-table 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +8 -0
- data/Guardfile +24 -0
- data/LICENSE.txt +22 -0
- data/README.md +134 -0
- data/Rakefile +1 -0
- data/app/table/assets/css/font-awesome.min.css +4 -0
- data/app/table/assets/css/main.scss +66 -0
- data/app/table/assets/fonts/FontAwesome.otf +0 -0
- data/app/table/assets/fonts/fontawesome-webfont.eot +0 -0
- data/app/table/assets/fonts/fontawesome-webfont.svg +655 -0
- data/app/table/assets/fonts/fontawesome-webfont.ttf +0 -0
- data/app/table/assets/fonts/fontawesome-webfont.woff +0 -0
- data/app/table/assets/fonts/fontawesome-webfont.woff2 +0 -0
- data/app/table/config/dependencies.rb +1 -0
- data/app/table/config/initializers/boot.rb +10 -0
- data/app/table/config/routes.rb +1 -0
- data/app/table/controllers/columns_controller.rb +101 -0
- data/app/table/controllers/footers_controller.rb +19 -0
- data/app/table/controllers/headers_controller.rb +98 -0
- data/app/table/controllers/main_controller.rb +135 -0
- data/app/table/tasks/count_task.rb +15 -0
- data/app/table/views/columns/column_head.html +4 -0
- data/app/table/views/columns/filter_head.html +36 -0
- data/app/table/views/columns/index.html +17 -0
- data/app/table/views/footers/index.html +14 -0
- data/app/table/views/headers/index.html +62 -0
- data/app/table/views/headers/modal.html +34 -0
- data/app/table/views/main/body.html +26 -0
- data/app/table/views/main/footers.html +1 -0
- data/app/table/views/main/index.html +7 -0
- data/app/table/views/wrapper/index.html +10 -0
- data/lib/volt/table.rb +18 -0
- data/lib/volt/table/version.rb +5 -0
- data/spec/dummy/.gitignore +9 -0
- data/spec/dummy/README.md +4 -0
- data/spec/dummy/app/main/assets/css/app.css.scss +1 -0
- data/spec/dummy/app/main/config/dependencies.rb +13 -0
- data/spec/dummy/app/main/config/initializers/boot.rb +10 -0
- data/spec/dummy/app/main/config/routes.rb +14 -0
- data/spec/dummy/app/main/controllers/main_controller.rb +67 -0
- data/spec/dummy/app/main/lib/seed_db.rb +32 -0
- data/spec/dummy/app/main/models/user.rb +15 -0
- data/spec/dummy/app/main/views/main/about.html +16 -0
- data/spec/dummy/app/main/views/main/index.html +25 -0
- data/spec/dummy/app/main/views/main/main.html +29 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/app.rb +137 -0
- data/spec/dummy/config/base/index.html +15 -0
- data/spec/dummy/config/initializers/boot.rb +4 -0
- data/spec/factories.rb +31 -0
- data/spec/integration/table_integration_spec.rb +171 -0
- data/spec/spec_helper.rb +19 -0
- data/volt-table.gemspec +46 -0
- metadata +399 -0
@@ -0,0 +1,14 @@
|
|
1
|
+
<:Body>
|
2
|
+
<div class="row">
|
3
|
+
<div class="col-xs-12 col-sm-9">
|
4
|
+
<:pagination total="{{ attrs.table_size }}" per_page="{{ params._per_page }}" />
|
5
|
+
</div>
|
6
|
+
<div class="col-xs-12 col-sm-3 col-md-3 col-lg-3 infoBar" style="padding-left:0px;">
|
7
|
+
<div class="infos">
|
8
|
+
Showing {{ start_offset+1 }} - {{ last_item }} of {{ attrs.table_size }}
|
9
|
+
<div>
|
10
|
+
<small>Filtered from a total of {{ attrs.total_size }}</small>
|
11
|
+
</div>
|
12
|
+
</div>
|
13
|
+
</div>
|
14
|
+
</div>
|
@@ -0,0 +1,62 @@
|
|
1
|
+
<:Body>
|
2
|
+
<div class="row table-toolbar">
|
3
|
+
<div class="col-sm-12">
|
4
|
+
<div class="input-group">
|
5
|
+
<div class="input-group">
|
6
|
+
<span e-click="toggle_popover" class="fa fa-search input-group-addon">
|
7
|
+
<div class="popover fade right in" role="tooltip" id="popover">
|
8
|
+
<div class="arrow" style="top: 75px"></div>
|
9
|
+
<h3 class="popover-title">Search Help</h3>
|
10
|
+
<div class="popover-content">
|
11
|
+
<b>' | '</b> - or <br />
|
12
|
+
<b>', '</b> - and<br>
|
13
|
+
{{ search_fields.each do |field| }}
|
14
|
+
<b>{{ field['search'] }}:</b> {{field['title']}}<br>
|
15
|
+
{{ end }}
|
16
|
+
</div>
|
17
|
+
</div>
|
18
|
+
</span>
|
19
|
+
<input type="text" class="form-control" placeholder="Search" value="{{ search_term }}" e-keyup="search">
|
20
|
+
</div>
|
21
|
+
<div class="input-group-btn">
|
22
|
+
<button type="button" class="btn btn-default btn-left" e-click="clear_filters">Clear All Filters</button>
|
23
|
+
</div>
|
24
|
+
<div class="input-group-btn">
|
25
|
+
<button type="button" class="btn btn-default btn-middle dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
26
|
+
Show {{ params._per_page }}
|
27
|
+
<span class="caret"></span>
|
28
|
+
</button>
|
29
|
+
<ul class="dropdown-menu dropdown-menu-right">
|
30
|
+
<li class="{{ if size == 10 }} active {{ end }}"><a href="#" e-click="set_table_size(10)">10</a></li>
|
31
|
+
<li class="{{ if size == 25 }} active {{ end }}"><a href="#" e-click="set_table_size(25)">25</a></li>
|
32
|
+
<li class="{{ if size == 50 }} active {{ end }}"><a href="#" e-click="set_table_size(50)">50</a></li>
|
33
|
+
</ul>
|
34
|
+
</div>
|
35
|
+
<!-- /input-group-btn -->
|
36
|
+
<div class="input-group-btn">
|
37
|
+
<button type="button" id="fields_shown" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
38
|
+
<span class="fa fa-list"></span>
|
39
|
+
<span class="caret"></span>
|
40
|
+
</button>
|
41
|
+
<ul id="fields_shown_list" class="dropdown-menu dropdown-menu-right">
|
42
|
+
{{ page._table._columns.each do |field| }}
|
43
|
+
{{ if field.key?('title') }}
|
44
|
+
<li>
|
45
|
+
<div class="checkbox">
|
46
|
+
<label class="dropdown-item">
|
47
|
+
<input name="shown_fields" type="checkbox" class="dropdown-item-checkbox" checked="{{ field._shown }}">
|
48
|
+
{{ field._title }}
|
49
|
+
</label>
|
50
|
+
</div>
|
51
|
+
</li>
|
52
|
+
{{ end }}
|
53
|
+
{{ end }}
|
54
|
+
</ul>
|
55
|
+
</div>
|
56
|
+
<!-- /btn-group -->
|
57
|
+
</div>
|
58
|
+
<!-- /input-group -->
|
59
|
+
</div>
|
60
|
+
<!-- /.col-lg-6 -->
|
61
|
+
</div>
|
62
|
+
<!-- /.row -->
|
@@ -0,0 +1,34 @@
|
|
1
|
+
<:Body>
|
2
|
+
<div class="modal fade" id="sortModal">
|
3
|
+
<div class="modal-dialog modal-md">
|
4
|
+
<div class="modal-content">
|
5
|
+
<div class="modal-header">
|
6
|
+
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
7
|
+
<h4 class="modal-title">Sort and Filter</h4>
|
8
|
+
</div>
|
9
|
+
<div class="modal-body">
|
10
|
+
{{ search_fields.each_with_index do |field, i| }}
|
11
|
+
<div class="row">
|
12
|
+
<div class="col-xs-3">
|
13
|
+
{{ field['title'] }}
|
14
|
+
</div>
|
15
|
+
<div class="col-xs-9">
|
16
|
+
<div class="col-sm-6">
|
17
|
+
<!-- <:fields:select value="{{ options[i] }}" label=false options="{{ [{label:'Greater Than', value:'$gt'}, {label:'Less Than', value:'$lt'}, {label:'Not Equal to', value:'$ne'}] }}" /> -->
|
18
|
+
</div>
|
19
|
+
<div class="col-sm-6">
|
20
|
+
<!-- <:fields:text value="{{ values[i] }}" label=false /> -->
|
21
|
+
</div>
|
22
|
+
</div>
|
23
|
+
</div>
|
24
|
+
{{ end }}
|
25
|
+
</div>
|
26
|
+
<div class="modal-footer">
|
27
|
+
<div align="center">
|
28
|
+
<button class="btn btn-default" data-dismiss="modal" style="margin-right:20px">Cancel</button>
|
29
|
+
<button class="btn btn-default" e-click="modal" style="margin-right:20px">Clear Filters</button>
|
30
|
+
<button class="btn btn-primary" e-click="apply_filters" style="margin-right:20px">Apply</button>
|
31
|
+
</div>
|
32
|
+
</div>
|
33
|
+
</div>
|
34
|
+
</div>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<:Body>
|
2
|
+
<tbody>
|
3
|
+
{{ unless current_page.loaded? }}
|
4
|
+
<tr>
|
5
|
+
<td class="loading" colspan="{{ page._table._columns.size }}">
|
6
|
+
Loading...
|
7
|
+
Someone please make me pretty!
|
8
|
+
</td>
|
9
|
+
</tr>
|
10
|
+
{{ end }}
|
11
|
+
{{ if false }}
|
12
|
+
{{ yield }}
|
13
|
+
{{ else }}
|
14
|
+
{{ current_page.each do |data| }}
|
15
|
+
<tr>
|
16
|
+
{{ page._table._columns.each_with_index do |item, index| }}
|
17
|
+
{{ if item._shown }}
|
18
|
+
<td e-click="td_click(data.id, index)" class="{{ if params._sort_field == item._sort_name }} selected_body {{ end }}">
|
19
|
+
{{ raw(data.send(item._field_name)) }}
|
20
|
+
</td>
|
21
|
+
{{ end }}
|
22
|
+
{{ end }}
|
23
|
+
</tr>
|
24
|
+
{{ end }}
|
25
|
+
{{ end }}
|
26
|
+
</tbody>
|
@@ -0,0 +1 @@
|
|
1
|
+
<:table:footers table_size="{{ table_size }}" total_size="{{ total_size }}" />
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<:Body>
|
2
|
+
<:table:headers/>
|
3
|
+
<:table:wrapper>
|
4
|
+
<:table:columns />
|
5
|
+
<:table:main:body source="{{ attrs.source }}" source_name="{{ attrs.source_name }}"/>
|
6
|
+
</:table:wrapper>
|
7
|
+
<:table:footers table_size="{{ table_size }}" source_name="{{ attrs.source_name }}" total_size="{{ total_size }}"/>
|
data/lib/volt/table.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# If you need to require in code in the gem's app folder, keep in mind that
|
2
|
+
# the app is not on the load path when the gem is required. Use
|
3
|
+
# app/{gemname}/config/initializers/boot.rb to require in client or server
|
4
|
+
# code.
|
5
|
+
#
|
6
|
+
# Also, in volt apps, you typically use the lib folder in the
|
7
|
+
# app/{componentname} folder instead of this lib folder. This lib folder is
|
8
|
+
# for setting up gem code when Bundler.require is called. (or the gem is
|
9
|
+
# required.)
|
10
|
+
#
|
11
|
+
# If you need to configure volt in some way, you can add a Volt.configure block
|
12
|
+
# in this file.
|
13
|
+
|
14
|
+
module Volt
|
15
|
+
module Table
|
16
|
+
# Your code goes here...
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
// Place your apps css here
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# Specify which components you wish to include when
|
2
|
+
# the "home" component loads.
|
3
|
+
|
4
|
+
# bootstrap css framework
|
5
|
+
component 'bootstrap'
|
6
|
+
|
7
|
+
# a default theme for the bootstrap framework
|
8
|
+
component 'bootstrap_jumbotron_theme'
|
9
|
+
|
10
|
+
# provides templates for login, signup, and logout
|
11
|
+
component 'user_templates'
|
12
|
+
component 'pagination'
|
13
|
+
component 'table'
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# Place any code you want to run when the component is included on the client
|
2
|
+
# or server.
|
3
|
+
|
4
|
+
# To include code only on the client use:
|
5
|
+
# if RUBY_PLATFORM == 'opal'
|
6
|
+
#
|
7
|
+
# To include code only on the server, use:
|
8
|
+
# unless RUBY_PLATFORM == 'opal'
|
9
|
+
# ^^ this will not send compile in code in the conditional to the client.
|
10
|
+
# ^^ this include code required in the conditional.
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# See https://github.com/voltrb/volt#routes for more info on routes
|
2
|
+
|
3
|
+
client '/about', action: 'about'
|
4
|
+
|
5
|
+
# Routes for login and signup, provided by user_templates component gem
|
6
|
+
client '/signup', component: 'user_templates', controller: 'signup'
|
7
|
+
client '/login', component: 'user_templates', controller: 'login', action: 'index'
|
8
|
+
client '/password_reset', component: 'user_templates', controller: 'password_reset', action: 'index'
|
9
|
+
client '/forgot', component: 'user_templates', controller: 'login', action: 'forgot'
|
10
|
+
client '/account', component: 'user_templates', controller: 'account', action: 'index'
|
11
|
+
|
12
|
+
# The main route, this should be last. It will match any params not
|
13
|
+
# previously matched.
|
14
|
+
client '/', {}
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# By default Volt generates this controller for your Main component
|
2
|
+
module Main
|
3
|
+
class MainController < Volt::ModelController
|
4
|
+
before_action :set_default_table_options, only: :index
|
5
|
+
before_action :set_default_table2_options, only: :about
|
6
|
+
|
7
|
+
def index
|
8
|
+
# Add code for when the index view is loaded
|
9
|
+
end
|
10
|
+
|
11
|
+
def about
|
12
|
+
# Add code for when the about view is loaded
|
13
|
+
end
|
14
|
+
|
15
|
+
def set_default_table_options
|
16
|
+
params._sort_field ||= "last_name"
|
17
|
+
params._sort_direction ||= 1
|
18
|
+
page._table = {
|
19
|
+
default_click_event: 'user_click',
|
20
|
+
columns: [
|
21
|
+
{title: "First Name", search_field: 'first', field_name: 'first_name', sort_name: 'first_name', shown: true},
|
22
|
+
{title: "Last Name", search_field: 'last', field_name: 'last_name', sort_name: 'last_name', shown: true},
|
23
|
+
{title: "Email", search_field: 'email', field_name: 'email', sort_name: 'email', click_event: 'email_click', shown: true},
|
24
|
+
]
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
def set_default_table2_options
|
29
|
+
params._sort_field ||= "last_name"
|
30
|
+
params._sort_direction ||= 1
|
31
|
+
page._table = {
|
32
|
+
columns: [
|
33
|
+
{title: "First Name", search_field: 'first', field_name: 'first_name', sort_name: 'first_name', shown: true},
|
34
|
+
{title: "Last Name", search_field: 'last', field_name: 'last_name', sort_name: 'last_name', shown: true},
|
35
|
+
{title: "Email", search_field: 'email', field_name: 'email', sort_name: 'email', shown: true},
|
36
|
+
]
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
def all_users
|
41
|
+
store.users.all
|
42
|
+
end
|
43
|
+
|
44
|
+
def show_user_detail(id)
|
45
|
+
puts id
|
46
|
+
end
|
47
|
+
|
48
|
+
def show_email(id)
|
49
|
+
puts "email of :#{id}"
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
# The main template contains a #template binding that shows another
|
55
|
+
# template. This is the path to that template. It may change based
|
56
|
+
# on the params._component, params._controller, and params._action values.
|
57
|
+
def main_path
|
58
|
+
"#{params._component || 'main'}/#{params._controller || 'main'}/#{params._action || 'index'}"
|
59
|
+
end
|
60
|
+
|
61
|
+
# Determine if the current nav component is the active one by looking
|
62
|
+
# at the first part of the url against the href attribute.
|
63
|
+
def active_tab?
|
64
|
+
url.path.split('/')[1] == attrs.href.split('/')[1]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require_relative '../../../../factories'
|
2
|
+
require 'ruby-progressbar'
|
3
|
+
|
4
|
+
num_users = 50
|
5
|
+
|
6
|
+
progressbar = ProgressBar.create
|
7
|
+
progressbar.total = 6 + num_users
|
8
|
+
|
9
|
+
#create Custom Users, used for testing
|
10
|
+
|
11
|
+
|
12
|
+
# Create several more users
|
13
|
+
# steps = num_users
|
14
|
+
Factories.custom_user({method: :save}, 'Bob', 'Smith')
|
15
|
+
progressbar.increment
|
16
|
+
|
17
|
+
Factories.custom_user({method: :save}, 'Jerry', 'Smith')
|
18
|
+
progressbar.increment
|
19
|
+
|
20
|
+
Factories.custom_user({method: :save}, 'Bob', 'Barker')
|
21
|
+
progressbar.increment
|
22
|
+
|
23
|
+
Factories.custom_user({method: :save}, 'Jerry', 'Sienfeld')
|
24
|
+
progressbar.increment
|
25
|
+
|
26
|
+
Factories.custom_user({method: :save}, 'Mary', 'Joe')
|
27
|
+
progressbar.increment
|
28
|
+
|
29
|
+
num_users.times do
|
30
|
+
Factories.user({method: :save})
|
31
|
+
progressbar.increment
|
32
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# By default Volt generates this User model which inherits from Volt::User,
|
2
|
+
# you can rename this if you want.
|
3
|
+
class User < Volt::User
|
4
|
+
# login_field is set to :email by default and can be changed to :username
|
5
|
+
# in config/app.rb
|
6
|
+
# ROLES = ['admin', 'student', 'teacher', 'TA']
|
7
|
+
|
8
|
+
field login_field
|
9
|
+
field :first_name
|
10
|
+
field :last_name
|
11
|
+
|
12
|
+
validate login_field, unique: true, length: 8
|
13
|
+
validate :email, email: true
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<:Title>
|
2
|
+
About
|
3
|
+
|
4
|
+
<:Body>
|
5
|
+
<h1>Table no wrapper</h1>
|
6
|
+
<div class="row">
|
7
|
+
<div class="col-md-12">
|
8
|
+
<div class="panel panel-primary">
|
9
|
+
<div class="panel-heading">Users Table
|
10
|
+
</div>
|
11
|
+
<div class="panel-body">
|
12
|
+
<:table source="{{ all_users }}" source_name="users"/>
|
13
|
+
</div>
|
14
|
+
</div>
|
15
|
+
</div>
|
16
|
+
</div>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<:Title>
|
2
|
+
Home
|
3
|
+
|
4
|
+
<:Body>
|
5
|
+
<h1>Table with Wrapper</h1>
|
6
|
+
<div class="row">
|
7
|
+
<div class="col-md-12">
|
8
|
+
<div class="panel panel-primary">
|
9
|
+
<div class="panel-heading">Users Table
|
10
|
+
</div>
|
11
|
+
<div class="panel-body">
|
12
|
+
<div class="row">
|
13
|
+
<div class="col-xs-12">
|
14
|
+
<:table:headers />
|
15
|
+
</div>
|
16
|
+
</div>
|
17
|
+
<:table:wrapper>
|
18
|
+
<:table:columns />
|
19
|
+
<:table:main:body source="{{ all_users }}" e-user_click="show_user_detail" e-email_click="show_email"/>
|
20
|
+
</:table:wrapper>
|
21
|
+
<:table:main:footers source="{{ all_users }}" />
|
22
|
+
</div>
|
23
|
+
</div>
|
24
|
+
</div>
|
25
|
+
</div>
|
@@ -0,0 +1,29 @@
|
|
1
|
+
<:Title>
|
2
|
+
{{ view main_path, "title", {controller_group: 'main'} }}
|
3
|
+
|
4
|
+
<:Body>
|
5
|
+
<div class="container">
|
6
|
+
<div class="header">
|
7
|
+
<ul class="nav nav-pills pull-right">
|
8
|
+
<:nav href="/">Home</:nav>
|
9
|
+
<:nav href="/about">About</:nav>
|
10
|
+
<:user_templates:menu />
|
11
|
+
</ul>
|
12
|
+
<h3 class="text-muted">dummy</h3>
|
13
|
+
</div>
|
14
|
+
|
15
|
+
<:volt:notices />
|
16
|
+
|
17
|
+
{{ view main_path, 'body', {controller_group: 'main'} }}
|
18
|
+
|
19
|
+
<div class="footer">
|
20
|
+
<p>© Company {{ Time.now.year }}</p>
|
21
|
+
</div>
|
22
|
+
|
23
|
+
</div>
|
24
|
+
|
25
|
+
<:Nav>
|
26
|
+
<li class="{{ if active_tab? }}active{{ end }}">
|
27
|
+
<a href="{{ attrs.href }}">{{ yield }}</a>
|
28
|
+
</li>
|
29
|
+
|