carte-server 1.0.8 → 1.0.9

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 10e4c87356c4d71772d5534102215a6ebee7bfa6
4
- data.tar.gz: dd8e7c1fd85b46173178451cd93c113bec50f86f
3
+ metadata.gz: cd3f472fe4bb7d487fcdaed6f4ac9d6e4fcc55ae
4
+ data.tar.gz: c52db06dafe184f6a745ce5c678be0603b38e581
5
5
  SHA512:
6
- metadata.gz: 16593c18c820bc4a76eae61d999daf1fe18ec8b4f6d6d8f5f17846dda80e26c4e370efc770ccf6c0b885c1a6ab25cacd0b7f2de9ca44ea3a3c407f55ec58497c
7
- data.tar.gz: e9b46b510b2a640e17a2390f0a1e79f5fe9626bf0f6eee9c8637958031908716511a3db7fbe19e4689680bd2d776484371724fa059e141d8435863ae6fe6c50c
6
+ metadata.gz: 14e3089137ea1bd9b1048eb573679eb85f5d5117f6de0eccabff4acf27d8c6590a6816db20877edef2e424c99e6743107ffe9294076808f74628f64ec2350b92
7
+ data.tar.gz: 3cac1e649934df4c691bc351325b0eaf3d91ed0d9305c1fba54afdcda896334472351d4a7db0da650cf1804945e9ab85bc0f53d884830cf05e8c4e0bae6d04d6
@@ -0,0 +1,9 @@
1
+ Backbone = require('backbone')
2
+ config = require('../config')
3
+ querystring = require('querystring')
4
+ $ = require('jquery')
5
+
6
+ module.exports = class Tag extends Backbone.Model
7
+ modelName: 'Tag'
8
+ idAttribute: 'name'
9
+ url: ()-> config.root_path + config.api_path + '/tags/' + encodeURIComponent(@get('name')) + '.json'
@@ -0,0 +1,10 @@
1
+ Backbone = require('backbone')
2
+ Tag = require('./tag')
3
+ $ = require('jquery')
4
+ config = require('../config')
5
+
6
+ module.exports = class Tags extends Backbone.Collection
7
+ collectionName: 'Tags'
8
+ model: Tag
9
+ url: config.root_path + config.api_path + '/tags.json'
10
+ parse: (response)-> response.tags
@@ -3,10 +3,15 @@ Backbone = require('backbone')
3
3
 
4
4
  module.exports = class Router extends Backbone.Router
5
5
  routes:
6
+ 'tags': 'tags'
6
7
  '': 'list'
7
8
  ':title': 'show'
8
9
  ':title/history': 'history'
9
10
 
11
+ tags: ->
12
+ console.log '[router] tags'
13
+ @current = 'tags'
14
+
10
15
  list: (string)->
11
16
  console.log '[router] list', string
12
17
  location.hash = '/' if location.hash == ''
@@ -2,10 +2,12 @@
2
2
  $ = require('jquery')
3
3
  React = require('react')
4
4
  List = require('./list')
5
+ Tags = require('./tags')
5
6
  Slideshow = require('./slideshow')
6
7
  CardCollection = require('../models/cards')
7
8
  CardHistoryCollection = require('../models/card_histories')
8
9
  CardModel = require('../models/card')
10
+ TagCollection = require('../models/tags')
9
11
  String = require('string')
10
12
  config = require('../config')
11
13
 
@@ -73,6 +75,13 @@ module.exports = React.createClass
73
75
  cards.fetch success: ()-> cards.fetching = false
74
76
  document.title = config.title + '、ヒストリー'
75
77
  <List key='list' router={@props.router} cards={cards} />
78
+ when "tags"
79
+ console.log '[views/content] tags', @props
80
+ tags = new TagCollection()
81
+ tags.fetching = true
82
+ tags.fetch success: ()-> tags.fetching = false
83
+ document.title = config.title + '、タグ一覧'
84
+ <Tags tags={tags} />
76
85
  else
77
86
  null
78
87
  }
@@ -53,7 +53,7 @@ module.exports = React.createClass
53
53
  else
54
54
  @props.onRequestHide()
55
55
  @props.card.set 'title', @state.title
56
- location.hash = '/' + @state.title
56
+ location.hash = '/' + encodeURIComponent(@state.title)
57
57
  else
58
58
  @props.onRequestHide()
59
59
  @props.card = new CardModel()
