carte-server 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1ad405840ee8644a09530f58b55f06d6577e7f47
4
- data.tar.gz: 02712abc98c52f3b2e84b721b6a09d921f3f0847
3
+ metadata.gz: 62e6b5113d7bafffdb2e35701cabd5a01ae26532
4
+ data.tar.gz: 8f4dd2dee37acd726a75e5c4477e5d7ec325e4ab
5
5
  SHA512:
6
- metadata.gz: 0880fb449f7b45ccd725f0d6688c9ce36eb988fdc919261e47fb57171a091701ecb47ad80f06558a190dc1d77912f8d33a3c31e77e3e43bdef56aec5f8ca1ee5
7
- data.tar.gz: 76cbdd005b7ea7b876dbf822f6e5f0c7eb27daf28e6a07316df3bb712600f2e1c18215492dcc92f8cd99216ef75d3781721ba846f1f458dd3db08076b42fc481
6
+ metadata.gz: af45cdb68b5f9de14cfc855e1199453ba0762f41bd6a781dd0e9f5db467f86713da9bd29f138d419e77b8d3bfbff7de045a30a972baf2f28b1631fdc9029853c
7
+ data.tar.gz: 015f9690877ab8a0f6ac5ca9f982b1774163ed38a9fef3fe237f02a516b1278403af5897a1d6f9e4f9113b6eb141030a84f94639b80dee25de4b13f3059fc299
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --format documentation --color
data/Rakefile CHANGED
@@ -1,49 +1,3 @@
1
1
  require "bundler/gem_tasks"
2
- require "carte/server"
2
+ require "carte/server/tasks"
3
3
  Carte::Server.configure { Mongoid.load!('mongoid.yml') }
4
- include Carte::Server::Models
5
-
6
- namespace :carte do
7
- desc 'analyze'
8
- task :analyze do
9
- title, content = {max: 0, min: 0}, {max: 0, min: 0}
10
- count = Hash.new(0)
11
- Card.all.each do |card|
12
- title[:max] = [card.title.length, title[:max]].max
13
- title[:min] = [card.title.length, title[:min]].min
14
- content[:max] = [card.content.length, content[:max]].max
15
- content[:min] = [card.content.length, content[:min]].min
16
- if card.content == ''
17
- puts "#{card.title} : content is empty"
18
- end
19
- count[card.title] += 1
20
- end
21
- puts "title: #{title}, content: #{content}"
22
- count.each do |card, count|
23
- puts "#{card}: #{count} items" if count != 1
24
- end
25
- end
26
-
27
- desc 'import fr.txt'
28
- task :import do
29
- entries = []
30
- file = File.open(ENV['FILE'])
31
- lines = file.read.split("\n")
32
- lines.each_slice(2) do |title, content|
33
- Card.create!(title: title, content: content)
34
- end
35
- end
36
-
37
- desc 'export'
38
- task :export do
39
- Card.all.each do |card|
40
- puts card.title
41
- puts card.content
42
- end
43
- end
44
-
45
- desc 'reset'
46
- task :reset do
47
- Card.delete_all
48
- end
49
- end
data/config.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
- "title": "carte sandbox",
3
- "description": "sandbox for carte",
2
+ "title": "Carte Sandbox",
3
+ "description": "Sandbox for Carte",
4
4
  "public_folder": "public",
5
5
  "script_path": "public/app.js",
6
- "link_color": "#2C21A6"
6
+ "link_color": "yellow"
7
7
  }
@@ -0,0 +1,4 @@
1
+
2
+ module.exports =
3
+ isMobile: ()->
4
+ /(iPhone|iPod|iPad).*AppleWebKit/i.test(navigator.userAgent)
@@ -1,4 +1,5 @@
1
1
  Backbone = require('backbone')
2
+ config = require('../../shared/config.json')
2
3
 
3
4
  module.exports = class Card extends Backbone.Model
4
5
  idAttribute: 'title'
@@ -10,10 +11,13 @@ module.exports = class Card extends Backbone.Model
10
11
  if @isNew()
11
12
  console.log @
12
13
  console.log 'url is new'
13
- '/api/cards.json'
14
+ url = '/api/cards.json'
14
15
  else
15
16
  console.log 'url is not new'
