fustrate-rails 0.3.3 → 0.4.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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/lib/fustrate/rails/version.rb +1 -1
  3. data/vendor/assets/javascripts/fustrate/_module.coffee +14 -8
  4. data/vendor/assets/javascripts/fustrate/components/autocomplete.coffee +4 -4
  5. data/vendor/assets/javascripts/fustrate/components/file_picker.coffee +1 -0
  6. data/vendor/assets/javascripts/fustrate/components/flash.coffee +4 -4
  7. data/vendor/assets/javascripts/fustrate/components/modal.coffee +79 -19
  8. data/vendor/assets/javascripts/fustrate/components/pagination.coffee +5 -5
  9. data/vendor/assets/javascripts/fustrate/generic_form.coffee +4 -5
  10. data/vendor/assets/javascripts/fustrate/generic_page.coffee +6 -6
  11. data/vendor/assets/javascripts/fustrate/generic_table.coffee +2 -2
  12. data/vendor/assets/javascripts/fustrate/listenable.coffee +1 -1
  13. data/vendor/assets/stylesheets/_fustrate.sass +6 -6
  14. data/vendor/assets/stylesheets/awesomplete.sass +2 -1
  15. data/vendor/assets/stylesheets/fustrate/_colors.sass +3 -0
  16. data/vendor/assets/stylesheets/fustrate/_settings.sass +7 -7
  17. data/vendor/assets/stylesheets/fustrate/components/_components.sass +17 -17
  18. data/vendor/assets/stylesheets/fustrate/components/_functions.sass +9 -8
  19. data/vendor/assets/stylesheets/fustrate/components/alerts.sass +26 -18
  20. data/vendor/assets/stylesheets/fustrate/components/buttons.sass +17 -21
  21. data/vendor/assets/stylesheets/fustrate/components/disclosures.sass +5 -5
  22. data/vendor/assets/stylesheets/fustrate/components/dropdowns.sass +24 -19
  23. data/vendor/assets/stylesheets/fustrate/components/flash.sass +21 -16
  24. data/vendor/assets/stylesheets/fustrate/components/forms.sass +99 -92
  25. data/vendor/assets/stylesheets/fustrate/components/grid.sass +15 -23
  26. data/vendor/assets/stylesheets/fustrate/components/labels.sass +13 -12
  27. data/vendor/assets/stylesheets/fustrate/components/modals.sass +97 -49
  28. data/vendor/assets/stylesheets/fustrate/components/pagination.sass +41 -29
  29. data/vendor/assets/stylesheets/fustrate/components/panels.sass +30 -12
  30. data/vendor/assets/stylesheets/fustrate/components/popovers.sass +10 -6
  31. data/vendor/assets/stylesheets/fustrate/components/tables.sass +13 -9
  32. data/vendor/assets/stylesheets/fustrate/components/tabs.sass +6 -6
  33. data/vendor/assets/stylesheets/fustrate/components/tooltips.sass +12 -12
  34. data/vendor/assets/stylesheets/fustrate/components/typography.sass +140 -104
  35. metadata +5 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9d5f71aa31c1e5bad989dc3c933c549a5e62f1a5
4
- data.tar.gz: 9a42f14c3770a006361c62eb23fa4403d0679024
3
+ metadata.gz: df054189ffa1878cc1b2315846a917e969a48c5b
4
+ data.tar.gz: 2f958a0fa3e5e527a30e4550ca5263b7ba19c722
5
5
  SHA512:
6
- metadata.gz: 91bf081fd1025eeea96885535db9b86837cb05d9f6f702d9c1c16b49f33c6a6765f25ae9188eb48af9f34d60b4451461d0da6a97c0fc2d264c5054360a3c5380
7
- data.tar.gz: 97193c0ca4c61d7b5fed80b4f98d6eea38a961a8799ebafa4d04a9cb5910de93dc96f5822c4b391f93474d4068b656363b2c64f59d6283dd3b9a9879c6153254
6
+ metadata.gz: 2277809e67752f86598ae25edf26f0fc57158cc9a05d9d8fb12f65d1d2f1fab32b8e0476fd23840eae8396a9e986231228550437b4ac7d109f4e9872535fa3e9
7
+ data.tar.gz: 5262aaf6879f964a5f508105680921f4f273cf3838685225a5331509901c923136de021b35d3ea550cdbf23be82abb3d3f05bf1c3e3743b134ae9d4514202778
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module Fustrate
3
3
  module Rails
4
- VERSION = '0.3.3'.freeze
4
+ VERSION = '0.4.0'.freeze
5
5
  end
6
6
  end
@@ -3,7 +3,7 @@
3
3
  #= require_tree .
4
4
 
5
5
  class window.Fustrate
6
- @VERSION: '0.3.3'
6
+ @VERSION: '0.4.0'
7
7
  @libs: {}
8
8
 
9
9
  constructor: ->
@@ -15,6 +15,9 @@ class window.Fustrate
15
15
  @initialize()
16
16
 
17
17
  initialize: ->
18
+ # Loop through every element on the page with a data-js-class attribute
19
+ # and convert the data attribute's value to a real object. Then instantiate
20
+ # a new object of that class.
18
21
  $('[data-js-class]').each (index, elem) ->
19
22
  element = $(elem)
20
23
  klass = Fustrate._stringToClass element.data('js-class')
@@ -30,24 +33,26 @@ class window.Fustrate
30
33
  $('.number').each (index, elem) ->
31
34
  elem = $ @
32
35
 
33
- number = if elem.data('number') != undefined
36
+ number = if elem.data('number') isnt undefined
34
37
  elem.data('number')
35
38
  else
36
39
  elem.html()
37
40
 
38
41
  elem.addClass 'negative' if parseInt(number, 10) < 0
39
42
 
43
+ # Take a string like 'Asgard.Whiteboard.Entry' and retrieve the real class
44
+ # with that name. Start at `window` and work down from there.
40
45
  @_stringToClass: (string) ->
41
46
  pieces = string.split('.')
42
47
 
43
48
  Fustrate._arrayToClass(pieces, window)
44
49
 
45
50
  @_arrayToClass: (pieces, root) ->
46
- if pieces.length == 1
47
- root[pieces[0]]
48
- else
49
- Fustrate._arrayToClass pieces.slice(1), root[pieces[0]]
51
+ return root[pieces[0]] if pieces.length is 1
52
+
53
+ Fustrate._arrayToClass pieces.slice(1), root[pieces[0]]
50
54
 
55
+ # Very similar to the Rails helper `link_to`. Returns an HTML string.
51
56
  @linkTo: (text, path, options = {}) ->
52
57
  $('<a>').prop('href', path).html(text).prop(options).outerHTML()
53
58
 
@@ -67,13 +72,13 @@ class window.Fustrate
67
72
  $.rails.CSRFProtection xhr
68
73
 
69
74
  @humanDate: (date, time = false) ->
70
- if date.year() == moment().year()
75
+ if date.year() is moment().year()
71
76
  date.format("M/D#{if time then ' h:mm A' else ''}")
72
77
  else
73
78
  date.format("M/D/YY#{if time then ' h:mm A' else ''}")
74
79
 
75
80
  @label: (text, type) ->
76
- type = if type then "#{type} " else ""
81
+ type = if type then "#{type} " else ''
77
82
 
78
83
  $('<span>')
79
84
  .text(text)
@@ -84,6 +89,7 @@ class window.Fustrate
84
89
 
85
90
  "<i class=\"fa #{classes}\"></i>"
86
91
 
92
+ # Replicate a few common prototype methods on String and Array
87
93
  String::titleize = ->
88
94
  @replace(/_/g, ' ').replace /\b[a-z]/g, (char) -> char.toUpperCase()
89
95
 