@@ -0,0 +1,66 @@
1
+ # @cjsx React.DOM
2
+ $ = require('jquery')
3
+ React = require('react/addons')
4
+ Modal = require('react-bootstrap/lib/Modal')
5
+ Button = require('react-bootstrap/lib/Button')
6
+
7
+ module.exports = React.createClass
8
+ mixins: [React.addons.LinkedStateMixin]
9
+
10
+ displayName: 'EditTag'
11
+
12
+ getInitialState: ()->
13
+ updating: false
14
+ name: @props.tag.get('name')
15
+ errors: false
16
+ shaking: false
17
+
18
+ onChangeName: (event)->
19
+ @setState name: event.target.value
20
+
21
+ onClickOk: (event)->
22
+ event.preventDefault()
23
+ @setState updating: true
24
+ attributes = {new_name: @state.name}
25
+ @props.tag.save attributes,
26
+ success: ()=>
27
+ @props.tag.set 'name', @state.name
28
+ @props.onRequestHide()
29
+ error: (model, response, options)=>
30
+ @setState errors: response.responseJSON.tag.errors
31
+ @setState updating: false
32
+ @setState shaking: true
33
+ setTimeout (=> @setState shaking: false), 300
34
+
35
+ render: ->
36
+ <Modal className={"animated infinite shake" if @state.shaking} {...@props} bsStyle='default' title={<i className="glyphicon glyphicon-edit" />} animation={false}>
37
+ <div className='modal-body'>
38
+ {
39
+ if @state.errors
40
+ <div className="alert alert-danger" role="alert">
41
+ <ul>
42
+ {
43
+ for key, errors of @state.errors
44
+ for error in errors
45
+ <li>{key + ' ' + error}</li>
46
+ }
47
+ </ul>
48
+ </div>
49
+ }
50
+ <div className="form-group">
51
+ <label className="control-label">Name</label>
52
+ <input type="text" className="form-control" value={@state.name} onChange={@onChangeName} disabled={@state.updating} id="inputError1" />
53
+ </div>
54
+ <div className="form-group">
55
+ <button className="btn btn-default pull-right" onClick={@onClickOk} disabled={@state.updating}>
56
+ &nbsp;
57
+ OK
58
+ &nbsp;
59
+ {
60
+ if @state.updating
61
+ <i className='glyphicon glyphicon-refresh glyphicon-refresh-animate' />
62
+ }
63
+ </button>
64
+ </div>
65
+ </div>
66
+ </Modal>
@@ -81,6 +81,11 @@ module.exports = React.createClass
81
81
  </a>
82
82
  </li>
83
83
  }
84
+ <li>
85
+ <a href={"#/tags"}>
86
+ <i className="glyphicon glyphicon-tag" />
87
+ </a>
88
+ </li>
84
89
  <li>
85
90
  <a href={config.root_path + config.api_path + "/cards.xml?" + @queryParam({}, [])}>
86
91
  <i className="fa fa-rss" />
@@ -94,16 +99,20 @@ module.exports = React.createClass
94
99
  </ul>
95
100
  </div>
96
101
  <div className="col-sm-4">
97
- <a href="javascript:void(0)" className="center-block text-center">
98
- <span className="badge">
99
- {
100
- if @props.cards.pagination
101
- @props.cards.pagination.total_entries
102
- else
103
- <i className="glyphicon glyphicon-refresh glyphicon-refresh-animate" />
104
- }
105
- </span>
106
- </a>
102
+ <ul className="nav nav-pills nav-justified">
103
+ <li>
104
+ <a href="javascript:void(0)" className="center-block text-center">
105
+ <span className="badge">
106
+ {
107
+ if @props.cards.pagination
108
+ @props.cards.pagination.total_entries
109
+ else
110
+ <i className="glyphicon glyphicon-refresh glyphicon-refresh-animate" />
111
+ }
112
+ </span>
113
+ </a>
114
+ </li>
115
+ </ul>
107
116
  </div>
108
117
  <div className="col-sm-4">