16
- '/api/cards/' + @get('title') + '.json'
17
+ url = '/api/cards/' + @get('title') + '.json'
18
+ if config.api_path
19
+ url = config.api_path + url
20
+ url
17
21
 
18
22
  parse: (response)->
19
23
  if response.card then response.card else response
@@ -1,12 +1,16 @@
1
1
  Backbone = require('backbone')
2
2
  CardModel = require('./card')
3
3
  $ = require('jquery')
4
+ config = require('../../shared/config.json')
4
5
 
5
6
  module.exports = class Cards extends Backbone.Collection
6
7
  model: CardModel
7
8
  query: {}
8
9
  url: ()->
9
- '/api/cards.json?' + $.param(@query)
10
+ url = '/api/cards.json?' + $.param(@query)
11
+ if config.api_path
12
+ url = config.api_path + url
13
+ url
10
14
  parse: (response)->
11
15
  console.log response
12
16
  @page = response.page
@@ -3,10 +3,10 @@ React = require('react')
3
3
  Edit = require('./edit')
4
4
  ModalTrigger = require('react-bootstrap/lib/ModalTrigger')
5
5
  markdownIt = require('markdown-it')(linkify: true)
6
+ helpers = require('../helpers')
6
7
 
7
8
  module.exports = React.createClass
8
9
  displayName: 'Card'
9
- isSafariOrUiWebView: /(iPhone|iPod|iPad).*AppleWebKit/i.test(navigator.userAgent)
10
10
 
11
11
  componentDidMount: ->
12
12
  @props.card.on 'change', @forceUpdate.bind(@, null)
@@ -38,7 +38,7 @@ module.exports = React.createClass
38
38
  <strong>
39
39
  {@props.card.get('title')}
40
40
  </strong>
41
- <span className='pull-right tools' style={{visibility: if @isSafariOrUiWebView || @state.showTools then 'visible' else 'hidden'}}>
41
+ <span className='pull-right tools' style={{visibility: if helpers.isMobile() || @state.showTools then 'visible' else 'hidden'}}>
42
42
  <ModalTrigger modal={<Edit card={@props.card} />}>
43
43
  <a href="javascript:void(0)">
44
44
  <i className='glyphicon glyphicon-edit' />
@@ -54,7 +54,7 @@ module.exports = React.createClass
54
54
  <div style={overflow:'hidden',width:'100%',height:'75%',wordWrap:'break-word'}>
55
55
  <div dangerouslySetInnerHTML={__html: markdownIt.render @props.card.get('content')} />
56
56
  </div>
