padma-assets 0.1.20 → 0.1.21
Sign up to get free protection for your applications and to get access to all the features.
- 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
|