padma-assets 0.1.20 → 0.1.21
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/app/abilities/general_ability.rb +1 -0
- data/app/assets/javascripts/async_render.js.coffee.erb +41 -0
- data/app/assets/javascripts/cache.js +432 -0
- data/app/assets/javascripts/initialize-lists-menu.js.coffee +14 -0
- data/app/assets/javascripts/jquery.quickfilter.js +33 -0
- data/app/assets/javascripts/padma-assets.js +4 -0
- data/app/assets/javascripts/ux-events.js.coffee +3 -3
- data/app/assets/stylesheets/header.css.erb +1 -1
- data/app/assets/stylesheets/layout_application.css +0 -1
- data/app/assets/stylesheets/reset.css +0 -5
- data/app/views/layouts/_alpha_lists_list.html.erb +44 -0
- data/app/views/layouts/_module_box.html.erb +6 -2
- data/config/locales/header-menu.en.yml +7 -0
- data/config/locales/header-menu.es.yml +7 -0
- data/config/locales/header-menu.pt-BR.yml +7 -0
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc745accd74d7cd14737449437a39a85579e2974
|
4
|
+
data.tar.gz: 344bd105e4580a50c28c91a9b6e44b7da04faec3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9af64dc748bba204f7856155fd679b5aed314f9fa9eaea693b2b8a0be4e20a731dd8ea8e2824af6467c8b3201a5372de187a455a8ae94e9f2a4636d45c0a51e1
|
7
|
+
data.tar.gz: 6b7e119aba1d76d69d1a511325b675f56f3b7ef968a7a98ab1bcd4502f599cac69c123a2e851ed71138c630788bccfef3949ad2fa95cfe0c95eddacb1aa69d84
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# Usage
|
2
|
+
#
|
3
|
+
# To a container element add css class 'async-render' and attribute data-url with url to be called.
|
4
|
+
# this will call url and replace elements content with returned html
|
5
|
+
# options are:
|
6
|
+
# data-url, data-success-callback
|
7
|
+
#
|
8
|
+
# With class 'cached-async-render" html will be cached locally to avoid constant requests.
|
9
|
+
# options are:
|
10
|
+
# data-url , data-cache-key, data-cache-expires-in, data-success-callback
|
11
|
+
#
|
12
|
+
# Author: Dwayne Macgowan
|
13
|
+
$(document).ready ->
|
14
|
+
|
15
|
+
cache = new Cache(-1, false, new Cache.LocalStorageCacheStorage())
|
16
|
+
|
17
|
+
$(".cached-async-render").each (i) ->
|
18
|
+
e = $(this)
|
19
|
+
cache_key = e.data('cache-key') || e.data('url')
|
20
|
+
expires_in = e.data('cache-expires-in') || 60 # default cache expiration to 1 min
|
21
|
+
|
22
|
+
cached_html = cache.getItem(cache_key)
|
23
|
+
if cached_html == null
|
24
|
+
$.ajax e.data('url'),
|
25
|
+
success: (html_response) ->
|
26
|
+
cache.setItem(cache_key,html_response,{expirantionSliding: expires_in})
|
27
|
+
e.html html_response
|
28
|
+
if e.data('success-callback')
|
29
|
+
eval e.data('success-callback')
|
30
|
+
else
|
31
|
+
e.html cached_html
|
32
|
+
if e.data('success-callback')
|
33
|
+
eval e.data('success-callback')
|
34
|
+
|
35
|
+
$(".async-render").each (i) ->
|
36
|
+
e = $(this)
|
37
|
+
$.ajax e.data('url'),
|
38
|
+
success: (html_response) ->
|
39
|
+
e.html html_response
|
40
|
+
if e.data('success-callback')
|
41
|
+
eval e.data('success-callback')
|
@@ -0,0 +1,432 @@
|
|
1
|
+
/*
|
2
|
+
MIT LICENSE
|
3
|
+
Copyright (c) 2007 Monsur Hossain (http://monsur.hossai.in)
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person
|
6
|
+
obtaining a copy of this software and associated documentation
|
7
|
+
files (the "Software"), to deal in the Software without
|
8
|
+
restriction, including without limitation the rights to use,
|
9
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
+
copies of the Software, and to permit persons to whom the
|
11
|
+
Software is furnished to do so, subject to the following
|
12
|
+
conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be
|
15
|
+
included in all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
19
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
20
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
21
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
22
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
23
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
24
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
25
|
+
*/
|
26
|
+
|
27
|
+
// Avoid polluting the global namespace if we're using a module loader
|
28
|
+
(function(){
|
29
|
+
|
30
|
+
/**
|
31
|
+
* Creates a new Cache object.
|
32
|
+
* @param {number} maxSize The maximum size of the cache (or -1 for no max).
|
33
|
+
* @param {boolean} debug Whether to log events to the console.log.
|
34
|
+
* @constructor
|
35
|
+
*/
|
36
|
+
function Cache(maxSize, debug, storage) {
|
37
|
+
this.maxSize_ = maxSize || -1;
|
38
|
+
this.debug_ = debug || false;
|
39
|
+
this.storage_ = storage || new Cache.BasicCacheStorage();
|
40
|
+
|
41
|
+
this.fillFactor_ = .75;
|
42
|
+
|
43
|
+
this.stats_ = {};
|
44
|
+
this.stats_['hits'] = 0;
|
45
|
+
this.stats_['misses'] = 0;
|
46
|
+
this.log_('Initialized cache with size ' + maxSize);
|
47
|
+
}
|
48
|
+
|
49
|
+
/**
|
50
|
+
* An easier way to refer to the priority of a cache item
|
51
|
+
* @enum {number}
|
52
|
+
*/
|
53
|
+
Cache.Priority = {
|
54
|
+
'LOW': 1,
|
55
|
+
'NORMAL': 2,
|
56
|
+
'HIGH': 4
|
57
|
+
};
|
58
|
+
|
59
|
+
/**
|
60
|
+
* Basic in memory cache storage backend.
|
61
|
+
* @constructor
|
62
|
+
*/
|
63
|
+
Cache.BasicCacheStorage = function() {
|
64
|
+
this.items_ = {};
|
65
|
+
this.count_ = 0;
|
66
|
+
}
|
67
|
+
Cache.BasicCacheStorage.prototype.get = function(key) {
|
68
|
+
return this.items_[key];
|
69
|
+
}
|
70
|
+
Cache.BasicCacheStorage.prototype.set = function(key, value) {
|
71
|
+
if (typeof this.get(key) === "undefined")
|
72
|
+
this.count_++;
|
73
|
+
this.items_[key] = value;
|
74
|
+
}
|
75
|
+
Cache.BasicCacheStorage.prototype.size = function(key, value) {
|
76
|
+
return this.count_;
|
77
|
+
}
|
78
|
+
Cache.BasicCacheStorage.prototype.remove = function(key) {
|
79
|
+
var item = this.get(key);
|
80
|
+
if (typeof item !== "undefined")
|
81
|
+
this.count_--;
|
82
|
+
delete this.items_[key];
|
83
|
+
return item;
|
84
|
+
}
|
85
|
+
Cache.BasicCacheStorage.prototype.keys = function() {
|
86
|
+
var ret = [], p;
|
87
|
+
for (p in this.items_) ret.push(p);
|
88
|
+
return ret;
|
89
|
+
}
|
90
|
+
|
91
|
+
/**
|
92
|
+
* Local Storage based persistant cache storage backend.
|
93
|
+
* If a size of -1 is used, it will purge itself when localStorage
|
94
|
+
* is filled. This is 5MB on Chrome/Safari.
|
95
|
+
* WARNING: The amortized cost of this cache is very low, however,
|
96
|
+
* when a the cache fills up all of localStorage, and a purge is required, it can
|
97
|
+
* take a few seconds to fetch all the keys and values in storage.
|
98
|
+
* Since localStorage doesn't have namespacing, this means that even if this
|
99
|
+
* individual cache is small, it can take this time if there are lots of other
|
100
|
+
* other keys in localStorage.
|
101
|
+
*
|
102
|
+
* @param {string} namespace A string to namespace the items in localStorage. Defaults to 'default'.
|
103
|
+
* @constructor
|
104
|
+
*/
|
105
|
+
Cache.LocalStorageCacheStorage = function(namespace) {
|
106
|
+
this.prefix_ = 'cache-storage.' + (namespace || 'default') + '.';
|
107
|
+
// Regexp String Escaping from http://simonwillison.net/2006/Jan/20/escape/#p-6
|
108
|
+
var escapedPrefix = this.prefix_.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
|
109
|
+
this.regexp_ = new RegExp('^' + escapedPrefix)
|
110
|
+
}
|
111
|
+
Cache.LocalStorageCacheStorage.prototype.get = function(key) {
|
112
|
+
var item = window.localStorage[this.prefix_ + key];
|
113
|
+
if (item) return JSON.parse(item);
|
114
|
+
return null;
|
115
|
+
}
|
116
|
+
Cache.LocalStorageCacheStorage.prototype.set = function(key, value) {
|
117
|
+
window.localStorage[this.prefix_ + key] = JSON.stringify(value);
|
118
|
+
}
|
119
|
+
Cache.LocalStorageCacheStorage.prototype.size = function(key, value) {
|
120
|
+
return this.keys().length;
|
121
|
+
}
|
122
|
+
Cache.LocalStorageCacheStorage.prototype.remove = function(key) {
|
123
|
+
var item = this.get(key);
|
124
|
+
delete window.localStorage[this.prefix_ + key];
|
125
|
+
return item;
|
126
|
+
}
|
127
|
+
Cache.LocalStorageCacheStorage.prototype.keys = function() {
|
128
|
+
var ret = [], p;
|
129
|
+
for (p in window.localStorage) {
|
130
|
+
if (p.match(this.regexp_)) ret.push(p.replace(this.prefix_, ''));
|
131
|
+
};
|
132
|
+
return ret;
|
133
|
+
}
|
134
|
+
|
135
|
+
/**
|
136
|
+
* Retrieves an item from the cache.
|
137
|
+
* @param {string} key The key to retrieve.
|
138
|
+
* @return {Object} The item, or null if it doesn't exist.
|
139
|
+
*/
|
140
|
+
Cache.prototype.getItem = function(key) {
|
141
|
+
|
142
|
+
// retrieve the item from the cache
|
143
|
+
var item = this.storage_.get(key);
|
144
|
+
|
145
|
+
if (item != null) {
|
146
|
+
if (!this.isExpired_(item)) {
|
147
|
+
// if the item is not expired
|
148
|
+
// update its last accessed date
|
149
|
+
item.lastAccessed = new Date().getTime();
|
150
|
+
} else {
|
151
|
+
// if the item is expired, remove it from the cache
|
152
|
+
this.removeItem(key);
|
153
|
+
item = null;
|
154
|
+
}
|
155
|
+
}
|
156
|
+
|
157
|
+
// return the item value (if it exists), or null
|
158
|
+
var returnVal = item ? item.value : null;
|
159
|
+
if (returnVal) {
|
160
|
+
this.stats_['hits']++;
|
161
|
+
this.log_('Cache HIT for key ' + key)
|
162
|
+
} else {
|
163
|
+
this.stats_['misses']++;
|
164
|
+
this.log_('Cache MISS for key ' + key)
|
165
|
+
}
|
166
|
+
return returnVal;
|
167
|
+
};
|
168
|
+
|
169
|
+
|
170
|
+
Cache._CacheItem = function(k, v, o) {
|
171
|
+
if (!k) {
|
172
|
+
throw new Error("key cannot be null or empty");
|
173
|
+
}
|
174
|
+
this.key = k;
|
175
|
+
this.value = v;
|
176
|
+
o = o || {};
|
177
|
+
if (o.expirationAbsolute) {
|
178
|
+
o.expirationAbsolute = o.expirationAbsolute.getTime();
|
179
|
+
}
|
180
|
+
if (!o.priority) {
|
181
|
+
o.priority = Cache.Priority.NORMAL;
|
182
|
+
}
|
183
|
+
this.options = o;
|
184
|
+
this.lastAccessed = new Date().getTime();
|
185
|
+
};
|
186
|
+
|
187
|
+
|
188
|
+
/**
|
189
|
+
* Sets an item in the cache.
|
190
|
+
* @param {string} key The key to refer to the item.
|
191
|
+
* @param {Object} value The item to cache.
|
192
|
+
* @param {Object} options an optional object which controls various caching
|
193
|
+
* options:
|
194
|
+
* expirationAbsolute: the datetime when the item should expire
|
195
|
+
* expirationSliding: an integer representing the seconds since
|
196
|
+
* the last cache access after which the item
|
197
|
+
* should expire
|
198
|
+
* priority: How important it is to leave this item in the cache.
|
199
|
+
* You can use the values Cache.Priority.LOW, .NORMAL, or
|
200
|
+
* .HIGH, or you can just use an integer. Note that
|
201
|
+
* placing a priority on an item does not guarantee
|
202
|
+
* it will remain in cache. It can still be purged if
|
203
|
+
* an expiration is hit, or if the cache is full.
|
204
|
+
* callback: A function that gets called when the item is purged
|
205
|
+
* from cache. The key and value of the removed item
|
206
|
+
* are passed as parameters to the callback function.
|
207
|
+
*/
|
208
|
+
Cache.prototype.setItem = function(key, value, options) {
|
209
|
+
|
210
|
+
// add a new cache item to the cache
|
211
|
+
if (this.storage_.get(key) != null) {
|
212
|
+
this.removeItem(key);
|
213
|
+
}
|
214
|
+
this.addItem_(new Cache._CacheItem(key, value, options));
|
215
|
+
this.log_("Setting key " + key);
|
216
|
+
|
217
|
+
// if the cache is full, purge it
|
218
|
+
if ((this.maxSize_ > 0) && (this.size() > this.maxSize_)) {
|
219
|
+
var that = this;
|
220
|
+
setTimeout(function() {
|
221
|
+
that.purge_.call(that);
|
222
|
+
}, 0);
|
223
|
+
}
|
224
|
+
};
|
225
|
+
|
226
|
+
|
227
|
+
/**
|
228
|
+
* Removes all items from the cache.
|
229
|
+
*/
|
230
|
+
Cache.prototype.clear = function() {
|
231
|
+
// loop through each item in the cache and remove it
|
232
|
+
var keys = this.storage_.keys()
|
233
|
+
for (var i = 0; i < keys.length; i++) {
|
234
|
+
this.removeItem(keys[i]);
|
235
|
+
}
|
236
|
+
this.log_('Cache cleared');
|
237
|
+
};
|
238
|
+
|
239
|
+
|
240
|
+
/**
|
241
|
+
* @return {Object} The hits and misses on the cache.
|
242
|
+
*/
|
243
|
+
Cache.prototype.getStats = function() {
|
244
|
+
return this.stats_;
|
245
|
+
};
|
246
|
+
|
247
|
+
|
248
|
+
/**
|
249
|
+
* @return {string} Returns an HTML string representation of the cache.
|
250
|
+
*/
|
251
|
+
Cache.prototype.toHtmlString = function() {
|
252
|
+
var returnStr = this.size() + " item(s) in cache<br /><ul>";
|
253
|
+
var keys = this.storage_.keys()
|
254
|
+
for (var i = 0; i < keys.length; i++) {
|
255
|
+
var item = this.storage_.get(keys[i]);
|
256
|
+
returnStr = returnStr + "<li>" + item.key.toString() + " = " +
|
257
|
+
item.value.toString() + "</li>";
|
258
|
+
}
|
259
|
+
returnStr = returnStr + "</ul>";
|
260
|
+
return returnStr;
|
261
|
+
};
|
262
|
+
|
263
|
+
|
264
|
+
/**
|
265
|
+
* Allows it to resize the Cache capacity if needed.
|
266
|
+
* @param {integer} newMaxSize the new max amount of stored entries within the Cache
|
267
|
+
*/
|
268
|
+
Cache.prototype.resize = function(newMaxSize) {
|
269
|
+
this.log_('Resizing Cache from ' + this.maxSize_ + ' to ' + newMaxSize);
|
270
|
+
// Set new size before purging so we know how many items to purge
|
271
|
+
var oldMaxSize = this.maxSize_
|
272
|
+
this.maxSize_ = newMaxSize;
|
273
|
+
|
274
|
+
if (newMaxSize > 0 && (oldMaxSize < 0 || newMaxSize < oldMaxSize)) {
|
275
|
+
if (this.size() > newMaxSize) {
|
276
|
+
// Cache needs to be purged as it does contain too much entries for the new size
|
277
|
+
this.purge_();
|
278
|
+
} // else if cache isn't filled up to the new limit nothing is to do
|
279
|
+
}
|
280
|
+
// else if newMaxSize >= maxSize nothing to do
|
281
|
+
this.log_('Resizing done');
|
282
|
+
}
|
283
|
+
|
284
|
+
/**
|
285
|
+
* Removes expired items from the cache.
|
286
|
+
*/
|
287
|
+
Cache.prototype.purge_ = function() {
|
288
|
+
var tmparray = new Array();
|
289
|
+
var purgeSize = Math.round(this.maxSize_ * this.fillFactor_);
|
290
|
+
if (this.maxSize_ < 0)
|
291
|
+
purgeSize = this.size() * this.fillFactor_;
|
292
|
+
// loop through the cache, expire items that should be expired
|
293
|
+
// otherwise, add the item to an array
|
294
|
+
var keys = this.storage_.keys();
|
295
|
+
for (var i = 0; i < keys.length; i++) {
|
296
|
+
var key = keys[i];
|
297
|
+
var item = this.storage_.get(key);
|
298
|
+
if (this.isExpired_(item)) {
|
299
|
+
this.removeItem(key);
|
300
|
+
} else {
|
301
|
+
tmparray.push(item);
|
302
|
+
}
|
303
|
+
}
|
304
|
+
|
305
|
+
if (tmparray.length > purgeSize) {
|
306
|
+
// sort this array based on cache priority and the last accessed date
|
307
|
+
tmparray = tmparray.sort(function(a, b) {
|
308
|
+
if (a.options.priority != b.options.priority) {
|
309
|
+
return b.options.priority - a.options.priority;
|
310
|
+
} else {
|
311
|
+
return b.lastAccessed - a.lastAccessed;
|
312
|
+
}
|
313
|
+
});
|
314
|
+
// remove items from the end of the array
|
315
|
+
while (tmparray.length > purgeSize) {
|
316
|
+
var ritem = tmparray.pop();
|
317
|
+
this.removeItem(ritem.key);
|
318
|
+
}
|
319
|
+
}
|
320
|
+
this.log_('Purged cached');
|
321
|
+
};
|
322
|
+
|
323
|
+
|
324
|
+
/**
|
325
|
+
* Add an item to the cache.
|
326
|
+
* @param {Object} item The cache item to add.
|
327
|
+
* @private
|
328
|
+
*/
|
329
|
+
Cache.prototype.addItem_ = function(item, attemptedAlready) {
|
330
|
+
var cache = this;
|
331
|
+
try {
|
332
|
+
this.storage_.set(item.key, item);
|
333
|
+
} catch(err) {
|
334
|
+
if (attemptedAlready) {
|
335
|
+
this.log_('Failed setting again, giving up: ' + err.toString());
|
336
|
+
throw(err);
|
337
|
+
}
|
338
|
+
this.log_('Error adding item, purging and trying again: ' + err.toString());
|
339
|
+
this.purge_();
|
340
|
+
this.addItem_(item, true);
|
341
|
+
}
|
342
|
+
};
|
343
|
+
|
344
|
+
|
345
|
+
/**
|
346
|
+
* Remove an item from the cache, call the callback function (if it exists).
|
347
|
+
* @param {String} key The key of the item to remove
|
348
|
+
*/
|
349
|
+
Cache.prototype.removeItem = function(key) {
|
350
|
+
var item = this.storage_.remove(key);
|
351
|
+
this.log_("removed key " + key);
|
352
|
+
|
353
|
+
// if there is a callback function, call it at the end of execution
|
354
|
+
if (item && item.options && item.options.callback) {
|
355
|
+
setTimeout(function() {
|
356
|
+
item.options.callback.call(null, item.key, item.value);
|
357
|
+
}, 0);
|
358
|
+
}
|
359
|
+
return item ? item.value : null;
|
360
|
+
};
|
361
|
+
|
362
|
+
/**
|
363
|
+
* Scan through each item in the cache and remove that item if it passes the
|
364
|
+
* supplied test.
|
365
|
+
* @param {Function} test A test to determine if the given item should be removed.
|
366
|
+
* The item will be removed if test(key, value) returns true.
|
367
|
+
*/
|
368
|
+
Cache.prototype.removeWhere = function(test) {
|
369
|
+
// Get a copy of the keys array - it won't be modified when we remove items from storage
|
370
|
+
var keys = this.storage_.keys();
|
371
|
+
for (var i = 0; i < keys.length; i++) {
|
372
|
+
var key = keys[i];
|
373
|
+
var item = this.storage_.get(key);
|
374
|
+
if(test(key, item.value) === true) {
|
375
|
+
this.removeItem(key);
|
376
|
+
}
|
377
|
+
}
|
378
|
+
};
|
379
|
+
|
380
|
+
Cache.prototype.size = function() {
|
381
|
+
return this.storage_.size();
|
382
|
+
}
|
383
|
+
|
384
|
+
|
385
|
+
/**
|
386
|
+
* @param {Object} item A cache item.
|
387
|
+
* @return {boolean} True if the item is expired
|
388
|
+
* @private
|
389
|
+
*/
|
390
|
+
Cache.prototype.isExpired_ = function(item) {
|
391
|
+
var now = new Date().getTime();
|
392
|
+
var expired = false;
|
393
|
+
if (item.options.expirationAbsolute &&
|
394
|
+
(item.options.expirationAbsolute < now)) {
|
395
|
+
// if the absolute expiration has passed, expire the item
|
396
|
+
expired = true;
|
397
|
+
}
|
398
|
+
if (!expired && item.options.expirationSliding) {
|
399
|
+
// if the sliding expiration has passed, expire the item
|
400
|
+
var lastAccess =
|
401
|
+
item.lastAccessed + (item.options.expirationSliding * 1000);
|
402
|
+
if (lastAccess < now) {
|
403
|
+
expired = true;
|
404
|
+
}
|
405
|
+
}
|
406
|
+
return expired;
|
407
|
+
};
|
408
|
+
|
409
|
+
|
410
|
+
/**
|
411
|
+
* Logs a message to the console.log if debug is set to true.
|
412
|
+
* @param {string} msg The message to log.
|
413
|
+
* @private
|
414
|
+
*/
|
415
|
+
Cache.prototype.log_ = function(msg) {
|
416
|
+
if (this.debug_) {
|
417
|
+
console.log(msg);
|
418
|
+
}
|
419
|
+
};
|
420
|
+
|
421
|
+
// Establish the root object, `window` in the browser, or `global` on the server.
|
422
|
+
var root = this;
|
423
|
+
|
424
|
+
if (typeof module !== "undefined" && module.exports) {
|
425
|
+
module.exports = Cache;
|
426
|
+
} else if (typeof define == "function" && define.amd) {
|
427
|
+
define(function() { return Cache; });
|
428
|
+
} else {
|
429
|
+
root.Cache = Cache;
|
430
|
+
}
|
431
|
+
|
432
|
+
})();
|
@@ -0,0 +1,14 @@
|
|
1
|
+
$(document).ready ->
|
2
|
+
$("input#menu-lists-filter").quickfilter("div#all-available-lists-menu li:not(.dropdown-header)")
|
3
|
+
$("a#refresh-lists-list-menu").click ->
|
4
|
+
console.log 'refreshing'
|
5
|
+
cache = new Cache(-1, false, new Cache.LocalStorageCacheStorage())
|
6
|
+
cache.clear()
|
7
|
+
e = $("div#menu-saved-lists")
|
8
|
+
e.html '...'
|
9
|
+
$.ajax e.data('url'),
|
10
|
+
success: (html_response) ->
|
11
|
+
e.html html_response
|
12
|
+
if e.data('success-callback')
|
13
|
+
eval e.data('success-callback')
|
14
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
/*
|
2
|
+
* Plugin Name: QuickFilter
|
3
|
+
* Author: Collin Henderson (collin@syropia.net)
|
4
|
+
* Version: 1.0
|
5
|
+
* © 2012, http://syropia.net
|
6
|
+
* You are welcome to freely use and modify this script in your personal and commercial products. Please don't sell it or release it as your own work. Thanks!
|
7
|
+
*/
|
8
|
+
(function($){
|
9
|
+
$.extend($.expr[':'], {missing: function (elem, index, match) {
|
10
|
+
return (elem.textContent || elem.innerText || "").toLowerCase().indexOf(match[3]) == -1;
|
11
|
+
}});
|
12
|
+
$.extend($.expr[':'], {exists: function(elem, i, match, array){
|
13
|
+
return (elem.textContent || elem.innerText || '').toLowerCase().indexOf((match[3] || "").toLowerCase()) >= 0;
|
14
|
+
}});
|
15
|
+
$.extend($.fn,{
|
16
|
+
quickfilter: function(el){
|
17
|
+
return this.each(function(){
|
18
|
+
var _this = $(this);
|
19
|
+
var query = _this.val().toLowerCase();
|
20
|
+
_this.keyup(function () {
|
21
|
+
query = $(this).val().toLowerCase();
|
22
|
+
if(query.replace(/\s/g,"") != ""){
|
23
|
+
$(el+':exists("' + query.toString() + '")').show();
|
24
|
+
$(el+':missing("' + query.toString() + '")').hide();
|
25
|
+
}
|
26
|
+
else {
|
27
|
+
$(el).show();
|
28
|
+
}
|
29
|
+
});
|
30
|
+
});
|
31
|
+
}
|
32
|
+
});
|
33
|
+
})(jQuery);
|
@@ -1,6 +1,6 @@
|
|
1
|
-
@registerEvent = (eventName,
|
1
|
+
@registerEvent = (eventName,meta_data) ->
|
2
2
|
try
|
3
|
-
mixpanel.track(eventName)
|
4
|
-
Intercom('trackEvent',eventName)
|
3
|
+
mixpanel.track(eventName,meta_data)
|
4
|
+
Intercom('trackEvent',eventName,meta_data)
|
5
5
|
catch err
|
6
6
|
console.error(err)
|
@@ -180,7 +180,7 @@ nav.navbar{max-width:1200px; background:none; margin:0 auto;}
|
|
180
180
|
#H_moduleArea .navbar-inverse .navbar-toggle:hover{ background:#266397;}
|
181
181
|
#H_moduleArea .navbar-right{margin-right:0;}
|
182
182
|
.navbar-nav li:hover .dropdown-menu { display: block; }
|
183
|
-
.navbar-nav li > a:hover{ background:#25669e;}
|
183
|
+
.navbar-inverse .navbar-nav li > a:hover{ background:#25669e;}
|
184
184
|
|
185
185
|
nav.subnav{ background:none; font-family: 'Gotham-Medium', verdana; font-weight:normal; font-size:11px; background:#f5f5f5; height: 54px;}
|
186
186
|
nav.subnav .wrapper{ max-width:1200px; margin:0 auto; overflow:hidden; position:relative;}
|
@@ -0,0 +1,44 @@
|
|
1
|
+
<li><%= link_to t('header-menu.lists.lists.new_list'), "#{APP_CONFIG['crm-url']}/contacts" %></li>
|
2
|
+
<li><%= link_to t('header-menu.lists.lists.all_lists'), "#{APP_CONFIG['crm-url']}/persistent_contact_searches" %></li>
|
3
|
+
|
4
|
+
<li class="pull-right"><a id="refresh-lists-list-menu"><span class="glyphicon glyphicon-refresh" aria-hidden="true"></span></a></li>
|
5
|
+
<li class="dropdown-header"><%= t('header-menu.lists.lists.saved_lists') %></li>
|
6
|
+
<li>
|
7
|
+
<input id="menu-lists-filter" class='form-control' type='text' placeholder='<%= t('header-menu.lists.lists.find_list') %>' />
|
8
|
+
</li>
|
9
|
+
<div id="all-available-lists-menu">
|
10
|
+
<div id="menu-saved-lists"
|
11
|
+
class="cached-async-render"
|
12
|
+
data-cache-expires-in="120"
|
13
|
+
data-cache-key="saved-lists-for-<%= current_user.current_account.name%>"
|
14
|
+
data-url="<%= APP_CONFIG['crm-url' ] %>/persistent_contact_searches/menu">
|
15
|
+
<li><a><%= image_tag 'spinner.gif' %></a></li>
|
16
|
+
</div>
|
17
|
+
<li class="dropdown-header"><%= t('header-menu.lists.lists.system_lists') %></li>
|
18
|
+
<%- %W(students former_students prospects).each do |st| -%>
|
19
|
+
<li>
|
20
|
+
<%= link_to t("header-menu.lists.contacts.#{st}"), "#{APP_CONFIG['crm-url']}/contacts/#{st}" %>
|
21
|
+
</li>
|
22
|
+
<%- end -%>
|
23
|
+
<li>
|
24
|
+
<%= link_to t('header-menu.lists.contacts.current_month_birthdays'), "#{APP_CONFIG['crm-url']}/contacts?contact_search%5Bchosen_columns%5D%5B%5D=full_name&contact_search%5Bchosen_columns%5D%5B%5D=birthday&contact_search%5Bdate_attribute%5D%5Bcategory%5D=birthday&contact_search%5Bdate_attribute%5D%5Bmonth%5D=#{Time.zone.now.month}&column=birthday&direction=asc" %>
|
25
|
+
</li>
|
26
|
+
|
27
|
+
<li class="dropdown-header"><%= t('header-menu.lists.subscription_changes.title') %></li>
|
28
|
+
|
29
|
+
<li><%= link_to t('header-menu.lists.subscription_changes.enrollments'), "#{APP_CONFIG['crm-url']}/enrollments" %></li>
|
30
|
+
<li><%= link_to t('header-menu.lists.subscription_changes.dropouts'), "#{APP_CONFIG['crm-url']}/drop_outs" %></li>
|
31
|
+
|
32
|
+
<li class="dropdown-header"><%= t('header-menu.lists.communications.title') %></li>
|
33
|
+
<li><%= link_to t('header-menu.lists.communications.all'), "#{APP_CONFIG['crm-url']}/communications" %></li>
|
34
|
+
<li><%= link_to t('header-menu.lists.communications.visits'), "#{APP_CONFIG['crm-url']}/communications/interviews" %></li>
|
35
|
+
<li><%= link_to t('header-menu.lists.communications.phonecalls'), "#{APP_CONFIG['crm-url']}/communications/phone_calls" %></li>
|
36
|
+
<li><%= link_to t('header-menu.lists.communications.emails'), "#{APP_CONFIG['crm-url']}/communications/emails" %></li>
|
37
|
+
<li><%= link_to t('header-menu.lists.communications.web'), "#{APP_CONFIG['crm-url']}/communications/web" %></li>
|
38
|
+
|
39
|
+
<li class="dropdown-header"><%= t('header-menu.lists.comments.title') %></li>
|
40
|
+
<li><%= link_to t('header-menu.lists.comments.all'), "#{APP_CONFIG['crm-url']}/comments" %></li>
|
41
|
+
<% %W(FollowUp Gestion Revisacion Reunion).each do |t| -%>
|
42
|
+
<li><%= link_to t("header-menu.lists.comments.#{t}"), "#{APP_CONFIG['crm-url']}/comments?comment_search%5Bcomment_types%5D%5B%5D=#{t}" %></li>
|
43
|
+
<% end -%>
|
44
|
+
</div>
|
@@ -12,8 +12,12 @@
|
|
12
12
|
<ul class="nav navbar-nav">
|
13
13
|
<li>
|
14
14
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><%= t('header-menu.lists.title') %> <span class="caret"></span></a>
|
15
|
-
<ul class="dropdown-menu" role="menu">
|
16
|
-
|
15
|
+
<ul id="lists-menu-drowpdown" class="dropdown-menu" role="menu">
|
16
|
+
<% if can?(:manage,:persistent_contact_searches) -%>
|
17
|
+
<%= render 'layouts/alpha_lists_list' %>
|
18
|
+
<% else -%>
|
19
|
+
<%= render 'layouts/lists_list' %>
|
20
|
+
<% end -%>
|
17
21
|
</ul>
|
18
22
|
</li>
|
19
23
|
<li> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><%= t('header-menu.stats.title') %> <span class="caret"></span></a>
|
@@ -12,6 +12,13 @@ en:
|
|
12
12
|
logout: Logout
|
13
13
|
lists:
|
14
14
|
title: Lists
|
15
|
+
lists:
|
16
|
+
new_list: New list
|
17
|
+
all_lists: All lists
|
18
|
+
find_list: Find list
|
19
|
+
saved_lists: Saved lists
|
20
|
+
system_lists: PADMA's lists
|
21
|
+
refresh: refresh lists
|
15
22
|
contacts:
|
16
23
|
title: Contacts
|
17
24
|
all: All contacts
|
@@ -12,6 +12,13 @@ es:
|
|
12
12
|
logout: Cerrar sessión
|
13
13
|
lists:
|
14
14
|
title: Listas
|
15
|
+
lists:
|
16
|
+
new_list: Nueva lista
|
17
|
+
all_lists: Todas las listas
|
18
|
+
find_list: Encontrar lista
|
19
|
+
saved_lists: Listas personalizadas
|
20
|
+
system_lists: Listas de PADMA
|
21
|
+
refresh: actualizar lista
|
15
22
|
contacts:
|
16
23
|
title: Contactos
|
17
24
|
all_contacts: Todos los contactos
|
@@ -12,6 +12,13 @@ pt-BR:
|
|
12
12
|
logout: Encerrar sessāo
|
13
13
|
lists:
|
14
14
|
title: Listas
|
15
|
+
lists:
|
16
|
+
new_list: Nova lista
|
17
|
+
all_lists: Todas as listas
|
18
|
+
find_list: Buscar lista
|
19
|
+
saved_lists: Listas personalizadas
|
20
|
+
system_lists: Listas de PADMA
|
21
|
+
refresh: atualizar listas
|
15
22
|
contacts:
|
16
23
|
title: Contatos
|
17
24
|
all_contacts: Todos os contatos
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: padma-assets
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.21
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dwayne Macgowan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-07-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|
@@ -60,8 +60,12 @@ files:
|
|
60
60
|
- app/assets/images/ie-spacer.gif
|
61
61
|
- app/assets/images/logo-padma-w.png
|
62
62
|
- app/assets/images/search.svg
|
63
|
+
- app/assets/javascripts/async_render.js.coffee.erb
|
64
|
+
- app/assets/javascripts/cache.js
|
65
|
+
- app/assets/javascripts/initialize-lists-menu.js.coffee
|
63
66
|
- app/assets/javascripts/jquery.ba-throttle-debounce.min.js
|
64
67
|
- app/assets/javascripts/jquery.gritter.min.js
|
68
|
+
- app/assets/javascripts/jquery.quickfilter.js
|
65
69
|
- app/assets/javascripts/jquery.stickyheader.js
|
66
70
|
- app/assets/javascripts/mixpanel.js
|
67
71
|
- app/assets/javascripts/notifications.js.coffee
|
@@ -85,6 +89,7 @@ files:
|
|
85
89
|
- app/assets/stylesheets/pm-modal.scss
|
86
90
|
- app/assets/stylesheets/reset.css
|
87
91
|
- app/assets/stylesheets/tables.css.scss
|
92
|
+
- app/views/layouts/_alpha_lists_list.html.erb
|
88
93
|
- app/views/layouts/_attendance_menu.html.erb
|
89
94
|
- app/views/layouts/_header.html.erb
|
90
95
|
- app/views/layouts/_lists_list.html.erb
|