zuora_connect_ui 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -0
  3. data/app/assets/javascripts/zuora_connect_ui.js +6 -0
  4. data/app/assets/javascripts/zuora_connect_ui/datatable.js +327 -2
  5. data/app/assets/javascripts/zuora_connect_ui/iframe.js +41 -0
  6. data/app/assets/javascripts/zuora_connect_ui/input.js +3 -2
  7. data/app/assets/stylesheets/_zuora_connect_ui.scss +3 -0
  8. data/app/assets/stylesheets/zuora_connect_ui/base.scss +5 -1
  9. data/app/assets/stylesheets/zuora_connect_ui/breadcrumb_bar.scss +15 -17
  10. data/app/assets/stylesheets/zuora_connect_ui/buttons.scss +94 -61
  11. data/app/assets/stylesheets/zuora_connect_ui/datatables.scss +71 -7
  12. data/app/assets/stylesheets/zuora_connect_ui/datepicker.scss +1 -0
  13. data/app/assets/stylesheets/zuora_connect_ui/input.scss +42 -28
  14. data/app/assets/stylesheets/zuora_connect_ui/modal.scss +41 -2
  15. data/app/assets/stylesheets/zuora_connect_ui/tabs.scss +4 -3
  16. data/app/helpers/datatable_helper.rb +0 -15
  17. data/app/views/partials/_filters.html.erb +33 -34
  18. data/app/views/partials/_table.html.erb +206 -364
  19. data/lib/zuora_connect_ui/version.rb +1 -1
  20. data/vendor/assets/contextMenu/css/jquery.contextMenu.min.css.map +1 -0
  21. data/vendor/assets/contextMenu/css/jquery.contextMenu.min.scss +16 -0
  22. data/vendor/assets/contextMenu/fonts/context-menu-icons.eot +0 -0
  23. data/vendor/assets/contextMenu/fonts/context-menu-icons.ttf +0 -0
  24. data/vendor/assets/contextMenu/fonts/context-menu-icons.woff +0 -0
  25. data/vendor/assets/contextMenu/fonts/context-menu-icons.woff2 +0 -0
  26. data/vendor/assets/contextMenu/js/jquery.contextMenu.min.js +18 -0
  27. data/vendor/assets/contextMenu/js/jquery.contextMenu.min.js.map.js +1 -0
  28. data/vendor/assets/contextMenu/js/jquery.ui.position.min.js +6 -0
  29. data/vendor/assets/idb-keyval/js/idb-keyval-iife.js +100 -0
  30. metadata +13 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b15db5e5bc714c83a7a878100b3eafb1892e01b7
4
- data.tar.gz: f51f07b1a557b601d6c74202efb7c79cf2baa762
3
+ metadata.gz: 7072ec4a018f4ee41485af010f04f3de1b2736fc
4
+ data.tar.gz: 9ef0c90e574c2691fd639b90d0e454cfc0b970c6
5
5
  SHA512:
6
- metadata.gz: 9384312078e4d703880880a154f3253201dac76f9f2534784b92d4fd7fbf412e0e2741496f8ff062bd74646a82c9e6d96150d370eaca1ccf2068976e6e3d8a4c
7
- data.tar.gz: 44264c4751c22a8f8af89684b2177757ebd0df46a23082902c252afc931a4b0a46780b7ba5dbd896c052e1d6d3605e17ea6663b85562b29006ca650ae820eca9
6
+ metadata.gz: efb0d89fc811ca6d8fff8c4a4ae61d1c706da049b4d1eac1029fa399a49a16b8a95d5c679fca9443b9b12c322f06657e41bcc68522782694464fe2c156b8396c
7
+ data.tar.gz: bc881df4198be5042ef5444e7064fc7ba16239952759c60d0166fd4fb30d013012cbcdcec4d75abf1af3ad95bd5e6c331d88568f4c67507ed5513692395fc4bd
data/README.md CHANGED
@@ -193,6 +193,8 @@ Single Select
193
193
 
194
194
  Multiple Select
195
195
 
