tomify 0.0.3 → 0.0.4

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.
Files changed (25) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/tomify/default/object.coffee +3 -0
  3. data/app/assets/javascripts/tomify/dynamic/classes/component.coffee +3 -1
  4. data/app/assets/javascripts/tomify/dynamic/classes/field.coffee +1 -0
  5. data/app/assets/javascripts/tomify/dynamic/classes/form.coffee +7 -6
  6. data/app/assets/javascripts/tomify/dynamic/classes/namespace.coffee +7 -11
  7. data/app/assets/javascripts/tomify/dynamic/classes/store.coffee +2 -1
  8. data/app/assets/javascripts/tomify/dynamic/global.coffee +1 -0
  9. data/app/assets/javascripts/tomify/dynamic/react/components/fields/default.coffee +1 -1
  10. data/app/assets/javascripts/tomify/dynamic/react/components/fields/file.coffee +1 -1
  11. data/app/assets/javascripts/tomify/dynamic/react/components/fields/textarea.coffee +1 -1
  12. data/app/assets/javascripts/tomify/dynamic/react/components/layout/messages.coffee +1 -1
  13. data/app/assets/javascripts/tomify/dynamic/react/components/layout/public_navbar.coffee +3 -2
  14. data/app/assets/javascripts/tomify/dynamic/react/components/public/profile.coffee +26 -0
  15. data/app/assets/javascripts/tomify/dynamic/react/components/public/sessions/show.coffee +0 -2
  16. data/app/assets/javascripts/tomify/dynamic/react/components/public/users/edit.coffee +24 -11
  17. data/app/assets/javascripts/tomify/dynamic/react/components/public/users/new.coffee +1 -1
  18. data/app/assets/javascripts/tomify/dynamic/react/components/public/users/show.coffee +23 -0
  19. data/app/assets/javascripts/tomify/dynamic/react/mixins/follow.coffee +2 -1
  20. data/app/controllers/tomify/api/public/users_controller.rb +9 -3
  21. data/app/controllers/tomify/public/profiles_controller.rb +7 -0
  22. data/config/routes.rb +2 -2
  23. data/lib/tomify/version.rb +1 -1
  24. metadata +5 -3
  25. data/app/controllers/tomify/public/users_controller.rb +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5a150d58dedb05af95126801e20124eb12a0d560
4
- data.tar.gz: b52597cf7561633de5a271dd217ddea463787a40
3
+ metadata.gz: 85ed285b35f88cccdcd9e97d65c548def5a31246
4
+ data.tar.gz: 8b6da7d56dbf1e62ffc0cdca368bb76ec8bb7fcf
5
5
  SHA512:
6
- metadata.gz: b5163f01fddc2fd9cbb95ee29a1482d757feb9f24a83faa87dc0bb1f90b8d23aa85b53ae107d14ad06e81e939e68a9592fe763ac743cff180e821fe691e19ba9
7
- data.tar.gz: b3b4bc88c6243f44348b1c5623394c9149da46f0ec2f734665d2df3eb161d88101bda6d95b616945fbd6f8b0f25b1f791640a049130213aa3e498d1ec3d80274
6
+ metadata.gz: b2b4b0a746afbf86c9c6a33387dd10f6c069667c40c7d882985601f3ff0417ae5632ab23d116cecddcfe0e686dff8f3582f5858fab1a9d83f12f33ebcc3a508f
7
+ data.tar.gz: 120be037ee276b3a4903798c5a0f613c2a38d5501e68499b8b1e3a4263eb87596209d988503c4c04c9ca9651588dedc722ddce7310817f0745587f5abe2f425a
@@ -10,3 +10,6 @@
10
10
  path += "#{encodeURIComponent(key)}=#{encodeURIComponent(value)}"
11
11
  path += "&" unless key == last
12
12
  path
13
+
14
+ @ObjectEmpty = (object) ->
15
+ Object.keys(object).length == 0
@@ -3,5 +3,7 @@ class @Component extends Namespace
3
3
  @create: (namespace, component) ->
4
4
  component.displayName ?= namespace
5
5
  component.mixins = @defaultMixins.concat(component.mixins || [])
6
- @namespace namespace, React.createClass(component)
6
+ value = @namespace namespace, React.createClass(component)
7
+ @public namespace
8
+ value
7
9
  @defaultMixins: [WillInitializeMixin, FollowMixin]