@@ -43,7 +43,7 @@ class Fustrate.Components.Autocomplete extends Fustrate.Components.Base
43
43
  .on 'focus', @onFocus
44
44
 
45
45
  blanked: =>
46
- return unless @input.val().trim() == ''
46
+ return unless @input.val().trim() is ''
47
47
 
48
48
  @awesomplete.close()
49
49
 
@@ -90,17 +90,17 @@ class Fustrate.Components.Autocomplete extends Fustrate.Components.Base
90
90
  false
91
91
 
92
92
  onKeyup: (e) =>
93
- keyCode = e.which || e.keyCode
93
+ keyCode = e.which or e.keyCode
94
94
 
95
95
  value = @input.val().trim()
96
96
 
97
- return @blanked() if value == ''
97
+ return @blanked() if value is ''
98
98
 
99
99
  # Ignore: Tab, Enter, Esc, Left, Up, Right, Down
100
100
  return if keyCode in [9, 13, 27, 37, 38, 39, 40]
101
101
 
102
102
  # Don't perform the same search twice in a row
103
- return unless value != @value && value.length >= 2
103
+ return unless value isnt @value and value.length >= 2
104
104
 
105
105
  @value = value
106
106
  @items = []
@@ -3,6 +3,7 @@ class Fustrate.Components.FilePicker extends Fustrate.Components.Base
3
3
  input = $ '<input type="file">'
4
4
 
5
5
  input
6
+ .appendTo $('body')
6
7
  .change ->
7
8
  callback input[0].files
8
9
 
@@ -3,7 +3,7 @@ class Fustrate.Components.Flash extends Fustrate.Components.Base
3
3
  @fadeOutSpeed: 2000
4
4
  @displayTime: 4000
5
5
 
6
- constructor: (message, {type, icon} = {}) ->
6
+ constructor: (message, { type, icon } = {}) ->
7
7
  message = "#{Fustrate.icon(icon)} #{message}" if icon
8
8
 
9
9
  bar = $ "<div class=\"flash #{type ? 'info'}\"></div>"
@@ -19,13 +19,13 @@ class Fustrate.Components.Flash extends Fustrate.Components.Base
19
19
  $('body').append '<div id="flashes">'
20
20
 
21
21
  class @Error
22
- constructor: (message, {icon} = {}) ->
22
+ constructor: (message, { icon } = {}) ->
23
23
  new Fustrate.Components.Flash message, type: 'error', icon: icon
24
24
 
25
25
  class @Info
26
- constructor: (message, {icon} = {}) ->
26
+ constructor: (message, { icon } = {}) ->
27
27
  new Fustrate.Components.Flash message, type: 'info', icon: icon
28
28
 
29
29
  class @Success
30
- constructor: (message, {icon} = {}) ->
30
+ constructor: (message, { icon } = {}) ->
31
31
  new Fustrate.Components.Flash message, type: 'success', icon: icon
@@ -1,4 +1,10 @@
1
1
  class Fustrate.Components.Modal extends Fustrate.Components.Base
2
+ @size: 'tiny'
3
+ @type: null
4
+ @icon: null
5
+ @title: null
6
+ @buttons: []
7
+
2
8
  @fadeSpeed: 250
3
9
 
4
10
  @settings:
@@ -16,13 +22,14 @@ class Fustrate.Components.Modal extends Fustrate.Components.Base
16
22
  display: 'none'
17
23
  _cachedHeight: undefined
18
24
 
19
- constructor: ({title, content, size, settings}) ->
20
- @modal = @constructor.createModal size: size
25
+ constructor: ({ content, settings } = {}) ->
26
+ @modal = @constructor.createModal()
21
27
  @settings = $.extend true, @constructor.settings, (settings ? {})
22
28
  @settings.previousModal = $()
23
29
 
24
- @setTitle title
25
- @setContent content
30
+ @setTitle @constructor.title, icon: @constructor.icon
31
+ @setContent content, false
32
+ @setButtons @constructor.buttons, false
26
33
 