196
+ **Multiple Select will not work with `include_blank: true`**
197
+
196
198
  ```erb
197
199
  <%= f.collection_select(:page_ids, Page.all, :id, :name, { prompt: false }, { multiple: true }) %>
198
200
  <%= f.label :page_ids, class: zuo_floating_label_class(@chapter.page_ids)%>
@@ -28,8 +28,14 @@
28
28
  //= require dataTables/extras/dataTables.colReorder
29
29
  //= require dataTables/extras/dataTables.select
30
30
  //
31
+ // contextMenu
32
+ //= require js/jquery.contextMenu.min.js
33
+ //
34
+ // IndexedDB Promise Wrapper
35
+ //= require js/idb-keyval-iife
31
36
  //
32
37
  //= require zuora_connect_ui/app
33
38
  //= require zuora_connect_ui/datatable
34
39
  //= require zuora_connect_ui/input
40
+ //= require zuora_connect_ui/iframe
35
41
  //
@@ -1,4 +1,329 @@
1
1
  // Datatables in tabs that aren't initially shown need columns resized on show
2
- $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
3
- $(this.getAttribute("href")).find('table.dataTable').each(function() { $(this).dataTable().fnAdjustColumnSizing() });
2
+ $('a[data-toggle="tab"]').on("shown.bs.tab", function(e) {
3
+ $(this.getAttribute("href"))
4
+ .find("table.dataTable")
5
+ .each(function() {
6
+ $(this)
7
+ .dataTable()
8
+ .fnAdjustColumnSizing();
9
+ });
4
10
  });
11
+
12
+ const zStorage = (function() {
13
+ const stores = {};
14
+
15
+ return {
16
+ set(key, value, table) {
17
+ if (!stores.hasOwnProperty(table)) {
18
+ stores[table] = new idbKeyval.Store(APP_NAME, table + "_table");
19
+ }
20
+ return idbKeyval.set(key, value, stores[table]);
21
+ },
22
+
23
+ get(key, table) {
24
+ if (!stores.hasOwnProperty(table)) {
25
+ stores[table] = new idbKeyval.Store(APP_NAME, table + "_table");
26
+ }
27
+ return idbKeyval.get(key, stores[table]);
28
+ }
29
+ };
30
+ })();
31
+
32
+ const DEBUG = true;
33
+
34
+ function getTableParams(tableName, settings, callback) {
35
+ const [cacheFilters, paramFilters] = settings.filters.reduce(
36
+ ([c, p], cur) => (cur.cache ? [[cur, ...c], p] : [c, [cur, ...p]]),
37
+ [[], []]
38
+ );
39
+
40
+ Promise.all(
41
+ [
42
+ zStorage.get("view", tableName),
43
+ zStorage.get("size", tableName),
44
+ zStorage.get("sort", tableName),
45
+ zStorage.get("fields", tableName)
46
+ ].concat(cacheFilters.map(f => zStorage.get(f.name + "_filter", tableName)))
47
+ ).then(v => {
48
+ const [view, size, sort, fields, ...savedFilters] = v;
49
+
50
+ cacheFilters.forEach((f, i) => setupFilter(tableName, f, savedFilters[i]));
51
+ paramFilters.forEach(f => setupFilter(tableName, f, undefined));
52
+
53
+ const visibleColumns = (fields || []).reduce(
54
+ (acc, cur) => (cur.vis ? acc.concat(cur.col) : acc),
55
+ []
56
+ );
57
+
58
+ const columns =
59
+ fields === undefined
60
+ ? settings.columns
61
+ : settings.columns
62
+ .map(c => {
63
+ const index = fields.findIndex(f => f.col === c.data);
64
+ return {
65
+ ...c,
66
+ visible: visibleColumns.includes(c.data),
67
+ sortIndex: index === -1 ? 9999 : index
68
+ };
69
+ })
70
+ .sort((a, b) => a.sortIndex - b.sortIndex);
71
+
72
+ callback(
73
+ columns,
74
+ view || settings.view,
75
+ size || settings.size,
76
+ (sort || settings.sort).map(([col, dir]) => {
77
+ const newCol = settings.columns.findIndex(c => c.data === col);
78
+ return [newCol > -1 ? newCol : 1, dir];
79
+ })
80
+ );
81
+ });
82
+ }
83
+
84
+ function setupFilter(tableName, filter, cached) {
85
+ switch (filter.type) {
86
+ case "checkbox":
87
+ return (cached === undefined ? filter.defaults : cached).forEach(v =>
88
+ $(`#${tableName}_content input[value="${v}"]`).prop("checked", true)
89
+ );
90
+ case "select":
91
+ case "group-select":
92
+ return $(`#${tableName}_content select[name="${filter.name}"]`)
93
+ .val(cached === undefined ? filter.defaults : cached)
94
+ .trigger("change");
95
+ // Is boolean used by any apps?
96
+ case "boolean":
97
+ return $(`#${tableName}_content input[name="${filter.name}"]`).prop(
98
+ "checked",
99
+ cached === undefined ? filter.defaults : cached
100
+ );
101
+ }
102
+ }
103
+
104
+ function initTable(api, tableName, settings, columns, tableFilters) {
105
+ initViewMode(api, tableName, settings.view);
106
+ initTableSize(api, tableName, settings.size);
107
+ initSortEvent(api, tableName);
108
+ initSearch(api, tableName);
109
+ initTableSelection(api, tableName);
110
+ initColumnEvents(api, tableName, columns);
111
+ initTableFilters(api, tableName, tableFilters);
112
+
113
+ $(`#${tableName}_content .table_refresh`).on("click", function(e) {
114
+ if (
115
+ $(`#${tableName}_content`).is(":visible") &&
116
+ !$(this).hasClass("zc-spin")
117
+ ) {
118
+ api.draw(false);
119
+ }
120
+ });
121
+ }
122
+
123
+ function initViewMode(api, tableName, mode) {
124
+ $(`#${tableName}_view_${mode}`).addClass("active");
125
+
126
+ const viewModeSelectors = `#${tableName}_view_table, #${tableName}_view_grid`;
127
+ $(viewModeSelectors).on("click", function(e) {
128
+ if ($(this).hasClass("active")) return;
129
+
130
+ $(viewModeSelectors).toggleClass("active");
131
+ zStorage.set("view", e.currentTarget.id.split("_")[2], tableName);
132
+ api
133
+ .draw(false)
134
+ .rows()
135
+ .deselect();
136
+ });
137
+ }
138
+
139
+ function getTableViewMode(tableName, fallback) {
140
+ if ($(`#${tableName}_view_table`).hasClass("active")) return "table";
141
+ else if ($(`#${tableName}_view_grid`).hasClass("active")) return "grid";
142
+ else return fallback;
143
+ }
144
+
145
+ function initTableSize(api, tableName, size) {
146
+ $("<select>", { id: "table_size", name: "table_size" }) // TODO: Not sure if this needs to be named
147
+ .appendTo(`#${tableName}_select_container`)
148
+ .append([10, 25, 50, 100].map(v => `<option value="${v}">${v}</option>`))
149
+ .val(size)
150
+ .select2({
151
+ minimumResultsForSearch: Infinity,
152
+ dropdownAutoWidth: true,
153
+ width: "100%"
154
+ })
155
+ .on("change", function(e) {
156
+ api.page.len(+$(this).val()).draw(false);
157
+ zStorage.set("size", +$(this).val(), tableName);
158
+ });
159
+ }
160
+
161
+ function initSortEvent(api, tableName) {
162
+ api.on("order.dt", function(e) {
163
+ zStorage.set(
164
+ "sort",
165
+ api.order().map(([col, dir]) => [api.column(col).dataSrc(), dir]),
166
+ tableName
167
+ );
168
+ });
169
+ }
170
+
171
+ function initSearch(api, tableName) {
172
+ $(`#${tableName}_search_btn`).on("click", () => {
173
+ $(`#${tableName}_search_wrapper`).toggleClass("active");
174
+ $(`#${tableName}_search`).focus();
175
+ });
176
+
177
+ let timer;
178
+ $(`#${tableName}_content input[name="table[search]"]`).keydown(function() {
179
+ clearTimeout(timer);
180
+ if ($(this).val()) {
181
+ timer = setTimeout(function() {
182
+ api.draw();
183
+ }, 700);
184
+ }
185
+ });
186
+ }
187
+
188
+ function initTableSelection(api, tableName) {
189
+ $(`#${tableName}_select_all`).on("click", function(e) {
190
+ $(this)
191
+ .find("span")
192
+ .hasClass("z-icon-addition")
193
+ ? api.rows().select()
194
+ : api.rows().deselect();
195
+ });
196
+
197
+ api.on("select.dt deselect.dt", function(e, dt, type, indexes) {
198
+ const count = dt.rows({ selected: true }).count();
199
+ $(`#${tableName}_group_actions`).toggleClass("hidden", count == 0);
200
+ $(`#${tableName}_select_all span`)
201
+ .toggleClass("z-icon-addition", count !== dt.rows().count())
202
+ .toggleClass("z-icon-subtraction", count === dt.rows().count());
203
+ if (DEBUG) {
204
+ console.log(e.type === "select" ? "Selected" : "Deselected");
205
+ console.log(dt.rows(indexes).data());
206
+ }
207
+ });
208
+ }
209
+
210
+ function initColumnEvents(api, tableName, columns) {
211
+ let dropdownReorder = false;
212
+
213
+ $(`#${tableName}_visibility_menu`)
214
+ .html(
215
+ columns.map((c, i) =>
216
+ $("<li>", { "data-key": c.data, class: "checkbox-row" }).append(
217
+ $("<div>", { class: "checkbox checkbox-primary" }).append(
218
+ $("<input>", {
219
+ type: "checkbox",
220
+ name: `${tableName}[table_column_vis][]`,
221
+ checked: !c.hasOwnProperty("visible") || c.visible,
222
+ value: i
223
+ }).on("change", function(e) {
224
+ index = api.colReorder.transpose(+$(this).val(), "toCurrent");
225
+ api.column(index).visible($(this).is(":checked"));
226
+ resize_iframe();
227
+ saveColumns();
228
+ }),
229
+ $("<label>").html(
230
+ (c.class || "").includes("actions") ? "Actions" : c.title
231
+ )
232
+ ),
233
+ $('<span class="icon z-icon-hamburger"></span>')
234
+ )
235
+ )
236
+ )
237
+ .sortable({ axis: "y" })
238
+ .on("sortstop", function(event, ui) {
239
+ if (DEBUG) console.log(`Sort Stop Trigger ${tableName}`);
240
+ dropdownReorder = true;
241
+
242
+ api.colReorder.order(
243
+ $(`#${tableName}_visibility_menu li input`)
244
+ .get()
245
+ .map(v => api.colReorder.transpose(+$(v).val(), "toCurrent"))
246
+ );
247
+ });
248
+
249
+ api.on("column-reorder", function(e, settings, details) {
250
+ if (DEBUG) console.log(`Ordering Trigger ${tableName}`, details);
251
+ saveColumns();
252
+
253
+ if (dropdownReorder) return (dropdownReorder = false);
254
+ if (DEBUG) console.log(`Ordering Trigger Rebuild DropDown ${tableName}`);
255
+
256
+ const orderedItems = api
257
+ .columns()
258
+ .dataSrc()
259
+ .toArray()
260
+ .map(v => $(`#${tableName}_visibility_menu li[data-key="${v}"]`));
261
+ $(`#${tableName}_visibility_menu`).html(orderedItems);
262
+ });
263
+
264
+ function saveColumns() {
265
+ if (DEBUG) console.log(`Save Fields ${tableName}`);
266
+
267
+ const fields = api
268
+ .columns()
269
+ .indexes()
270
+ .toArray()
271
+ .map(i => ({
272
+ col: api.column(i).dataSrc(),
273
+ vis: api.column(i).visible()
274
+ }));
275
+
276
+ zStorage.set("fields", fields, tableName);
277
+ }
278
+ }
279
+
280
+ function initTableFilters(api, tableName, tableFilters) {
281
+ tableFilters.forEach(filter => {
282
+ const cache = filter.hasOwnProperty("cache") && filter.cache;
283
+
284
+ switch (filter.type) {
285
+ case "checkbox":
286
+ return checkboxFilter(api, cache, filter);
287
+ case "select":
288
+ case "group-select":
289
+ return selectFilter(api, cache, filter);
290
+ case "boolean":
291
+ return booleanFilter(api, cache, filter);
292
+ }
293
+ });
294
+
295
+ function checkboxFilter(api, cache, filter) {
296
+ const checkboxDebounceDraw = debounce(() => {
297
+ const f = $(
298
+ `#${tableName}_content input[name="${filter.name}[]"]:checked`
299
+ )
300
+ .map((_, el) => $(el).val())
301
+ .get();
302
+ if (cache) zStorage.set(filter.name + "_filter", f, tableName);
303
+ api.draw();
304
+ }, 750);
305
+
306
+ $(`#${tableName}_content input[name="${filter.name}[]"]`).on(
307
+ "click",
308
+ checkboxDebounceDraw
309
+ );
310
+ }
311
+
312
+ function selectFilter(api, cache, filter) {
313
+ $(`#${tableName}_content select[name="${filter.name}"]`).change(function() {
314
+ const f = $(this).val();
315
+ if (cache) zStorage.set(filter.name + "_filter", f, tableName);
316
+ api.draw();
317
+ });
318
+ }
319
+
320
+ function booleanFilter(api, cache, filter) {
321
+ $(`#${tableName}_content input[name="${filter.name}"]`).change(function() {
322
+ const f = $(
323
+ `#${tableName}_content input[name="${filter.name}"]:checked`
324
+ ).val();
325
+ if (cache) zStorage.set(filter.name + "_filter", f, tableName);
326
+ api.draw();
327
+ });
328
+ }
329
+ }
@@ -0,0 +1,41 @@
1
+ $(document).on("hidden.bs.modal shown.bs.modal shown.bs.tab", resize_iframe);
2
+
3
+ let height_prev;
4
+ function resize_iframe() {
5
+ var height = 0;
6
+ if ($(".modal-dialog").height() + 100 > $("body").height()) {
7
+ height = $(".modal-dialog").height() + 100;
8
+ } else if (
9
+ $(".dropdown-menu.table_visiblity.ui-sortable:visible").height() + 150 >
10
+ $("body").height()
11
+ ) {
12
+ height =
13
+ $(".dropdown-menu.table_visiblity.ui-sortable:visible").height() + 150;
14
+ } else if ($("#canvas").is(":visible")) {
15
+ var canvas_height =
16
+ window.innerHeight -
17
+ ($("#breadcrumbs").height() + $(".green-header").height() + 20);
18
+ $("#canvas").css("height", "500px");
19
+ height = $("body").height();
20
+ } else if ($("#canvas-swimlane").is(":visible")) {
21
+ $("#canvas-swimlane").css("height", "300px");
22
+ height = $("body").height() + $("#task_data").height() - 160;
23
+ } else {
24
+ height = $("body").height() + 25;
25
+ }
26
+ if (height_prev != height) {
27
+ window.parent.postMessage({ func: "resizeIframe", height: height }, "*");
28
+ }
29
+ height_prev = height;
30
+ }
31
+
32
+ // Function to be called from iframe
33
+ function receiveMessage(event) {
34
+ if (event.origin !== window.location.origin) return;
35
+ var data = event.data;
36
+ if (typeof window[data.func] == "function") {
37
+ window[data.func].call(null, data.type, data.url);
38
+ } else {
39
+ console.log("Function not found: " + data.func);
40
+ }
41
+ }
@@ -1,9 +1,10 @@
1
1
  // 'Polyfill' for :placeholder-shown, since it's not standard yet