@@ -1,6 +1,7 @@
1
1
  class @Field
2
2
  @build: (options) ->
3
3
  props = { name: options.name, type: options.type }
4
+ props.placeholder = options.placeholder || options.name.titleize
4
5
  switch props.type
5
6
  when "checkbox"
6
7
  props.label = options.label
@@ -1,6 +1,6 @@
1
1
  class @Form
2
2
  copy: ->
3
- form = new Form(@layout)
3
+ form = new Form @layout
4
4
  form.fields = (field.copy(form) for field in @fields)
5
5
  form.models = @models
6
6
  form
@@ -28,10 +28,11 @@ class @Form
28
28
  options = $.extend { type: type, name: name, form: @ }, options
29
29
  @fields.push Field.build(options)
30
30
  @models.push options.model if options.model
31
- setComponent: (component) ->
31
+ setComponent: (component, store) ->
32
+ store ?= component.store
32
33
  @component = component
33
- @record = component.store.findOrCreate "Record", {}
34
- @changes = component.store.findOrCreate "Changes", {}
34
+ @record = store.findOrCreate "Record", {}
35
+ @changes = store.findOrCreate "Changes", {}
35
36
  @stores = { record: @record, changes: @changes }
36
37
  component.followModels.push model for model in @models
37
38
  component.followStores.push BuildObject(key, value) for key, value of @stores
@@ -57,10 +58,10 @@ class @Form
57
58
  FieldComponent = Form.Field[field.props.type.capitalize] || Form.Field.Default
58
59
  if @layout == "horizontal"
59
60
  <div key={field.props.name} className="form-group">
60
- <label className="col-sm-2 control-label" htmlFor={field.props.name}>
61
+ <label className="col-sm-3 control-label" htmlFor={field.props.name}>
61
62
  {field.props.name.titleize}
62
63
  </label>
63
- <div className="col-sm-10">
64
+ <div className="col-sm-9">
64
65
  <FieldComponent {...field.props} />
65
66
  </div>
66
67
  </div>
@@ -1,24 +1,20 @@
1
1
  class @Namespace
2
2
  @base: window,
3
3
  @namespace: (namespace, value) ->
4
- unless namespace?.length then throw "Namespace: Requires Keys"
5
- unless value? then throw "Namespace: Requires Value"
6
- keys = namespace.split(".")
7
4
  value.namespace = namespace
5
+ @base[namespace] = value
6
+ @public: (namespace) ->
7
+ keys = namespace.split(".")
8
8
  scope = @base
9
9
  for key in keys when key isnt keys.last
10
10
  scope[key] ?= {}
11
11
  scope = scope[key]
12
- scope[keys.last] = value
13
- value
12
+ scope[keys.last] = @find namespace
14
13
  @create: @namespace
15
14
  @find: (namespace) ->
16
- unless namespace?.length then throw "Namespace: Requires Keys"
17
- scope = @base
18
- scope = (scope ? {})[key] for key in namespace.split(".")
19
- scope
15
+ @base[namespace]
20
16
  @findOrCreate: (namespace, options) ->
21
- @find(namespace, options) || @create(namespace, options)
17
+ @find(namespace) ? @create(namespace, options)
22
18
  findOrCreate: (namespace, options) ->
23
19
  namespace = "#{@namespace}.#{namespace}"
24
- @constructor.find(namespace, options) || @constructor.create(namespace, options)
20
+ @constructor.find(namespace) ? @constructor.create(namespace, options)
@@ -24,7 +24,7 @@ class @Store extends Observer
24
24
  @set(item for item in data when item?)
25
25
  get: (field) ->
26
26
  throw "Store: Invalid Data Type" unless @isDefined()
27
- return @data if @isString() && !field
27
+ return @data if @isBoolean() || @isString()
28
28
  data = $.extend(@data.constructor(), @data)
29
29
  if field then data[field] else data
30
30
  empty: ->
@@ -34,4 +34,5 @@ class @Store extends Observer
34
34
  isDefined: -> @data?
35
35
  isObject: -> @data instanceof Object
36
36
  isArray: -> @data instanceof Array
37
+ isBoolean: -> $.type(@data) == "boolean"
37
38
  isString: -> $.type(@data) == "string"
@@ -16,6 +16,7 @@ env.on "change", ->
16
16
 
17
17
  $ -> Store.find("Env").set(window.env)
18
18
 