57
- <div style={{visibility: if @isSafariOrUiWebView || @state.showTools then 'visible' else 'hidden'}}>
57
+ <div style={{visibility: if helpers.isMobile() || @state.showTools then 'visible' else 'hidden'}}>
58
58
  {
59
59
  if @props.card.get("tags")
60
60
  @props.card.get("tags").map (tag)->
@@ -3,6 +3,7 @@ React = require('react')
3
3
  List = require('./list')
4
4
  CardCollection = require('../models/cards')
5
5
  CardModel = require('../models/card')
6
+ String = require('string')
6
7
  config = require('../../shared/config.json')
7
8
 
8
9
  module.exports = React.createClass
@@ -31,7 +32,7 @@ module.exports = React.createClass
31
32
  title = []
32
33
  for k, v of cards.query
33
34
  if k != 'title'
34
- title.push(k + ': ' + v)
35
+ title.push(String(k).capitalize() + ': ' + v)
35
36
  title = title.join(', ')
36
37
  title = 'search: ' + cards.query.title + ' (' + title + ')' if cards.query.title
37
38
  title += ' - ' + config.title
@@ -36,7 +36,7 @@ module.exports = React.createClass
36
36
  <nav className="navbar navbar-default" style={{padding:"0px",backgroundColor:"white",marginBottom:"5px"}}>
37
37
  <div className="container-fluid">
38
38
  <div className="navbar-header">
39
- <a className="navbar-brand" href="#/" style={{paddingTop:"10px"}}>
39
+ <a className="navbar-brand" href={if config.icon_link then config.icon_link else "#/"} style={{paddingTop:"10px"}}>
40
40
  <img alt="Brand" src="/images/icon.png" width="30" height="30" />
41
41
  </a>
42
42
  <a className="navbar-brand" href="#/">
@@ -3,6 +3,8 @@ $ = require('jquery')
3
3
  React = require('react')
4
4
  Cards = require('./cards')
5
5
  CardCollection = require('../models/cards')
6
+ Pagination = require('./pagination')
7
+ helpers = require('../helpers')
6
8
 
7
9
  module.exports = React.createClass
8
10
  displayName: 'List'
@@ -33,11 +35,6 @@ module.exports = React.createClass
33
35
  delete query.page
34
36
  $.param(query)
35
37
 
36
- pageParam: (page)->
37
- query = $.extend {}, @props.cards.query
38
- query = $.extend query, {page: page}
39
- $.param(query)
40
-
41
38
  tagParam: (tag)->
42
39
  query = $.extend {}, @props.cards.query
43
40
  query = $.extend query, {tags: tag}
@@ -78,48 +75,7 @@ module.exports = React.createClass
78
75
  </li>
79
76
  </ul>
80
77
  else
81
- <ul className="nav nav-pills pull-right">
82
- <li>
83
- {
84
- if @props.cards.page
85
- if @props.cards.page.current > 1
86
- href = "/#/?" + @pageParam(@props.cards.page.current - 1)
87
- else
88
- href = "/#/?" + @pageParam(@props.cards.page.total)
89
- else
90
- href = "javascript:void(0)"
91
- <a href={href} aria-label="Previous" style={{padding:'6px 12px'}}>
92
- <span aria-hidden="true">&laquo;</span>
93
- </a>
94
- }
95
- </li>
96
- <li style={width:'4.0em',textAlign:'center'}>
97
- {
98
- if @props.cards.page
99
- <a href={"/#/?" + @pageParam(@props.cards.page.current)} style={{padding:'6px 12px'}}>
100
- {@props.cards.page.current} / {@props.cards.page.total}
101
- </a>
102
- else
103
- <a href="javascript:void(0)" style={{padding:'6px 12px'}}>
104
- <i className="glyphicon glyphicon-refresh glyphicon-refresh-animate" />
105
- </a>
106
- }
107
- </li>
108
- <li>
109
- {
110
- if @props.cards.page
111
- if @props.cards.page.current < @props.cards.page.total
112
- href = "/#/?" + @pageParam(@props.cards.page.current + 1)
113
- else
114
- href = "/#/?" + @pageParam(1)
115
- else
116
- href = "javascript:void(0)"
117
- <a href={href} aria-label="Next" style={{padding:'6px 12px'}}>
118
- <span aria-hidden="true">&raquo;</span>
119
- </a>
120
- }
121
- </li>
122
- </ul>
78
+ <Pagination cards={@props.cards} />
123
79
  }
124
80
  </div>
125
81
  </div>
@@ -133,4 +89,12 @@ module.exports = React.createClass
133
89
  </div>
134
90
  }
135
91
  <Cards cards={@props.cards} />
92
+ {
93
+ if !@props.card && helpers.isMobile()
94
+ <div className="row">
95
+ <div className="col-sm-12" style={{padding:"0px"}}>
96
+ <Pagination cards={@props.cards} />
97
+ </div>
98
+ </div>
99
+ }
136
100
  </div>
