material_raingular 0.3.3 → 0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|