19
+ @redirect = (path) -> location.assign path || "/"
19
20
  @message = (message) -> Store.find("Messages").push message
20
21
  @setting = (name) ->
21
22
  setting = Store.find("Settings").get().find (setting) -> setting.name == name
@@ -1,3 +1,3 @@
1
1
  Component.create "Form.Field.Default",
2
2
  render: ->
3
- <input placeholder={@props.name.titleize} className="form-control" type={@props.type} name={@props.name} id={@props.name} value={@props.value(@props.name)} onChange={@props.onChange.bind(null, @props.name)} />
3
+ <input placeholder={@props.placeholder} className="form-control" type={@props.type} name={@props.name} id={@props.name} value={@props.value(@props.name)} onChange={@props.onChange.bind(null, @props.name)} />
@@ -1,3 +1,3 @@
1
1
  Component.create "Form.Field.File",
2
2
  render: ->
3
- <input placeholder={@props.name.titleize} className="form-control" type="file" name={@props.name} id={@props.name} onChange={@props.onChange.bind(null, @props.name)} />
3
+ <input placeholder={@props.placeholder} className="form-control" type="file" name={@props.name} id={@props.name} onChange={@props.onChange.bind(null, @props.name)} />
@@ -1,3 +1,3 @@
1
1
  Component.create "Form.Field.Textarea",
2
2
  render: ->
3
- <textarea placeholder={@props.name.titleize} className="form-control" type="text" name={@props.name} id={@props.name} value={@props.value(@props.name)} onChange={@props.onChange.bind(null, @props.name)} />
3
+ <textarea placeholder={@props.placeholder} className="form-control" type="text" name={@props.name} id={@props.name} value={@props.value(@props.name)} onChange={@props.onChange.bind(null, @props.name)} />
@@ -11,7 +11,7 @@ Component.create "Layout.Messages",
11
11
  <div>
12
12
  {for message, i in @state.messages
13
13
  <div key={i} className="alert alert-#{message.type} text-center">
14
- {message.text}
14
+ <span dangerouslySetInnerHTML={__html: message.text} />
15
15
  <a className="btn btn-danger btn-xs pull-right" href="#" onClick={@remove.bind(null, i)}><i className="fa fa-close" /></a>
16
16
  </div>
17
17
  }
@@ -7,7 +7,8 @@ Component.create "Layout.PublicNavbar",
7
7
  logout: (e) ->
8
8
  e.preventDefault()
9
9
  Model.find("Public.Session").destroy().then (response) ->
10
- window.location.replace "/" if response.type == "success"
10
+ return redirect response.redirect if response.type == "success"
11
+ message type: response.type, text: response.message
11
12
  link: (page) ->
12
13
  <li key={page.name}>
13
14
  <a href="/#{page.path}">{page.name}</a>
@@ -27,7 +28,7 @@ Component.create "Layout.PublicNavbar",
27
28
  <div id="navbar" className="navbar-collapse collapse">
28
29
  <ul className="nav navbar-nav">
29
30
  {if @state.user.id
30
- @link(name: "Profile", path: "user/edit")
31
+ @link(name: "Profile", path: "profile")
31
32
  else if setting "allow_signup"
32
33
  @link(name: "Login", path: "session")
33
34
  }
@@ -0,0 +1,26 @@
1
+ Component.create "Public.Profile",
2
+ followStores: ["user"]
3
+ componentWillInitialize: ->
4
+ @model = Model.find "Public.User"
5
+ @model.setAction "show", Request.none
6
+ @follow @model.on "show", @modelShow
7
+ @follow @model.on "edit", @modelEdit
8
+ modelShow: ->
9
+ @setState(edit: false)
10
+ modelEdit: ->
11
+ @setState(edit: true)
12
+ edit: (e) ->
13
+ e.preventDefault()
14
+ Model.findOrCreate("Public.User").edit()
15
+ render: ->
16
+ <div className="container-fluid">
17
+ <div className="row text-center">
18
+ <div className="col-md-4 col-md-offset-4">
19
+ {if @state.edit
20
+ <Public.Users.Edit />
21
+ else
22
+ <Public.Users.Show />
23
+ }
24
+ </div>
25
+ </div>
26
+ </div>
@@ -1,6 +1,4 @@
1
1
  Component.create "Public.Sessions.Show",
2
- getInitialState: ->
3
- { forgotPassword: false }
4
2
  componentWillInitialize: ->