27
34
  @_reloadUIElements()
28
35
  @addEventListeners()
@@ -44,15 +51,64 @@ class Fustrate.Components.Modal extends Fustrate.Components.Base
44
51
  button = $ element
45
52
  @buttons[button.data('button')] = button
46
53
 
47
- setTitle: (title) =>
48
- $('.modal-title span', @modal).html title
54
+ setTitle: (title, { icon } = {}) =>
55
+ if icon
56
+ $('.modal-title span', @modal).html "#{Fustrate.icon icon} #{title}"
57
+ else if @constructor.icon and icon isnt false
58
+ $('.modal-title span', @modal)
59
+ .html "#{Fustrate.icon @constructor.icon} #{title}"
60
+ else
61
+ $('.modal-title span', @modal).html title
49
62
 
50
- setContent: (content) =>
63
+ setContent: (content, reload = true) =>
51
64
  $('.modal-content', @modal).html content
52
65
 
53
66
  @settings._cachedHeight = undefined
54
67
 
55
- @_reloadUIElements()
68
+ @_reloadUIElements() if reload
69
+
70
+ setButtons: (buttons, reload = true) =>
71
+ if buttons?.length < 1
72
+ $('.modal-buttons', @modal).empty()
73
+
74
+ return
75
+
76
+ list = []
77
+
78
+ for button in buttons
79
+ if typeof button is 'string'
80
+ list.push """
81
+ <button data-button="#{button}" class="#{button} expand">
82
+ #{button.titleize()}
83
+ </button>"""
84
+ else if typeof button is 'object'
85
+ for name, options of button
86
+ if typeof options is 'object'
87
+ text = options.text
88
+ else if typeof options is 'string'
89
+ text = options
90
+
91
+ text ?= name.titleize()
92
+
93
+ list.push(
94
+ $("<button data-button=\"#{name}\" class=\"expand\">")
95
+ .text(text)
96
+ .addClass(options.type ? name)
97
+ .outerHTML()
98
+ )
99
+
100
+ columns = list.map (button) -> "<div class=\"columns\">#{button}</div>"
101
+
102
+ $('.modal-buttons', @modal)
103
+ .empty()
104
+ .html "<div class=\"row\">#{columns.join('')}</div>"
105
+
106
+ $('.modal-buttons .row .columns', @modal)
107
+ .addClass("large-#{12 / columns.length}")
108
+
109
+ @settings._cachedHeight = undefined
110
+
111
+ @_reloadUIElements() if reload
56
112
 
57
113
  addEventListeners: =>
58
114
  @modal
@@ -73,13 +129,13 @@ class Fustrate.Components.Modal extends Fustrate.Components.Base
73
129
  # Focus requires a slight physical scroll on iOS 8.4
74
130
  return true if /iPad|iPhone|iPod/g.test navigator.userAgent
75
131
 
76
- $('input, select', @modal)
132
+ $('input, select, textarea', @modal)
77
133
  .filter(':visible:not(:disabled):not([readonly])')
78
134
  .first()
79
135
  .focus()
80
136
 
81
137
  open: =>
82
- return if @modal.hasClass('locked') || @modal.hasClass('open')
138
+ return if @modal.hasClass('locked') or @modal.hasClass('open')
83
139
 
84
140
  @modal.addClass('locked')
85
141
 
@@ -91,13 +147,13 @@ class Fustrate.Components.Modal extends Fustrate.Components.Base
91
147
  $('body')
92
148
  .off 'keyup.modal'
93
149
  .on 'keyup.modal', (e) =>
94
- return if @modal.hasClass('locked') || e.which != 27
150
+ return if @modal.hasClass('locked') or e.which isnt 27
95
151
 
96
152
  @close()
97
153
 
98
154
  @modal.trigger 'opening.modal'
99
155
 
