material_raingular 0.3.3 → 0.5
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 +4 -4
- data/lib/assets/javascripts/active_record/collection.coffee +13 -0
- data/lib/assets/javascripts/active_record/controller.coffee +171 -0
- data/lib/assets/javascripts/active_record/param_serializer.coffee +23 -0
- data/lib/assets/javascripts/active_record/resource.coffee +65 -0
- data/lib/assets/javascripts/extensions/array.coffee +148 -0
- data/lib/assets/javascripts/extensions/object.coffee +21 -0
- data/lib/assets/javascripts/extensions/string.coffee +13 -0
- data/lib/assets/javascripts/material_raingular/directives/destroy/linkmodel.coffee +6 -3
- data/lib/assets/javascripts/material_raingular/directives/update/linkmodel.coffee +14 -5
- data/lib/assets/javascripts/material_raingular.js.coffee +3 -1
- data/lib/assets/javascripts/super_classes/angular_injectable_model.coffee +5 -0
- data/lib/assets/javascripts/super_classes/angular_model.coffee +2 -1
- data/lib/material_raingular/version.rb +1 -1
- metadata +10 -3
- data/lib/assets/javascripts/extensions.coffee +0 -118
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2b4a25561c752fffb57c14c195bb05957cd026e6
|
4
|
+
data.tar.gz: d7e59069570e7b59c6d4f713136206493f273e4d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 32eb70e30c96b3959877e29da4e798cd4dfc055f6ef6c40d4955cf180645a6e1ad7c94f4eaab964efc3b9cb1f1a2b9d80be68cc682f0655196b7642a0b8a6a30
|
7
|
+
data.tar.gz: 91db8e9fbda211b774877bf37e40b15492be1deb573cea7ab110ec1c5d69d9a344c7d6f4e7bab85516361d79b944d306c25b3d277196545bbb59792a3017312e
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class ActiveRecord.$Collection extends Array
|
2
|
+
$inject: (args...) ->
|
3
|
+
@$injector ||= angular.element(document.body).injector()
|
4
|
+
@[item] = @$injector.get(item) for item in args
|
5
|
+
constructor: (@$promise,callback,error,@options) ->
|
6
|
+
@$resolved = false
|
7
|
+
@$inject('$paramSerializer')
|
8
|
+
@$promise?.then(@$processResponse).then(callback,error)
|
9
|
+
$processResponse: (response)=>
|
10
|
+
for item in response.data
|
11
|
+
@.push(ActiveRecord.$Resource.initialize(item,@options))
|
12
|
+
@$resolved = true
|
13
|
+
return response.data
|
@@ -0,0 +1,171 @@
|
|
1
|
+
class ActiveRecord.Controller extends AngularServiceModel
|
2
|
+
@$inject: ['$paramSerializer','$http']
|
3
|
+
new: (params,callback,error) -> @$singleRecord(params,'new','GET',callback,error)
|
4
|
+
create: (params,callback,error) -> @$singleRecord(params,'create','POST',callback,error)
|
5
|
+
show: (params,callback,error) -> @$singleRecord(params,'show','GET',callback,error)
|
6
|
+
edit: (params,callback,error) -> @$singleRecord(params,'edit','GET',callback,error)
|
7
|
+
update: (params,callback,error) -> @$singleRecord(params,'update','PUT',callback,error)
|
8
|
+
destroy: (params,callback,error) -> @$singleRecord(params,'destroy','DELETE',callback,error)
|
9
|
+
index: (params,callback,error) -> @$collectionRecord(params,'index','GET',callback,error)
|
10
|
+
|
11
|
+
# Privte
|
12
|
+
__name__: -> @constructor.toString().match(/function\s*(.*?)\(/)?[1]
|
13
|
+
__table_name__: -> @__name__().tableize()
|
14
|
+
__url__: -> '/' + @__table_name__() + '/:id'
|
15
|
+
$rawUrl: (params,route,method)->
|
16
|
+
method ||= 'GET'
|
17
|
+
@$buildUrls() unless @_urls
|
18
|
+
key = Object.keys(params || {}).intersection(Object.keys(@_urls))[0]
|
19
|
+
path = @_urls[key][route] if key && route
|
20
|
+
path ||= @__url__()
|
21
|
+
replacements = {new: 'new',edit: ':id/edit'}
|
22
|
+
path = path.replace(':id',replacements[route]) if route in Object.keys(replacements)
|
23
|
+
additionals={}
|
24
|
+
for key,val of (params || {})
|
25
|
+
newPath = path.replace(':' + key, val)
|
26
|
+
additionals[key] = val if newPath == path
|
27
|
+
path = newPath
|
28
|
+
[path,additionals]
|
29
|
+
$url: (params,route,method)->
|
30
|
+
[path,additionals] = @$rawUrl(params,route,method)
|
31
|
+
path = path.split('/').reject( (item)-> item[0] == ':').join('/')
|
32
|
+
path += '.json' unless path.match(/\.json$/)
|
33
|
+
if method == 'GET'
|
34
|
+
query = @$paramSerializer.clean(additionals)
|
35
|
+
path += '?' + query if query
|
36
|
+
path
|
37
|
+
|
38
|
+
routes:
|
39
|
+
shallow: ['edit','update','show','destroy']
|
40
|
+
nonShallow: ['new','create','index']
|
41
|
+
restful: ['new','create','index','edit','update','show','destroy']
|
42
|
+
$buildUrls: ->
|
43
|
+
@_urls ||= {}
|
44
|
+
for item in [@parents].compact().flatten()
|
45
|
+
atom = if typeof item == 'string' then item else Object.keys(item)[0]
|
46
|
+
foreignKey = item[atom]?.foreignKey || atom + '_id'
|
47
|
+
@_urls[foreignKey] ||= {}
|
48
|
+
for key in @routes.restful
|
49
|
+
continue if key not in (item[atom]?.only || []) && item[atom]?.only
|
50
|
+
shallow = key in @routes.shallow && (item[atom]?.shallow)
|
51
|
+
@_urls[foreignKey][key] = if shallow then '' else '/' + atom.pluralize() + '/:' + foreignKey
|
52
|
+
@_urls[foreignKey][key] += @__url__()
|
53
|
+
$singleRecord: (params,route,method,callback,error) -> @$fetchRecord(params,route,method,callback,error,'$Resource')
|
54
|
+
$collectionRecord: (params,route,method,callback,error) -> @$fetchRecord(params,route,method,callback,error,'$Collection')
|
55
|
+
$fetchRecord: (params,route,method,callback,error,type,update_url,destroy_url) ->
|
56
|
+
if typeof params == 'function'
|
57
|
+
error = callback
|
58
|
+
callback = params
|
59
|
+
params = {}
|
60
|
+
url = if route in @routes.restful then @$url(params,route,method) else route
|
61
|
+
promise = @$http(url: url, method: method, data: params)
|
62
|
+
options = {
|
63
|
+
klass: @__name__()
|
64
|
+
update_url: update_url || @$rawUrl(params,'update','PUT')[0]
|
65
|
+
destroy_url: destroy_url || @$rawUrl(params,'destroy','DELETE')[0]}
|
66
|
+
new ActiveRecord[type](promise,callback,error,options)
|
67
|
+
@$addRoutes: (routes) ->
|
68
|
+
for key,val of routes
|
69
|
+
@::[key] = (params,callback,error)->
|
70
|
+
type = if val.collection then '$Collection' else '$Resource'
|
71
|
+
@$fetchRecord(params,val.url,(val.method || 'GET'),callback,error,type,val.update_url,val.destroy_url)
|
72
|
+
|
73
|
+
|
74
|
+
###
|
75
|
+
Desired Syntax
|
76
|
+
class ActiveRecord.Project extends ActiveRecord.Base
|
77
|
+
@register(angular.app)
|
78
|
+
@parents: [{company: {shallow: true}},{person: {only: ['index']},'organization'] # Non-Shallow routes index,create,new Shallow routes update,edit,show,destroy
|
79
|
+
# Alternate function snytax:
|
80
|
+
@parents: ->[{company: {shallow: true}},{person: {only: ['index']},'organization']
|
81
|
+
|
82
|
+
resulting functionality
|
83
|
+
# New
|
84
|
+
@Project.new() => /projects/new.json #Method => GET
|
85
|
+
@Project.new(company_id: 1) => /companies/1/projects/new.json #Method => GET
|
86
|
+
@Project.new(person_id: 1) => /projects/new.json?person_id=1 #Method => GET
|
87
|
+
@Project.new(organization_id: 1) => /organizations/1/projects/new.json #Method => GET
|
88
|
+
# Create
|
89
|
+
@Project.create() => /projects.json #Method => POST
|
90
|
+
@Project.create(company_id: 1) => /companies/1/projects.json #Method => POST
|
91
|
+
@Project.create(person_id: 1) => /projects.json?person_id=1 #Method => POST
|
92
|
+
@Project.create(organization_id: 1) => /organizations/1/projects.json #Method => POST
|
93
|
+
# Edit
|
94
|
+
@Project.edit(id: 3) => /projects/3/edit.json #Method => GET
|
95
|
+
@Project.edit(id: 3,company_id: 1) => /projects/3/edit.json?company_id=1 #Method => GET
|
96
|
+
@Project.edit(id: 3,person_id: 1) => /projects/3/edit.json?person_id=1 #Method => GET
|
97
|
+
@Project.edit(id: 3,organization_id: 1) => /organizations/1/projects/3/edit.json #Method => GET
|
98
|
+
# Update
|
99
|
+
@Project.update(id: 3) => /projects/3.json #Method => PUT/PATCH
|
100
|
+
@Project.update(id: 3,company_id: 1) => /projects/3.json?company_id=1 #Method => PUT/PATCH
|
101
|
+
@Project.update(id: 3,person_id: 1) => /projects/3.json?person_id=1 #Method => PUT/PATCH
|
102
|
+
@Project.update(id: 3,organization_id: 1) => /organizations/1/projects/3.json #Method => PUT/PATCH
|
103
|
+
# Show
|
104
|
+
@Project.show(id: 3) => /projects/3.json #Method => GET
|
105
|
+
@Project.show(id: 3,company_id: 1) => /projects/3.json?company_id=1 #Method => GET
|
106
|
+
@Project.show(id: 3,person_id: 1) => /projects/3.json?person_id=1 #Method => GET
|
107
|
+
@Project.show(id: 3,organization_id: 1) => /organizations/1/projects/3.json #Method => GET
|
108
|
+
# Destroy
|
109
|
+
@Project.destroy(id: 3) => /projects/3.json #Method => DELETE
|
110
|
+
@Project.destroy(id: 3,company_id: 1) => /projects/3.json?company_id=1 #Method => DELETE
|
111
|
+
@Project.destroy(id: 3,person_id: 1) => /projects/3.json?person_id=1 #Method => DELETE
|
112
|
+
@Project.destroy(id: 3,organization_id: 1) => /organizations/1/projects/3.json #Method => DELETE
|
113
|
+
# Index
|
114
|
+
@Project.index() => /projects.json #Method => GET
|
115
|
+
@Project.index(company_id: 1) => /companies/1/projects.json #Method => GET
|
116
|
+
@Project.index(person_id: 1) => /people/1/projects.json #Method => GET
|
117
|
+
@Project.index(organization_id: 1) => /organizations/1/projects.json #Method => GET
|
118
|
+
|
119
|
+
Desired Syntax
|
120
|
+
class ActiveRecord.Project extends ActiveRecord.Base
|
121
|
+
@register(angular.app)
|
122
|
+
@__url__: -> '/not_projects'
|
123
|
+
@parents: [{company: {shallow: true}}]
|
124
|
+
|
125
|
+
resulting functionality
|
126
|
+
# New
|
127
|
+
@Project.new() => /not_projects/new.json #Method => GET
|
128
|
+
@Project.new(company_id: 1) => /companies/1/not_projects/new.json #Method => GET
|
129
|
+
# Create
|
130
|
+
@Project.create() => /not_projects.json #Method => POST
|
131
|
+
@Project.create(company_id: 1) => /companies/1/not_projects.json #Method => POST
|
132
|
+
# Edit
|
133
|
+
@Project.edit(id: 3) => /not_projects/3/edit.json #Method => GET
|
134
|
+
@Project.edit(id: 3,company_id: 1) => /not_projects/3/edit.json?company_id=1 #Method => GET
|
135
|
+
# Update
|
136
|
+
@Project.update(id: 3) => /not_projects/3.json #Method => PUT/PATCH
|
137
|
+
@Project.update(id: 3,company_id: 1) => /not_projects/3.json?company_id=1 #Method => PUT/PATCH
|
138
|
+
# Show
|
139
|
+
@Project.show(id: 3) => /not_projects/3.json #Method => GET
|
140
|
+
@Project.show(id: 3,company_id: 1) => /not_projects/3.json?company_id=1 #Method => GET
|
141
|
+
# Destroy
|
142
|
+
@Project.destroy(id: 3) => /not_projects/3.json #Method => DELETE
|
143
|
+
@Project.destroy(id: 3,company_id: 1) => /not_projects/3.json?company_id=1 #Method => DELETE
|
144
|
+
# Index
|
145
|
+
@Project.index() => /not_projects.json #Method => GET
|
146
|
+
@Project.index(company_id: 1) => /companies/1/not_projects.json #Method => GET
|
147
|
+
|
148
|
+
Desired Syntax
|
149
|
+
class ActiveRecord.Project extends ActiveRecord.Base
|
150
|
+
@register(angular.app)
|
151
|
+
@__url__: -> '/not_projects'
|
152
|
+
@parents: [{company: {shallow: true, url: '/not_companies/:id/something'}}]
|
153
|
+
|
154
|
+
resulting functionality
|
155
|
+
# New
|
156
|
+
@Project.new(company_id: 1) => /not_companies/1/something/new.json #Method => GET
|
157
|
+
# Create
|
158
|
+
@Project.create(company_id: 1) => /not_companies/1/something.json #Method => POST
|
159
|
+
# Edit
|
160
|
+
@Project.edit(id: 3,company_id: 1) => /not_projects/3/edit.json?company_id=1 #Method => GET
|
161
|
+
# Update
|
162
|
+
@Project.update(id: 3,company_id: 1) => /not_projects/3.json?company_id=1 #Method => PUT/PATCH
|
163
|
+
# Show
|
164
|
+
@Project.show(id: 3,company_id: 1) => /not_projects/3.json?company_id=1 #Method => GET
|
165
|
+
# Destroy
|
166
|
+
@Project.destroy(id: 3,company_id: 1) => /not_projects/3.json?company_id=1 #Method => DELETE
|
167
|
+
# Index
|
168
|
+
@Project.index(company_id: 1) => /not_companies/1/something.json #Method => GET
|
169
|
+
|
170
|
+
|
171
|
+
###
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class $paramSerializer extends AngularServiceModel
|
2
|
+
@register(MaterialRaingular.app)
|
3
|
+
@inject('$httpParamSerializer')
|
4
|
+
clean: (obj) -> @$httpParamSerializer @update(obj)
|
5
|
+
update: (obj) ->
|
6
|
+
res = {}
|
7
|
+
for key,val of @strip(obj)
|
8
|
+
continue if val == obj['$' + key + '_was']
|
9
|
+
continue if val?.toString() == obj['$' + key + '_was']?.toString()
|
10
|
+
res[key] = val
|
11
|
+
res
|
12
|
+
strip: (obj) ->
|
13
|
+
res = {}
|
14
|
+
for key,val of obj
|
15
|
+
continue if ['$','_'].includes(key[0]) || key in ['constructor','initialize']
|
16
|
+
res[key] = if (typeof val == 'object' && val != null && !val instanceof Date) then @strip(val) else val
|
17
|
+
res
|
18
|
+
create: (obj) ->
|
19
|
+
res = {}
|
20
|
+
for key,val of @strip(obj)
|
21
|
+
continue unless val
|
22
|
+
res[key] = val
|
23
|
+
res
|
@@ -0,0 +1,65 @@
|
|
1
|
+
class ActiveRecord.$Resource extends Module
|
2
|
+
@include AngularInjectableModel
|
3
|
+
constructor: (@$promise,callback,error,@_options) ->
|
4
|
+
@$activeRecord = true
|
5
|
+
@_options ||= {}
|
6
|
+
@$resolved = false
|
7
|
+
@$inject('$paramSerializer','$http','$q','$timeout','$rootScope')
|
8
|
+
@$promise?.then(@$processResponse.bind(@)).then(callback,error)
|
9
|
+
$updatingKeys: []
|
10
|
+
$activeRecord: true
|
11
|
+
@initialize: (resource,options) ->
|
12
|
+
record = new @(null,null,null,options)
|
13
|
+
record.$processResponse(data: resource)
|
14
|
+
return record
|
15
|
+
@_resourcify: (obj,klass) ->
|
16
|
+
return if obj.$activeRecord
|
17
|
+
record = @initialize(obj,{klass: klass})
|
18
|
+
obj[key] = val for key,val of record
|
19
|
+
|
20
|
+
$deferProcessResponse: (response) ->
|
21
|
+
promise = @$timeout => @$processResponse.bind(@)(response,true)
|
22
|
+
return promise
|
23
|
+
|
24
|
+
$processResponse: (response,apply) ->
|
25
|
+
@$resolved = true
|
26
|
+
for key,val of response.data
|
27
|
+
@[key] = val if @[key] == @['$' + key + '_was'] || key in @$updatingKeys
|
28
|
+
@['$' + key + '_was'] = val unless key[0] in ['$','_']
|
29
|
+
@$updatingKeys = []
|
30
|
+
return response.data
|
31
|
+
|
32
|
+
_defaultWrap: -> @_options.klass.underscore()
|
33
|
+
_defaultPath: -> '/' + @_options.klass.tableize() + '/:id'
|
34
|
+
$updateUrl: ->
|
35
|
+
path = @_options.updateUrl || @_defaultPath()
|
36
|
+
path = path.replace(':id', @.id || '').replace(/\/$/,'')
|
37
|
+
path += '.json' unless path.match(/\.json$/)
|
38
|
+
path
|
39
|
+
$destroyUrl: ->
|
40
|
+
path = @_options.destroyUrl || @_defaultPath()
|
41
|
+
path = path.replace(':id', @.id)
|
42
|
+
path += '.json' unless path.match(/\.json$/)
|
43
|
+
path
|
44
|
+
$save: (callback,error)->
|
45
|
+
if @$promise
|
46
|
+
@$promise = @$promise.then(@_save.bind(@)).then(callback,error) if (@$promise.$$state.status != 0 || !@$resolved)
|
47
|
+
else
|
48
|
+
@$promise = @_save.bind(@)().then(callback,error)
|
49
|
+
_save: ->
|
50
|
+
res = @$paramSerializer.update(@)
|
51
|
+
unless Object.keys(res).length > 0
|
52
|
+
defer = @$q.defer()
|
53
|
+
defer.resolve(@)
|
54
|
+
return defer.promise
|
55
|
+
@$updatingKeys = Object.keys(res)
|
56
|
+
method = if @.id then 'put' else 'post'
|
57
|
+
params = {}
|
58
|
+
params[@_options.paramWrapper || @_defaultWrap()] = if @.id then @$paramSerializer.update(@) else @$paramSerializer.create(@)
|
59
|
+
@["$" + key + "_was"] = val for key,val of res
|
60
|
+
return @$http[method](@$updateUrl(),params).then(@$deferProcessResponse.bind(@))
|
61
|
+
$destroy: (callback,error)->
|
62
|
+
@$promise.$$state.status = 0
|
63
|
+
@$promise = @_destroy().then(callback,error)
|
64
|
+
_destroy: =>
|
65
|
+
return @$http.delete(@$destroyUrl()).then(@$processResponse.bind(@))
|
@@ -0,0 +1,148 @@
|
|
1
|
+
Array::dup = -> return @slice(0)
|
2
|
+
Array::empty = -> @length == 0
|
3
|
+
Array::first = -> @[0]
|
4
|
+
Array::intersects = (arr) -> @intersection(arr).length > 0
|
5
|
+
Array::last = -> @[@length - 1]
|
6
|
+
Array::min = -> return Math.min.apply(null,@)
|
7
|
+
Array::max = -> return Math.max.apply(null,@)
|
8
|
+
Array::present = -> @length != 0
|
9
|
+
Array::remove_all = -> @splice(0,@length)
|
10
|
+
|
11
|
+
Array::add = (arr) ->
|
12
|
+
(@push(item) unless @includes(item)) for item in arr
|
13
|
+
@
|
14
|
+
Array::allIndicesOf = (arg) ->
|
15
|
+
res = []
|
16
|
+
until res.last() == -1 || res.length > 10
|
17
|
+
start = if (res.last() > -1) then res.last() + 1 else 0
|
18
|
+
res.push(@indexOf(arg,start))
|
19
|
+
res[0..-2]
|
20
|
+
Array::compact = ->
|
21
|
+
arr = []
|
22
|
+
arr.push(i) if !!i or i == false for i in @
|
23
|
+
arr
|
24
|
+
Array::drop = (entry)->
|
25
|
+
if (entry || {}).hasOwnProperty('id')
|
26
|
+
index = @pluck('id').indexOf(entry.id)
|
27
|
+
else
|
28
|
+
index = @indexOf(entry)
|
29
|
+
return @ unless index > -1
|
30
|
+
@splice(index,1)
|
31
|
+
Array::find = (id) ->
|
32
|
+
index = @pluck('id').indexOf(id)
|
33
|
+
@[index]
|
34
|
+
Array::flatten = ->
|
35
|
+
arr = []
|
36
|
+
for l in @
|
37
|
+
if Array.isArray(l)
|
38
|
+
for i in l.flatten()
|
39
|
+
arr.push i
|
40
|
+
else
|
41
|
+
arr.push l
|
42
|
+
arr
|
43
|
+
Array::includes = (entry)->
|
44
|
+
return @indexOf(entry) > -1 unless entry
|
45
|
+
if entry instanceof Date
|
46
|
+
(@map (obj) -> obj.toDateString()).includes(entry.toDateString())
|
47
|
+
else if entry.hasOwnProperty('id')
|
48
|
+
return @pluck('id').includes(entry.id)
|
49
|
+
else
|
50
|
+
return @indexOf(entry) > -1
|
51
|
+
Array::index = (obj) ->
|
52
|
+
return unless (obj || {}).hasOwnProperty('id')
|
53
|
+
@pluck('id').indexOf(obj.id)
|
54
|
+
Array::$inject = (action) ->
|
55
|
+
operators = {
|
56
|
+
'+': (a,b) -> a + b
|
57
|
+
'-': (a,b) -> a - b
|
58
|
+
'*': (a,b) -> a * b
|
59
|
+
'/': (a,b) -> a / b
|
60
|
+
'&': (a,b) -> a && b
|
61
|
+
'|': (a,b) -> a || b
|
62
|
+
'merge': (a,b) ->
|
63
|
+
res = new Object(a)
|
64
|
+
res[key] = value for key,value of b
|
65
|
+
res
|
66
|
+
}
|
67
|
+
result = null
|
68
|
+
for item,index in @
|
69
|
+
result ||= item
|
70
|
+
continue if index == 0
|
71
|
+
result = operators[action](result,item)
|
72
|
+
result
|
73
|
+
Array::intersection = (arr) ->
|
74
|
+
res = []
|
75
|
+
(res.push(val) if arr.includes(val)) for val in @
|
76
|
+
return res
|
77
|
+
Array::merge = (arg) ->
|
78
|
+
@push(i) for i in arg
|
79
|
+
@
|
80
|
+
Array::pluck = (property) ->
|
81
|
+
return [] if !(@ && property)
|
82
|
+
property = String(property)
|
83
|
+
return @map (object) ->
|
84
|
+
object = Object(object)
|
85
|
+
return object[property] if (object.hasOwnProperty(property))
|
86
|
+
return ''
|
87
|
+
Array::railsMap = (func)->
|
88
|
+
args = func.match(/\|(.*)\|,(.*)/) || []
|
89
|
+
throw 'Invalid syntax "|a|, a.b"' unless args.length == 3
|
90
|
+
arr = []
|
91
|
+
for obj in @
|
92
|
+
eval args[1] + '= obj'
|
93
|
+
if args[2].includes(':')
|
94
|
+
arr.push eval "(" + args[2] + ")"
|
95
|
+
else
|
96
|
+
arr.push eval args[2]
|
97
|
+
arr
|
98
|
+
Array::reject = (func) ->
|
99
|
+
arr=[]
|
100
|
+
(arr.push(item) unless func(item)) for item in @
|
101
|
+
arr
|
102
|
+
Array::remove = (arr) ->
|
103
|
+
indices = []
|
104
|
+
for item in arr
|
105
|
+
indices.push(@indexOf(item)) if @indexOf(item) > -1
|
106
|
+
(while indices.length > 0
|
107
|
+
@splice(indices.drop(indices.max())[0],1)).flatten()
|
108
|
+
Array::select = (func) ->
|
109
|
+
arr=[]
|
110
|
+
(arr.push(item) if func(item)) for item in @
|
111
|
+
arr
|
112
|
+
Array::sum = ->
|
113
|
+
total = 0
|
114
|
+
(total += parseFloat(i) if i) for i in @
|
115
|
+
total
|
116
|
+
Array::update = (obj) ->
|
117
|
+
return unless (obj || {}).hasOwnProperty('id')
|
118
|
+
@[@index(obj)] = obj
|
119
|
+
Array::union = (arr) ->
|
120
|
+
dup = @slice(0)
|
121
|
+
dup.add(arr)
|
122
|
+
Array::unique = (filterOn) ->
|
123
|
+
equiv = (first,second) ->
|
124
|
+
return true if first == second
|
125
|
+
return !first && !second
|
126
|
+
newItems = []
|
127
|
+
for item in @
|
128
|
+
item = item[filterOn] if filterOn
|
129
|
+
for newItem in newItems
|
130
|
+
isDuplicate = false
|
131
|
+
if equiv(item,newItem)
|
132
|
+
isDuplicate = true
|
133
|
+
break
|
134
|
+
newItems.push(item) if (!isDuplicate)
|
135
|
+
return newItems
|
136
|
+
Array::where = (obj) ->
|
137
|
+
equiv = (first,second) ->
|
138
|
+
return true if first == second
|
139
|
+
if !isNaN(first) && !isNaN(second)
|
140
|
+
return true if parseFloat(first) == parseFloat(second)
|
141
|
+
return false
|
142
|
+
result = []
|
143
|
+
for entry in @
|
144
|
+
addEntry = true
|
145
|
+
for key,value of obj
|
146
|
+
addEntry = addEntry && equiv(entry[key], value)
|
147
|
+
result.push(entry) if addEntry
|
148
|
+
result
|
@@ -0,0 +1,21 @@
|
|
1
|
+
Object.reject = (obj,arg) ->
|
2
|
+
res = {}
|
3
|
+
for key,val of obj
|
4
|
+
unless typeof arg == 'function'
|
5
|
+
res[key] = val unless [arg].flatten().includes?(key)
|
6
|
+
else
|
7
|
+
temp={}
|
8
|
+
temp[key] = val
|
9
|
+
res[key] = val unless arg(key,val,temp)
|
10
|
+
res
|
11
|
+
|
12
|
+
Object.select = (obj,arg) ->
|
13
|
+
res = {}
|
14
|
+
for key,val of obj
|
15
|
+
unless typeof arg == 'function'
|
16
|
+
res[key] = val if [arg].flatten().includes?(key)
|
17
|
+
else
|
18
|
+
temp={}
|
19
|
+
temp[key] = val
|
20
|
+
res[key] = val if arg(key,val,temp)
|
21
|
+
res
|
@@ -0,0 +1,13 @@
|
|
1
|
+
String.prototype.to_number = ->
|
2
|
+
Number(this)
|
3
|
+
String.prototype.to_string = ->
|
4
|
+
this.toString()
|
5
|
+
String.prototype.to_date = ->
|
6
|
+
new Date(this)
|
7
|
+
String.prototype.titleize = ->
|
8
|
+
return this.replace(/\_/g,' ').replace(/([A-Z])/g, ' $1').trim().replace(/\b[a-z]/g, (letter)->
|
9
|
+
return letter[0].toUpperCase())
|
10
|
+
String.prototype.to_f = ->
|
11
|
+
return parseFloat(this)
|
12
|
+
String.prototype.to_i = ->
|
13
|
+
return parseInt(this)
|
@@ -13,14 +13,17 @@ class MrDestroyModel extends AngularLinkModel
|
|
13
13
|
initialize: ->
|
14
14
|
@_setForm()
|
15
15
|
@$element.bind 'click', @destroy
|
16
|
+
@_resourcify()
|
16
17
|
@register(Directives.MrDestroy)
|
18
|
+
_resourcify: ->
|
19
|
+
ActiveRecord.$Resource._resourcify(@_model(),@_matchedExpression()[1].classify())
|
17
20
|
|
18
21
|
destroy: =>
|
19
22
|
return if @$attrs.disabled || @form.disabled
|
20
|
-
|
21
|
-
|
23
|
+
@_resourcify()
|
24
|
+
@$timeout => @_list().drop(@_model())
|
22
25
|
factory = @$injector.get(@_options().factory || @factoryName(@_matchedExpression()[1]))
|
23
|
-
|
26
|
+
@_model().$destroy @_callBack
|
24
27
|
|
25
28
|
_callBack: (data) => @$controller[1]?.evaluate(data)
|
26
29
|
_model: -> @$controller[0].$viewValue
|
@@ -5,11 +5,20 @@ class DirectiveModels.MrUpdateModel extends AngularLinkModel
|
|
5
5
|
'RailsUpdater'
|
6
6
|
)
|
7
7
|
initialize: ->
|
8
|
-
[@ngModelCtrl,@mrCallbackCtrl
|
9
|
-
@
|
8
|
+
[@ngModelCtrl,@mrCallbackCtrl] = @$controller
|
9
|
+
[@parent,@atom] = Helpers.NgModelParse(@$attrs.ngModel,@$scope)
|
10
|
+
@parentVal = @$parse(@parent)
|
11
|
+
@atomVal = @$parse(@atom)
|
12
|
+
@_resourcify()
|
10
13
|
@_bind()
|
14
|
+
|
11
15
|
@register(Directives.MrUpdate)
|
12
16
|
|
17
|
+
_resourcify: ->
|
18
|
+
ActiveRecord.$Resource._resourcify(@parentVal(@$scope),@parent.classify())
|
19
|
+
_update: ->
|
20
|
+
@_resourcify()
|
21
|
+
@parentVal(@$scope).$save.bind(@parentVal(@$scope))().then((data) => @mrCallbackCtrl?.evaluate(data))
|
13
22
|
_bind: -> @$timeout => @_bindInput()[@_funcName()]()
|
14
23
|
_bindInput: =>
|
15
24
|
radio: => @_boundUpdate('input',true)
|
@@ -23,7 +32,7 @@ class DirectiveModels.MrUpdateModel extends AngularLinkModel
|
|
23
32
|
_boundUpdate: (binding,checkValid) ->
|
24
33
|
@$element.bind binding, (event) =>
|
25
34
|
return if !@ngModelCtrl.$valid && checkValid
|
26
|
-
@
|
35
|
+
@_update()
|
27
36
|
|
28
37
|
_bindText: ->
|
29
38
|
@$element.bind 'focus', =>
|
@@ -37,13 +46,13 @@ class DirectiveModels.MrUpdateModel extends AngularLinkModel
|
|
37
46
|
return if @$element.val() == @oldValue
|
38
47
|
@$timeout.cancel(@debounce)
|
39
48
|
@debounce = @$timeout =>
|
40
|
-
@
|
49
|
+
@_update()
|
41
50
|
,delay
|
42
51
|
|
43
52
|
_watcher: ->
|
44
53
|
@$scope.$watch @_modelVal(), (updated,old) =>
|
45
54
|
return if old == undefined
|
46
|
-
@
|
55
|
+
@_update()
|
47
56
|
_specificTypes: ['radio','date','checkbox','hidden']
|
48
57
|
_factory: -> @_options().factory
|
49
58
|
_options: -> @$scope.$eval(@$attrs.mrOptions || '{}')
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# //= require_tree ./super_classes
|
2
2
|
# //= require inflections
|
3
|
-
# //=
|
3
|
+
# //= require_tree ./extensions
|
4
4
|
# //= require angular
|
5
5
|
# //= require angular-route
|
6
6
|
# //= require angular-resource
|
@@ -18,6 +18,7 @@
|
|
18
18
|
# //= require identifier_interceptor
|
19
19
|
# //= require rails_updater
|
20
20
|
# //= require_self
|
21
|
+
# //= require_tree ./active_record
|
21
22
|
# //= require_tree ./material_raingular
|
22
23
|
|
23
24
|
@MaterialRaingular = {
|
@@ -28,3 +29,4 @@
|
|
28
29
|
'ngRoute', 'ngMaterial', 'ngMessages', 'ngResource', 'materialFilters', 'NgCallback'
|
29
30
|
'NgSortable', 'FilteredSelect'])
|
30
31
|
}
|
32
|
+
@ActiveRecord = {}
|
@@ -6,7 +6,8 @@ class @AngularModel extends Module
|
|
6
6
|
app?[type] name, @
|
7
7
|
# Injects dependencies included in args
|
8
8
|
@inject: (args...) ->
|
9
|
-
@$inject
|
9
|
+
@$inject ||= []
|
10
|
+
@$inject.merge args
|
10
11
|
|
11
12
|
constructor: (args...) ->
|
12
13
|
# Bind injected dependencies on scope ie @$scope
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: material_raingular
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.5'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Moody
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-02-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -67,6 +67,10 @@ files:
|
|
67
67
|
- LICENSE.txt
|
68
68
|
- README.md
|
69
69
|
- Rakefile
|
70
|
+
- lib/assets/javascripts/active_record/collection.coffee
|
71
|
+
- lib/assets/javascripts/active_record/controller.coffee
|
72
|
+
- lib/assets/javascripts/active_record/param_serializer.coffee
|
73
|
+
- lib/assets/javascripts/active_record/resource.coffee
|
70
74
|
- lib/assets/javascripts/ajax_errors.js.coffee
|
71
75
|
- lib/assets/javascripts/dateconverter.coffee
|
72
76
|
- lib/assets/javascripts/dateparser.coffee
|
@@ -98,7 +102,9 @@ files:
|
|
98
102
|
- lib/assets/javascripts/directives/table.js.coffee
|
99
103
|
- lib/assets/javascripts/directives/textarea.coffee
|
100
104
|
- lib/assets/javascripts/directives/video.js.coffee
|
101
|
-
- lib/assets/javascripts/extensions.coffee
|
105
|
+
- lib/assets/javascripts/extensions/array.coffee
|
106
|
+
- lib/assets/javascripts/extensions/object.coffee
|
107
|
+
- lib/assets/javascripts/extensions/string.coffee
|
102
108
|
- lib/assets/javascripts/factory_name.js.coffee
|
103
109
|
- lib/assets/javascripts/identifier_interceptor.js.coffee
|
104
110
|
- lib/assets/javascripts/material_filters.coffee
|
@@ -127,6 +133,7 @@ files:
|
|
127
133
|
- lib/assets/javascripts/super_classes/angular_compile_model.coffee
|
128
134
|
- lib/assets/javascripts/super_classes/angular_directive.coffee
|
129
135
|
- lib/assets/javascripts/super_classes/angular_directive_model.coffee
|
136
|
+
- lib/assets/javascripts/super_classes/angular_injectable_model.coffee
|
130
137
|
- lib/assets/javascripts/super_classes/angular_link_model.coffee
|
131
138
|
- lib/assets/javascripts/super_classes/angular_model.coffee
|
132
139
|
- lib/assets/javascripts/super_classes/angular_route_model.coffee
|
@@ -1,118 +0,0 @@
|
|
1
|
-
String.prototype.to_number = ->
|
2
|
-
Number(this)
|
3
|
-
String.prototype.to_string = ->
|
4
|
-
this.toString()
|
5
|
-
String.prototype.to_date = ->
|
6
|
-
new Date(this)
|
7
|
-
Array.prototype.empty = ->
|
8
|
-
this.length == 0
|
9
|
-
Array.prototype.present = ->
|
10
|
-
this.length != 0
|
11
|
-
Array.prototype.min = ->
|
12
|
-
return Math.min.apply(null,this)
|
13
|
-
Array.prototype.max = ->
|
14
|
-
return Math.max.apply(null,this)
|
15
|
-
Array.prototype.railsMap = (func)->
|
16
|
-
args = func.match(/\|(.*)\|,(.*)/) || []
|
17
|
-
throw 'Invalid syntax "|a|, a.b"' unless args.length == 3
|
18
|
-
arr = []
|
19
|
-
for obj in this
|
20
|
-
eval args[1] + '= obj'
|
21
|
-
if args[2].includes(':')
|
22
|
-
arr.push eval "(" + args[2] + ")"
|
23
|
-
else
|
24
|
-
arr.push eval args[2]
|
25
|
-
arr
|
26
|
-
Array.prototype.compact = ->
|
27
|
-
arr = []
|
28
|
-
for i in this
|
29
|
-
arr.push(i) if !!i or i == false
|
30
|
-
arr
|
31
|
-
Array.prototype.flatten = ->
|
32
|
-
arr = []
|
33
|
-
for l in this
|
34
|
-
if Array.isArray(l)
|
35
|
-
for i in l.flatten()
|
36
|
-
arr.push i
|
37
|
-
else
|
38
|
-
arr.push l
|
39
|
-
arr
|
40
|
-
Array.prototype.sum = ->
|
41
|
-
total = 0
|
42
|
-
for i in this
|
43
|
-
total += parseFloat(i) if i
|
44
|
-
total
|
45
|
-
Array.prototype.includes = (entry)->
|
46
|
-
return @.indexOf(entry) > -1 unless entry
|
47
|
-
if entry instanceof Date
|
48
|
-
(@.map (obj) -> obj.toDateString()).includes(entry.toDateString())
|
49
|
-
else if entry.hasOwnProperty('id')
|
50
|
-
return @.pluck('id').includes(entry.id)
|
51
|
-
else
|
52
|
-
return @.indexOf(entry) > -1
|
53
|
-
Array.prototype.drop = (entry)->
|
54
|
-
if (entry || {}).hasOwnProperty('id')
|
55
|
-
index = @.pluck('id').indexOf(entry.id)
|
56
|
-
else
|
57
|
-
index = @.indexOf(entry)
|
58
|
-
return this unless index > -1
|
59
|
-
@.splice(index,1)
|
60
|
-
String.prototype.titleize = ->
|
61
|
-
return this.replace(/\_/g,' ').replace(/([A-Z])/g, ' $1').trim().replace(/\b[a-z]/g, (letter)->
|
62
|
-
return letter[0].toUpperCase())
|
63
|
-
Array.prototype.pluck = (property) ->
|
64
|
-
return [] if !(this && property)
|
65
|
-
property = String(property)
|
66
|
-
return this.map (object) ->
|
67
|
-
object = Object(object)
|
68
|
-
return object[property] if (object.hasOwnProperty(property))
|
69
|
-
return ''
|
70
|
-
Array.prototype.unique = (filterOn) ->
|
71
|
-
equiv = (first,second) ->
|
72
|
-
return true if first == second
|
73
|
-
return !first && !second
|
74
|
-
newItems = []
|
75
|
-
for item in this
|
76
|
-
item = item[filterOn] if filterOn
|
77
|
-
for newItem in newItems
|
78
|
-
isDuplicate = false
|
79
|
-
if equiv(item,newItem)
|
80
|
-
isDuplicate = true
|
81
|
-
break
|
82
|
-
newItems.push(item) if (!isDuplicate)
|
83
|
-
return newItems
|
84
|
-
String.prototype.to_f = ->
|
85
|
-
return parseFloat(this)
|
86
|
-
String.prototype.to_i = ->
|
87
|
-
return parseInt(this)
|
88
|
-
Array.prototype.dup = ->
|
89
|
-
return @.slice(0)
|
90
|
-
Array.prototype.where = (obj) ->
|
91
|
-
equiv = (first,second) ->
|
92
|
-
return true if first == second
|
93
|
-
if !isNaN(first) && !isNaN(second)
|
94
|
-
return true if parseFloat(first) == parseFloat(second)
|
95
|
-
return false
|
96
|
-
result = []
|
97
|
-
for entry in @
|
98
|
-
addEntry = true
|
99
|
-
for key,value of obj
|
100
|
-
addEntry = addEntry && equiv(entry[key], value)
|
101
|
-
result.push(entry) if addEntry
|
102
|
-
result
|
103
|
-
Array.prototype.intersection = (arr) ->
|
104
|
-
res = []
|
105
|
-
for val in @
|
106
|
-
res.push(val) if arr.includes(val)
|
107
|
-
return res
|
108
|
-
Array.prototype.intersects = (arr) ->
|
109
|
-
@.intersection(arr).length > 0
|
110
|
-
Array.prototype.find = (id) ->
|
111
|
-
index = @.pluck('id').indexOf(id)
|
112
|
-
@[index]
|
113
|
-
Array.prototype.index = (obj) ->
|
114
|
-
return unless (obj || {}).hasOwnProperty('id')
|
115
|
-
@.pluck('id').indexOf(obj.id)
|
116
|
-
Array.prototype.update = (obj) ->
|
117
|
-
return unless (obj || {}).hasOwnProperty('id')
|
118
|
-
@[@.index(obj)] = obj
|