5
3
  @follow Model.find("Public.Session").on "new", @newSession
6
4
  @follow Model.find("Public.Password").on "new", @newPassword
@@ -26,17 +26,30 @@ Component.create "Public.Users.Edit",
26
26
  else
27
27
  @model.update @form.changes.get()
28
28
  false
29
+ show: (e) ->
30
+ e.preventDefault()
31
+ Model.findOrCreate("Public.User").show()
32
+ destroy: (e) ->
33
+ e.preventDefault()
34
+ Model.find("Public.User").destroy().then (response) ->
35
+ return redirect response.redirect if response.type == "success"
36
+ message type: response.type, text: response.message
37
+ false
29
38
  render: ->
30
- <div className="container-fluid">
31
- <div className="row text-center">
32
- <div className="col-md-4 col-md-offset-4">
33
- <h3>Edit Profile</h3>
34
- <form onSubmit={@submit}>
35
- {@form.render()}
36
- <div className="form-group">
37
- <input type="submit" name="commit" value="Save" className="btn btn-primary" />
38
- </div>
39
- </form>
39
+ <div>
40
+ <h3>Edit Profile</h3>
41
+ <form onSubmit={@submit}>
42
+ {@form.render()}
43
+ <div className="form-group">
44
+ <div className="btn-group">
45
+ <input type="submit" name="commit" value="Save" className="btn btn-primary" />
46
+ <a href="#" onClick={@show} className="btn btn-default">Back</a>
47
+ </div>
48
+ </div>
49
+ <div className="form-group">
50
+ <small>
51
+ <a href="#" onClick={@destroy} data-confirm="Are you sure you want to permanently delete your account?">Delete</a>
52
+ </small>
40
53
  </div>
41
- </div>
54
+ </form>
42
55
  </div>
@@ -14,7 +14,7 @@ Component.create "Public.Users.New",
14
14
  @form = form.setComponent @
15
15
  @follow @model.on "create", @modelCreate
16
16
  modelCreate: (response) ->
17
- return window.location.replace "/" if response.type == "success"
17
+ return redirect response.redirect if response.type == "success"
18
18
  message type: response.type, text: response.message
19
19
  submit: (e) ->
20
20
  e.preventDefault()
@@ -0,0 +1,23 @@
1
+ Component.create "Public.Users.Show",
2
+ followStores: ["user"]
3
+ edit: (e) ->
4
+ e.preventDefault()
5
+ Model.findOrCreate("Public.User").edit()
6
+ render: ->
7
+ <div>
8
+ <h3>Profile</h3>
9
+ <div className="row">
10
+ <div className="col-sm-6 text-right"><b>First Name:</b></div>
11
+ <div className="col-sm-6 text-left">{@state.user.first_name}</div>
12
+ </div>
13
+ <div className="row">
14
+ <div className="col-sm-6 text-right"><b>Last Name:</b></div>
15
+ <div className="col-sm-6 text-left">{@state.user.last_name}</div>
16
+ </div>
17
+ <div className="row">
18
+ <div className="col-sm-6 text-right"><b>Member Since:</b></div>
19
+ <div className="col-sm-6 text-left">{@state.user.created_at.date()}</div>
20
+ </div>
21
+ <br />
22
+ <a href="#" onClick={@edit} className="btn btn-primary">Edit</a>
23
+ </div>
@@ -19,7 +19,7 @@
19
19
  state[key] = store.get()
20
20
  context.setState(state)
21
21
  context.events.push store.on("change", callback)
22
- model.all() for key, model in @models when !model.requested("all")
22
+ model.all() for key, model of @models when !model.requested("all")
23
23
  componentWillUnmount: ->
24
24
  event.off() for event in @events
25
25
  follow: (event) ->
@@ -33,6 +33,7 @@
33
33
  setupModels: ->
34
34
  @models = @convertToHash(@followModels?() || @followModels || [])
35
35
  for key, value of @models when not (value instanceof Store)
36
+ delete @models[key]
36
37
  store = @stores[key.camelize] = @store.findOrCreate value, []
37
38
  model = @models[key.camelize] = Model.findOrCreate(value)
38
39
  context = @
@@ -1,12 +1,11 @@
1
1
  class Tomify::Api::Public::UsersController < Tomify.controllers.public_api
2
2
  before_action :require_user!, only: [:show, :update]