100
- @_cacheHeight() if typeof @settings._cachedHeight == 'undefined'
156
+ @_cacheHeight() if typeof @settings._cachedHeight is 'undefined'
101
157
 
102
158
  if @settings.previousModal.length
103
159
  @settings.previousModal.trigger('hide.modal')
@@ -123,17 +179,17 @@ class Fustrate.Components.Modal extends Fustrate.Components.Base
123
179
  ), 125
124
180
 
125
181
  close: (openPrevious = true) =>
126
- return if @modal.hasClass('locked') || !@modal.hasClass('open')
182
+ return if @modal.hasClass('locked') or not @modal.hasClass('open')
127
183
 
128
184
  @modal.addClass 'locked'
129
185
 
130
186
  $('body').off 'keyup.modal'
131
187
 
132
- unless @settings.previousModal.length && openPrevious
188
+ unless @settings.previousModal.length and openPrevious
133
189
  @constructor.toggleBackground(false)
134
190
 
135
191
  end_css =
136
- top: - $(window).scrollTop() - @settings._cachedHeight + 'px',
192
+ top: -$(window).scrollTop() - @settings._cachedHeight + 'px',
137
193
  opacity: 0
138
194
 
139
195
  setTimeout (=>
@@ -166,16 +222,20 @@ class Fustrate.Components.Modal extends Fustrate.Components.Base
166
222
 
167
223
  @modal.hide()
168
224
 
169
- @createModal: ({size}) ->
225
+ @createModal: ->
170
226
  $("""
171
- <div class="modal #{size ? 'tiny'}">
227
+ <div class="#{@_defaultClasses().join(' ')}">
172
228
  <div class="modal-title">
173
229
  <span></span>
174
230
  <a href="#" class="modal-close">&#215;</a>
175
231
  </div>
176
232
  <div class="modal-content"></div>
233
+ <div class="modal-buttons"></div>
177
234
  </div>""").appendTo(@settings.appendTo)
178
235
 
236
+ @_defaultClasses: ->
237
+ ['modal', @size, @type].filter (klass) -> klass isnt null
238
+
179
239
  @toggleBackground: (visible = true) =>
180
240
  @overlay = $ '<div class="modal-overlay">' unless @overlay
181
241
 
@@ -194,7 +254,7 @@ class Fustrate.Components.Modal extends Fustrate.Components.Base
194
254
  @backgroundClicked: ->
195
255
  modal = $ '.modal.open'
196
256
 
197
- return if !modal || modal.hasClass('locked')
257
+ return if not modal or modal.hasClass('locked')
198
258
 
199
259
  # Don't continue to close if we're not supposed to
200
260
  return unless Fustrate.Components.Modal.settings.closeOnBackgroundClick
@@ -206,7 +266,7 @@ class Fustrate.Components.Modal extends Fustrate.Components.Base
206
266
  @closeButtonClicked: ->
207
267
  modal = $ '.modal.open'
208
268
 
209
- return if !modal || modal.hasClass('locked')
269
+ return if not modal or modal.hasClass('locked')
210
270
 
211
271
  modal.trigger 'close.modal'
212
272
 
@@ -1,5 +1,5 @@
1
1
  class Fustrate.Components.Pagination extends Fustrate.Components.Base
2
- constructor: ({@current_page, @total_pages, @total_entries, @per_page}) ->
2
+ constructor: ({ @current_page, @total_pages, @total_entries, @per_page }) ->
3
3
  @base = @constructor._getPreppedPaginationURL()
4
4
 
5
5
  link: (text, page, options = {}) =>
@@ -28,9 +28,9 @@ class Fustrate.Components.Pagination extends Fustrate.Components.Base
28
28
 
29
29
  if @total_pages > 1
30
30
  pages = for i in @windowedPageNumbers()
31
- if i == @current_page
31
+ if i is @current_page
32
32
  "<li class=\"current\">#{Fustrate.linkTo(i, '#')}</li>"
33
- else if i == 'gap'
33
+ else if i is 'gap'
34
34
  '<li class="unavailable"><span class="gap">…</span></li>'
35
35
  else
36
36
  "<li>#{@link i, i}</li>"
@@ -74,9 +74,9 @@ class Fustrate.Components.Pagination extends Fustrate.Components.Base
74
74
  @_getPreppedPaginationURL: ->
75
75
  search = window.location.search.replace(/[?&]page=\d+/, '')
76
76
 
77
- search = if search[0] == '?'
77
+ search = if search[0] is '?'
78
78
  "#{search}&"
79
- else if search[0] == '&'
79
+ else if search[0] is '&'
80
80
  "?#{search[1...search.length]}&"
81
81
  else
82
82
  '?'
@@ -21,11 +21,10 @@ class Fustrate.GenericForm extends Fustrate.GenericPage
21
21
  validate: -> true
22
22
 
23
23
  onSubmit: (e) =>
24
- e.preventDefault()
24
+ return true if @validate()
25
25
 
26
- unless @validate()
27
- setTimeout (=> $.rails.enableFormElements(@root)), 100
26
+ e.preventDefault()
28
27
 
29
- return false
28
+ setTimeout (=> $.rails.enableFormElements(@root)), 100
30
29
 
31
- true
30
+ false
@@ -14,21 +14,21 @@ class Fustrate.GenericPage
14
14
  @fields = {}
15
15
  @buttons = {}
16
16
 
17
- $('[data-field]', @root).each (index, element) =>
17
+ $('[data-field]', @root).not('.modal [data-field]').each (i, element) =>
18
18
  field = $ element
19
19
  @fields[field.data('field')] = field
20
20
 
21
- $('[data-button]', @root).each (index, element) =>
21
+ $('[data-button]', @root).not('.modal [data-button]').each (i, element) =>
22
22
  button = $ element
23
23
  @buttons[button.data('button')] = button
24
24
 
25
- flashSuccess: (message, {icon} = {}) ->
25
+ flashSuccess: (message, { icon } = {}) ->
26
26
  new Fustrate.Components.Flash.Success(message, icon: icon)
27
27
 
28
- flashError: (message, {icon} = {}) ->
28
+ flashError: (message, { icon } = {}) ->
29
29
  new Fustrate.Components.Flash.Error(message, icon: icon)
30
30
 
31
- flashInfo: (message, {icon} = {}) ->
31
+ flashInfo: (message, { icon } = {}) ->
32
32
  new Fustrate.Components.Flash.Info(message, icon: icon)
33
33
 
34
34
  setHeader: (text) ->
@@ -37,4 +37,4 @@ class Fustrate.GenericPage
37
37
  # Calls all methods matching /refresh.+/
38
38
  refresh: =>
39
39
  for own name, func of @
40
- func() if name.indexOf('refresh') == 0 && name != 'refresh'
40
+ func() if name.indexOf('refresh') is 0 and name isnt 'refresh'
@@ -12,7 +12,7 @@ class Fustrate.GenericTable extends Fustrate.GenericPage
12
12
  sortRows: (rows, sortFunction = ->) ->
13
13
  sorted = ([sortFunction(row), row] for row in rows)
14
14
  sorted.sort (x, y) ->
15
- if x[0] == y[0] then 0 else if x[0] > y[0] then 1 else -1
15
+ if x[0] is y[0] then 0 else if x[0] > y[0] then 1 else -1
16
16
  sorted.map (row) -> row[1]
17
17
 
18
18
  createRow: (item) =>
@@ -21,7 +21,7 @@ class Fustrate.GenericTable extends Fustrate.GenericPage
21
21
  updateRow: (row, item) ->
22
22
  row
23
23
 
24
- reloadRows: (rows, {sort} = { sort: null }) =>
24
+ reloadRows: (rows, { sort } = { sort: null }) =>
25
25
  tbody = $ 'tbody', @table
26
26
 
27
27
  $('tr.loading', tbody).hide()