@@ -0,0 +1,55 @@
1
+ # @cjsx React.DOM
2
+ $ = require('jquery')
3
+ React = require('react')
4
+
5
+ module.exports = React.createClass
6
+ displayName: 'Pagination'
7
+
8
+ pageParam: (page)->
9
+ query = $.extend {}, @props.cards.query
10
+ query = $.extend query, {page: page}
11
+ $.param(query)
12
+
13
+ render: ->
14
+ <ul className="nav nav-pills pull-right">
15
+ <li>
16
+ {
17
+ if @props.cards.page
18
+ if @props.cards.page.current > 1
19
+ href = "/#/?" + @pageParam(@props.cards.page.current - 1)
20
+ else
21
+ href = "/#/?" + @pageParam(@props.cards.page.total)
22
+ else
23
+ href = "javascript:void(0)"
24
+ <a href={href} aria-label="Previous" style={{padding:'6px 12px'}}>
25
+ <span aria-hidden="true">&laquo;</span>
26
+ </a>
27
+ }
28
+ </li>
29
+ <li style={width:'4.0em',textAlign:'center'}>
30
+ {
31
+ if @props.cards.page
32
+ <a href={"/#/?" + @pageParam(@props.cards.page.current)} style={{padding:'6px 12px'}}>
33
+ {@props.cards.page.current} / {@props.cards.page.total}
34
+ </a>
35
+ else
36
+ <a href="javascript:void(0)" style={{padding:'6px 12px'}}>
37
+ <i className="glyphicon glyphicon-refresh glyphicon-refresh-animate" />
38
+ </a>
39
+ }
40
+ </li>
41
+ <li>
42
+ {
43
+ if @props.cards.page
44
+ if @props.cards.page.current < @props.cards.page.total
45
+ href = "/#/?" + @pageParam(@props.cards.page.current + 1)
46
+ else
47
+ href = "/#/?" + @pageParam(1)
48
+ else
49
+ href = "javascript:void(0)"
50
+ <a href={href} aria-label="Next" style={{padding:'6px 12px'}}>
51
+ <span aria-hidden="true">&raquo;</span>
52
+ </a>
53
+ }
54
+ </li>
55
+ </ul>
data/lib/carte/server.rb CHANGED
@@ -4,6 +4,7 @@ require 'mongoid'
4
4
  require 'mongoid_auto_increment_id'
5
5
  require 'will_paginate_mongoid'
6
6
  require 'mongoid-simple-tags'
7
+ require 'carte/server/validators'
7
8
  require 'carte/server/models'
8
9
 
9
10
  module Carte
@@ -22,6 +22,9 @@ module Carte
22
22
  validates :content,
23
23
  presence: true,
24
24
  length: {maximum: 560}
25
+ validates :tags,
26
+ length: {maximum: 3, message: 'are too many (maximum is 3 tags)'},
27
+ array: {length: {maximum: 10}}
25
28
 
26
29
  has_many :histories
27
30
 
@@ -0,0 +1,47 @@
1
+ require 'carte/server'
2
+ include Carte::Server::Models
3
+
4
+ namespace :carte do
5
+ desc 'analyze data'
6
+ task :analyze do
7
+ title, content = {max: 0, min: 0}, {max: 0, min: 0}
8
+ count = Hash.new(0)
9
+ Card.all.each do |card|
10
+ title[:max] = [card.title.length, title[:max]].max
11
+ title[:min] = [card.title.length, title[:min]].min
12
+ content[:max] = [card.content.length, content[:max]].max
13
+ content[:min] = [card.content.length, content[:min]].min
14
+ if card.content == ''
15
+ puts "#{card.title} : content is empty"
16
+ end
17
+ count[card.title] += 1
18
+ end
19
+ puts "title: #{title}, content: #{content}"
20
+ count.each do |title, count|
21
+ puts "duplicate: #{title}: #{count} items" if count != 1
22
+ end
23
+ end
24
+
25
+ desc 'import pdic one line format data'
26
+ task :import do
27
+ entries = []
28
+ file = File.open(ENV['FILE'])
29
+ lines = file.read.split("\n")
30
+ lines.each_slice(2) do |title, content|
31
+ Card.create!(title: title, content: content)
32
+ end
33
+ end
34
+
35
+ desc 'export data as pdic one line format'
36
+ task :export do
37
+ Card.all.each do |card|
38
+ puts card.title
39
+ puts card.content
40
+ end
41
+ end
42
+
43
+ desc 'reset database'
44
+ task :reset do
45
+ Card.delete_all
46
+ end
47
+ end
@@ -0,0 +1 @@
1
+ require 'carte/server/validators/array_validator'
@@ -0,0 +1,24 @@
1
+
2
+ class ArrayValidator < ActiveModel::EachValidator
3
+ def validate_each(record, attribute, values)
4
+ [values].flatten.each do |value|
5
+ options.each do |key, args|
6
+ validator_options = { attributes: attribute }
7
+ validator_options.merge!(args) if args.is_a?(Hash)
8
+
9
+ next if value.nil? && validator_options[:allow_nil]
10
+ next if value.blank? && validator_options[:allow_blank]
11
+
12
+ validator_class_name = "#{key.to_s.camelize}Validator"
13
+ validator_class = begin
14
+ validator_class_name.constantize
15
+ rescue NameError
16
+ "ActiveModel::Validations::#{validator_class_name}".constantize
17
+ end
18
+
19
+ validator = validator_class.new(validator_options)
20
+ validator.validate_each(record, attribute, value)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -2,6 +2,6 @@ require 'sinatra/base'
2
2
 