109
118
  {
@@ -136,7 +145,7 @@ module.exports = React.createClass
136
145
  <div className="col-sm-12">
137
146
  <ul className="nav nav-pills">
138
147
  <li>
139
- <a href={"#/" + title + '?context=title'}>
148
+ <a href={"#/" + encodeURIComponent(title) + '?context=title'}>
140
149
  {
141
150
  if @props.card && @props.card.query.context == 'title'
142
151
  <strong>A to Z</strong>
@@ -146,7 +155,7 @@ module.exports = React.createClass
146
155
  </a>
147
156
  </li>
148
157
  <li>
149
- <a href={"#/" + title + '?context=updated_at'}>
158
+ <a href={"#/" + encodeURIComponent(title) + '?context=updated_at'}>
150
159
  {
151
160
  if @props.card && @props.card.query.context == 'updated_at'
152
161
  <strong>Latest</strong>
@@ -156,7 +165,7 @@ module.exports = React.createClass
156
165
  </a>
157
166
  </li>
158
167
  <li>
159
- <a href={"#/" + title + '?context=none'}>
168
+ <a href={"#/" + encodeURIComponent(title) + '?context=none'}>
160
169
  {
161
170
  if @props.card && @props.card.query.context == 'none'
162
171
  <strong>Detail</strong>
@@ -166,7 +175,7 @@ module.exports = React.createClass
166
175
  </a>
167
176
  </li>
168
177
  <li>
169
- <a href={"#/" + title + '/history'}>
178
+ <a href={"#/" + encodeURIComponent(title) + '/history'}>
170
179
  {
171
180
  if @props.cards.collectionName == 'CardHistories'
172
181
  <strong>History</strong>
@@ -0,0 +1,65 @@
1
+ # @cjsx React.DOM
2
+ $ = require('jquery')
3
+ Backbone = require('backbone')
4
+ React = require('react')
5
+ EditTag = require('./edit_tag')
6
+ ModalTrigger = require('react-bootstrap/lib/ModalTrigger')
7
+
8
+ module.exports = React.createClass
9
+ displayName: 'Tags'
10
+
11
+ componentDidMount: ->
12
+ console.log '[views/tags] component did mount'
13
+ @props.tags.on 'sync', @forceUpdate.bind(@, null)
14
+
15
+ componentWillReceiveProps: (nextProps)->
16
+ console.log '[views/tags] component will receive props'
17
+ nextProps.tags.on 'sync', @forceUpdate.bind(@, null)
18
+
19
+ render: ->
20
+ <div className="container carte-list">
21
+ <div className="row">
22
+ <div className="col-sm-12">
23
+ <ul className="nav nav-pills">
24
+ <li>
25
+ <a href="#/">
26
+ <i className="glyphicon glyphicon-arrow-left" />
27
+ </a>
28
+ </li>
29
+ </ul>
30
+ </div>
31
+ </div>
32
+
33
+ <div className="row">
34
+ {
35
+ if @props.tags.fetching
36
+ <div className="list-group col-sm-4">
37
+ <div className="list-group-item">
38
+ <i className="glyphicon glyphicon-refresh glyphicon-refresh-animate" />
39
+ </div>
40
+ </div>
41
+ else
42
+ @props.tags.map (tag)->
43
+ <div className="list-group col-sm-4">
44
+ <div className="list-group-item">
45
+ <i className="glyphicon glyphicon-tag" />
46
+ &nbsp;
47
+ {tag.get('name')}
48
+ &nbsp;
49
+ (
50
+ <a href={'#/?tags=' + encodeURIComponent(tag.get('name'))}>
51
+ {tag.get('count')}
52
+ </a>
53
+ )
54
+ <span className="pull-right tools">
55
+ <ModalTrigger modal={<EditTag tag={tag} />}>
56
+ <a href="javascript:void(0)">
57
+ <i className="glyphicon glyphicon-edit" />
58
+ </a>
59
+ </ModalTrigger>
60
+ </span>
61
+ </div>
62
+ </div>
63
+ }
64
+ </div>
65
+ </div>
@@ -135,6 +135,23 @@ module Carte
135
135
  {tags: Card.all_tags}.to_json
136
136
  end
137
137
 
138
+ put '/tags/:name.json' do
139
+ # TODO: existence and length validation
140
+ if json_data['new_name']
141
+ cards = Card.collection.where(tags: params[:name])
142
+ cards.update(
143
+ {'$push' => {tags: json_data['new_name']}},
144
+ {:multi => true}
145
+ )
146
+ cards.update(
147
+ {'$pull' => {tags: params[:name]}},
148
+ {:multi => true}
149
+ )
150
+ end
151
+ status 201
152
+ {}.to_json
153
+ end
154
+
138
155
  error(404) do
139
156
  {}.to_json
140
157
  end
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "carte-client",
3
3
  "description": "something like dictionary, wiki, or information card",
4
- "version": "1.0.8",
4
+ "version": "1.0.9",
5
5
  "main": "lib/carte.coffee",
6
6
  "scripts": {
7
7
  "test": "echo \"Error: no test specified\" && exit 1"
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: 1.0.8
4
+ version: 1.0.9
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-23 00:00:00.000000000 Z
11
+ date: 2015-05-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -267,6 +267,8 @@ files:
267
267
  - lib/carte/client/models/card_histories.coffee
268
268
  - lib/carte/client/models/card_history.coffee
269
269
  - lib/carte/client/models/cards.coffee
270
+ - lib/carte/client/models/tag.coffee
271
+ - lib/carte/client/models/tags.coffee
270
272
  - lib/carte/client/router.coffee
271
273
  - lib/carte/client/tasks.coffee
272
274
  - lib/carte/client/views/app.cjsx
@@ -274,12 +276,14 @@ files:
274
276
  - lib/carte/client/views/cards.cjsx
275
277
  - lib/carte/client/views/content.cjsx
276
278
  - lib/carte/client/views/edit.cjsx
279
+ - lib/carte/client/views/edit_tag.cjsx
277
280
  - lib/carte/client/views/footer.cjsx
278
281
  - lib/carte/client/views/header.cjsx
279
282
  - lib/carte/client/views/list.cjsx
280
283
  - lib/carte/client/views/message.cjsx
281
284
  - lib/carte/client/views/pagination.cjsx
282
285
  - lib/carte/client/views/slideshow.cjsx
286
+ - lib/carte/client/views/tags.cjsx
283
287
  - lib/carte/server.rb
284
288
  - lib/carte/server/models.rb
285
289
  - lib/carte/server/models/card.rb