3
- before_action :set_record, only: [:show, :update]
3
+ before_action :set_record, only: [:show, :update, :destroy]
4
4
  before_action :not_found, only: :create, unless: "setting(:allow_signup)"
5
5
 
6
6
  def create
7
7
  session[:current_user_id] = Tomify.models.user.create!(record_params).id
8
- flash[:success] = "Welcome #{current_user.name}!"
9
- render json: { type: :success, message: "Welcome #{current_user.name}!" }
8
+ render json: { type: :success }, success: "Welcome #{current_user.name}!"
10
9
  rescue ActiveRecord::RecordInvalid => e
11
10
  render json: { type: :warning, message: e.record.errors.full_messages.join(", ") }
12
11
  end
@@ -18,6 +17,13 @@ class Tomify::Api::Public::UsersController < Tomify.controllers.public_api
18
17
  render json: { type: :warning, message: e.record.errors.full_messages.join(", ") }
19
18
  end
20
19
 
20
+ def destroy
21
+ flash[:danger] = "Goodbye #{current_user.name}"
22
+ find_record
23
+ destroy_record
24
+ render json: { type: :success }
25
+ end
26
+
21
27
  private
22
28
  def set_record
23
29
  @record = current_user
@@ -0,0 +1,7 @@
1
+ class Tomify::Public::ProfilesController < Tomify.controllers.public
2
+ before_action :require_user!
3
+
4
+ def show
5
+ render component: "Public.Profile"
6
+ end
7
+ end
data/config/routes.rb CHANGED
@@ -3,7 +3,7 @@ Rails.application.routes.draw do
3
3
  root "public/pages#root"
4
4
 
5
5
  scope module: :public do
6
- resource :user, only: :edit
6
+ resource :profile, only: :show
7
7
  resource :session, only: :show
8
8
  end
9
9
 
@@ -27,7 +27,7 @@ Rails.application.routes.draw do
27
27
  end
28
28
 
29
29
  namespace :public do
30
- resource :user, only: [:create, :show, :update]
30
+ resource :user, only: [:create, :show, :update, :destroy]
31
31
  resource :session, only: [:create, :destroy]
32
32
  resource :password, only: :create
33
33
  end
@@ -1,3 +1,3 @@
1
1
  module Tomify
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tomify
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Prats
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-03 00:00:00.000000000 Z
11
+ date: 2017-04-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -288,10 +288,12 @@ files:
288
288
  - app/assets/javascripts/tomify/dynamic/react/components/new.coffee
289
289
  - app/assets/javascripts/tomify/dynamic/react/components/pagination.coffee
290
290
  - app/assets/javascripts/tomify/dynamic/react/components/public/passwords/new.coffee
291
+ - app/assets/javascripts/tomify/dynamic/react/components/public/profile.coffee
291
292
  - app/assets/javascripts/tomify/dynamic/react/components/public/sessions/new.coffee
292
293
  - app/assets/javascripts/tomify/dynamic/react/components/public/sessions/show.coffee
293
294
  - app/assets/javascripts/tomify/dynamic/react/components/public/users/edit.coffee
294
295
  - app/assets/javascripts/tomify/dynamic/react/components/public/users/new.coffee
296
+ - app/assets/javascripts/tomify/dynamic/react/components/public/users/show.coffee
295
297
  - app/assets/javascripts/tomify/dynamic/react/mixins/follow.coffee
296
298
  - app/assets/javascripts/tomify/dynamic/react/mixins/will-initialize.coffee
297
299
  - app/assets/javascripts/tomify/dynamic/react/mount.coffee
@@ -331,8 +333,8 @@ files:
331
333
  - app/controllers/tomify/concerns/default/react_helper.rb
332
334
  - app/controllers/tomify/public/controller.rb
333
335
  - app/controllers/tomify/public/pages_controller.rb
336
+ - app/controllers/tomify/public/profiles_controller.rb
334
337
  - app/controllers/tomify/public/sessions_controller.rb
335
- - app/controllers/tomify/public/users_controller.rb
336
338
  - app/controllers/tomify_controller.rb
337
339
  - app/helpers/tomify/carrierwave_helper.rb
338
340
  - app/helpers/tomify/email_helper.rb
@@ -1,7 +0,0 @@
1
- class Tomify::Public::UsersController < Tomify.controllers.public
2
- before_action :require_user!
3
-
4
- def edit
5
- render component: "Public.Users.Edit"
6
- end
7
- end