3
3
  module Carte
4
4
  class Server < Sinatra::Base
5
- VERSION = "0.0.7"
5
+ VERSION = "0.0.8"
6
6
  end
7
7
  end
data/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "carte-client",
3
3
  "description": "something like dictionary, wiki, or information card",
4
- "version": "0.0.7",
4
+ "version": "0.0.8",
5
5
  "main": "lib/carte.coffee",
6
6
  "scripts": {
7
7
  "test": "echo \"Error: no test specified\" && exit 1"
@@ -35,6 +35,7 @@
35
35
  "react": "^0.13.2",
36
36
  "react-bootstrap": "^0.21.0",
37
37
  "react-tagsinput": "^1.3.2",
38
+ "string": "^3.1.1",
38
39
  "vinyl-source-stream": "^1.1.0",
39
40
  "watchify": "^3.1.2"
40
41
  }
data/spec/server_spec.rb CHANGED
@@ -10,7 +10,7 @@ end
10
10
 
11
11
  class DictionaryClient
12
12
  include HTTParty
13
- base_uri 'http://localhost/api/'
13
+ base_uri 'http://localhost:9393/api/'
14
14
  format :json
15
15
  end
16
16
 
@@ -40,32 +40,44 @@ describe 'API' do
40
40
  it 'returns error when the title is not specified' do
41
41
  response = client.post('/cards.json', body: {content: 'content1'}.to_json)
42
42
  expect(response.code).to eq(400)
43
- expect(response['card']['errors']).to eq({'title' => ['が入力されていません']})
43
+ expect(response['card']['errors']).to eq({'title' => ["can't be blank"]})
44
44
  end
45
45
 
46
46
  it 'returns error when the content is not specified' do
47
47
  response = client.post('/cards.json', body: {title: 'card1'}.to_json)
48
48
  expect(response.code).to eq(400)
49
- expect(response['card']['errors']).to eq({'content' => ['が入力されていません']})
49
+ expect(response['card']['errors']).to eq({'content' => ["can't be blank"]})
50
50
  end
51
51
 
52
52
  it 'returns error when the title is not unique' do
53
53
  response = client.post('/cards.json', body: {title: 'card1', content: 'content1'}.to_json)
54
54
  response = client.post('/cards.json', body: {title: 'card1', content: 'content1'}.to_json)
55
55
  expect(response.code).to eq(400)
56
- expect(response['card']['errors']).to eq({'title' => ['は既に存在します']})
56
+ expect(response['card']['errors']).to eq({'title' => ['is already taken']})
57
57
  end
58
58
 
59
59
  it 'returns error when the title is too long' do
60
60
  response = client.post('/cards.json', body: {title: 'w' * 71, content: 'content1'}.to_json)
61
61
  expect(response.code).to eq(400)
62
- expect(response['card']['errors']).to eq({'title' => [' 70 文字以内で入力してください']})
62
+ expect(response['card']['errors']).to eq({'title' => ['is too long (maximum is 70 characters)']})
63
63
  end
64
64
 
65
65
  it 'returns error when the content is too long' do
66
66
  response = client.post('/cards.json', body: {title: 'card1', content: 'd' * 561}.to_json)
67
67
  expect(response.code).to eq(400)
68
- expect(response['card']['errors']).to eq({'content' => [' 560 文字以内で入力してください']})
68
+ expect(response['card']['errors']).to eq({'content' => ['is too long (maximum is 560 characters)']})
69
+ end
70
+
71
+ it 'returns error when the tags is too many' do
72
+ response = client.post('/cards.json', body: {title: 'card1', content: 'content1', tags: %w(tag1 tag2 tag3 tag4)}.to_json)
73
+ expect(response.code).to eq(400)
74
+ expect(response['card']['errors']).to eq({'tags' => ['are too many (maximum is 3 tags)']})
75
+ end
76
+
77
+ it 'returns error when one of the tags is too long' do
78
+ response = client.post('/cards.json', body: {title: 'card1', content: 'content1', tags: ['a' * 11]}.to_json)
79
+ expect(response.code).to eq(400)
80
+ expect(response['card']['errors']).to eq({'tags' => ['is too long (maximum is 10 characters)']})
69
81
  end