2
2
 
3
3
  $(document).on('focus focusout', '.zuo-textbox', function(e) {
4
- $("label[for='" + $(this).attr('id') + "']").toggleClass('floating', $(this).val() !== "");
4
+ $("label[for='" + $(this).attr('id') + "']").toggleClass('floating', $(this).val() !== "");
5
5
  });
6
6
 
7
7
  $(document).on('change.select2', 'select', function(e) {
8
- $("label[for='" + $(this).attr('id') + "']").toggleClass('floating', $(this).val() !== "");
8
+ console.log($(this).val());
9
+ $("label[for='" + $(this).attr('id') + "']").toggleClass('floating', !['', null].includes($(this).val()));
9
10
  });
@@ -113,6 +113,9 @@ $check-icon: "\E936";
113
113
  // Bootstrap Datepicker
114
114
  @import "bootstrap-datepicker";
115
115
 
116
+ // contextMenu
117
+ @import "css/jquery.contextMenu.min.scss";
118
+
116
119
  // Glyphicon and FA
117
120
  @import "css/icons.scss";
118
121
 
@@ -95,7 +95,7 @@ select {
95
95
 
96
96
  .dropdown-menu {
97
97
  min-width: 164px;
98
- padding: 6px 0;
98
+ padding: .5rem 0;
99
99
  box-shadow: 0 1px 8px -1px $neutral-shadow;
100
100
  border-radius: 0;
101
101
  font-size: 0.875rem;
@@ -115,6 +115,10 @@ select {
115
115
  // }
116
116
 
117
117
  > li {
118
+ &.checkbox-row {
119
+ padding: 0px 15px;
120
+ margin: 10px 0px;
121
+ }
118
122
  &.divider {
119
123
  margin: 0.5rem;
120
124
  }