70
82
  end
71
83
  end
@@ -126,21 +138,35 @@ describe 'API' do
126
138
  response = client.post('/cards.json', body: {title: 'card2', content: 'content2'}.to_json)
127
139
  response = client.put("/cards/card2.json", body: {new_title: 'card1', content: 'content1'}.to_json)
128
140
  expect(response.code).to eq(400)
129
- expect(response['card']['errors']).to eq({'title' => ['は既に存在します']})
141
+ expect(response['card']['errors']).to eq({'title' => ['is already taken']})
130
142
  end
131
143
 
132
144
  it 'returns error when the title is too long' do
133
145
  response = client.post('/cards.json', body: {title: 'card1', content: 'content1'}.to_json)
134
146
  response = client.put("/cards/card1.json", body: {new_title: 'w' * 71}.to_json)
135
147
  expect(response.code).to eq(400)
136
- expect(response['card']['errors']).to eq({'title' => [' 70 文字以内で入力してください']})
148
+ expect(response['card']['errors']).to eq({'title' => ['is too long (maximum is 70 characters)']})
137
149
  end
138
150
 
139
151
  it 'returns error when the content is too long' do
140
152
  response = client.post('/cards.json', body: {title: 'card1', content: 'content1'}.to_json)
141
153
  response = client.put("/cards/card1.json", body: {content: 'd' * 561}.to_json)
142
154
  expect(response.code).to eq(400)
143
- expect(response['card']['errors']).to eq({'content' => [' 560 文字以内で入力してください']})
155
+ expect(response['card']['errors']).to eq({'content' => ['is too long (maximum is 560 characters)']})
156
+ end
157
+
158
+ it 'returns error when the tags is too many' do
159
+ response = client.post('/cards.json', body: {title: 'card1', content: 'content1'}.to_json)
160
+ response = client.put("/cards/card1.json", body: {tags: %w(tag1 tag2 tag3 tag4)}.to_json)
161
+ expect(response.code).to eq(400)
162
+ expect(response['card']['errors']).to eq({'tags' => ['are too many (maximum is 3 tags)']})
163
+ end
164
+
165
+ it 'returns error when one of the tags is too long' do
166
+ response = client.post('/cards.json', body: {title: 'card1', content: 'content1'}.to_json)
167
+ response = client.put("/cards/card1.json", body: {tags: ['a' * 11]}.to_json)
168
+ expect(response.code).to eq(400)
169
+ expect(response['card']['errors']).to eq({'tags' => ['is too long (maximum is 10 characters)']})
144
170
  end
145
171
  end
146
172
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: carte-server
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - tily
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-02 00:00:00.000000000 Z
11
+ date: 2015-05-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -200,6 +200,7 @@ extensions: []
200
200
  extra_rdoc_files: []
201
201
  files:
202
202
  - .gitignore
203
+ - .rspec
203
204
  - Gemfile
204
205
  - LICENSE.txt
205
206
  - README.md
@@ -211,6 +212,7 @@ files:
211
212
  - lib/carte.coffee
212
213
  - lib/carte.rb
213
214
  - lib/carte/client.coffee
215
+ - lib/carte/client/helpers.coffee
214
216
  - lib/carte/client/models/card.coffee
215
217
  - lib/carte/client/models/cards.coffee
216
218
  - lib/carte/client/router.coffee
@@ -222,10 +224,14 @@ files:
222
224
  - lib/carte/client/views/footer.cjsx
223
225
  - lib/carte/client/views/header.cjsx
224
226
  - lib/carte/client/views/list.cjsx
227
+ - lib/carte/client/views/pagination.cjsx
225
228
  - lib/carte/server.rb
226
229
  - lib/carte/server/models.rb
227
230
  - lib/carte/server/models/card.rb
228
231
  - lib/carte/server/models/history.rb
232
+ - lib/carte/server/tasks.rb
233
+ - lib/carte/server/validators.rb
234
+ - lib/carte/server/validators/array_validator.rb
229
235
  - lib/carte/server/version.rb
230
236
  - lib/carte/server/views/cards.builder
231
237
  - lib/carte/server/views/index.haml