From f848ea9a8f8615414a9366dc644178d4a9b1cf2c Mon Sep 17 00:00:00 2001 From: Wynne Crisman Date: Fri, 20 Oct 2017 14:54:58 -0700 Subject: [PATCH] Fixed all known bugs; Modified the menu to hide; Fixed the tables to scroll with a fixed header. --- client/main.styl | 4 + imports/api/Sale.js | 2 +- imports/api/User.js | 10 +- imports/ui/Measures.html | 52 ++--- imports/ui/Measures.import.styl | 101 ++++++---- imports/ui/Measures.js | 33 ++-- imports/ui/Pricing.html | 39 ++-- imports/ui/Pricing.import.styl | 44 ++++- imports/ui/Pricing.js | 37 ++-- imports/ui/ProductTags.html | 29 +-- imports/ui/ProductTags.import.styl | 33 +++- imports/ui/ProductTags.js | 31 +-- imports/ui/Products.html | 58 +++--- imports/ui/Products.import.styl | 116 ++++++++---- imports/ui/Products.js | 33 ++-- imports/ui/Sales.html | 30 +-- imports/ui/Sales.import.styl | 49 +++-- imports/ui/Sales.js | 31 +-- imports/ui/SalesSheetEditor.html | 4 +- imports/ui/SalesSheetEditor.js | 54 ++++-- imports/ui/SalesSheetForm.js | 25 ++- imports/ui/SalesSheets.html | 6 +- imports/ui/SalesSheets.js | 47 ++--- imports/ui/UserManagement.html | 110 +++++------ imports/ui/UserManagement.import.styl | 136 +++++++++---- imports/ui/UserManagement.js | 214 ++++++++++++--------- imports/ui/Venues.html | 50 ++--- imports/ui/Venues.import.styl | 101 ++++++---- imports/ui/Venues.js | 33 ++-- imports/ui/layouts/Body.html | 15 +- imports/ui/layouts/Body.import.styl | 263 +++++++------------------- imports/ui/layouts/Body.js | 7 + imports/util/polyfills/date.js | 31 +++ server/enhanceSaleDateFields.js | 12 +- 34 files changed, 1019 insertions(+), 821 deletions(-) diff --git a/client/main.styl b/client/main.styl index 836e2ee..001c556 100644 --- a/client/main.styl +++ b/client/main.styl @@ -153,6 +153,10 @@ body overflow: visible !important max-width: none !important +// Keep the custom scroll bars on top so they can be interacted with. They are placed outside the content div that they scroll. +.mCSB_1_scrollbar + z-index: 999 + @import "../imports/ui/styles/effects.import.styl" @import "../imports/ui/styles/buttons.import.styl" @import "../imports/ui/styles/maxHeightLayout.import.styl" diff --git a/imports/api/Sale.js b/imports/api/Sale.js index 4e6e5a1..d3319e5 100644 --- a/imports/api/Sale.js +++ b/imports/api/Sale.js @@ -296,7 +296,7 @@ if(Meteor.isServer) { comment: Match.Optional(String) }); - let dateString = date.toString(); + let dateString = sale.date.toString(); sale.createdAt = new Date(); sale.timestamp = new Date(dateString.substring(0, 4) + "-" + dateString.substring(4, 6) + "-" + dateString.substring(6, 8) + "T00:00:00Z"); diff --git a/imports/api/User.js b/imports/api/User.js index 24626e0..a405878 100644 --- a/imports/api/User.js +++ b/imports/api/User.js @@ -9,22 +9,22 @@ if(Meteor.isServer) { }); Meteor.methods({ - "insertUser": function(user, roles) { + "insertUser": function(user) { check(user, { username: String, - email: String + email: String, + roles: [String] }); - check(roles, [String]); //Verify the currently logged in user has authority to manage users. if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_MANAGE])) { //Verify the user name isn't already used. - if(Meteor.collections.Users.findOne({username: user.username}) == undefined) { + if(Meteor.collections.Users.findOne({username: user.username}) === undefined) { let pwd = Random.secret(20); let id = Accounts.createUser({password: pwd, username: user.username, email: user.email}); //Requires the alanning:roles package. - Roles.addUsersToRoles(id, roles); + Roles.addUsersToRoles(id, user.roles); } else { throw new Meteor.Error(400, "User already exists."); diff --git a/imports/ui/Measures.html b/imports/ui/Measures.html index 86beb8f..28d4ec1 100644 --- a/imports/ui/Measures.html +++ b/imports/ui/Measures.html @@ -2,32 +2,36 @@
{{#if Template.subscriptionsReady}}
- Show Hidden -
- +
+ Show Hidden +
+ +
- - Prev - Next - + +
+
+ + + + + + + + +
Name {{>MeasureSearch columnName='name'}}Postfix {{>MeasureSearch columnName='postfix'}}Actions
-
+
- - - - - - - - {{#if displayNewMeasure}} - {{> MeasureEditor isNew=true}} + {{> MeasureEditor isNew=true}} {{/if}} {{#each measures}} {{> Measure}} @@ -47,15 +51,15 @@ {{#if editing}} {{> MeasureEditor}} {{else}} - - + + {{#if hidden}} - + {{else}} {{#if deactivated}} - + {{else}} - + {{/if}} {{/if}} {{/if}} diff --git a/imports/ui/Measures.import.styl b/imports/ui/Measures.import.styl index a7d03a9..f868ff4 100644 --- a/imports/ui/Measures.import.styl +++ b/imports/ui/Measures.import.styl @@ -7,20 +7,73 @@ text-align: left .tableControls + display: table + width: 100% text-align: right margin-right: 20px - .controlLabel - font-size: 9px - font-weight: 700 - color: #5a5a5a - position: relative - top: -2px - .toggleShowHidden - margin: 0 40px 0 0 - position: relative - top: -4px - display: inline-block - + .showHidden + display: table-cell + width: 100% + .controlLabel + font-size: 9px + font-weight: 700 + color: #5a5a5a + position: relative + top: -2px + .toggleShowHidden + margin: 0 40px 0 0 + position: relative + top: -4px + display: inline-block + .contentControls + vertical-align: bottom + display: table-cell + text-align: right + min-width: 100px + a + font-size: 12px + font-family: "Arial", san-serif + font-weight: 800 + color: #2d1b8c + text-decoration: none + a:hover + text-decoration: underline + a.disabled + visibility: hidden + .table + table-layout: fixed + min-width: 100% + thead, tbody + > tr + > .name + width: 50% + min-width: 100px + > .postfix + width: 50% + min-width: 100px + > .actions + width: 90px + min-width: 90px + .separatedTableHeader + table + thead + > tr + .actions + text-align: center + .newMeasureButton + margin-top: 4px + padding: 0 12px + .fa-plus-circle + display: inline-block + .fa-times-circle + display: none + .newMeasureButton.active + background-color: #fb557b + color: black + .fa-times-circle + display: inline-block + .fa-plus-circle + display: none .listRow display: table-row .listCell @@ -57,28 +110,8 @@ select2 font-size: .4em > thead - > tr - > th.name - width: auto - > th.postfix - width: auto - > th.actions - width: 90px - text-align: center - .newMeasureButton - margin-top: 4px - padding: 0px 12px - .fa-plus-circle - display: inline-block - .fa-times-circle - display: none - .newMeasureButton.active - background-color: #fb557b - color: black - .fa-times-circle - display: inline-block - .fa-plus-circle - display: none + display: none + visibility: hidden > tbody > tr .actionRemove diff --git a/imports/ui/Measures.js b/imports/ui/Measures.js index 4b67eae..4c9dc96 100644 --- a/imports/ui/Measures.js +++ b/imports/ui/Measures.js @@ -1,7 +1,8 @@ import './Measures.html'; -let QUERY_LIMIT = 20; +let QUERY_LIMIT = 100; +let QUERY_LIMIT_INCREMENT = 100; let PREFIX = "Measures."; Tracker.autorun(function() { @@ -11,6 +12,15 @@ Tracker.autorun(function() { Template.Measures.onCreated(function() { Session.set(PREFIX + "displayNewMeasure", false); Session.set(PREFIX + "showHidden", false); + Session.set(PREFIX + "queryLimit", QUERY_LIMIT); +}); +Template.Measures.onRendered(function() { + $(".tableContainer").mCustomScrollbar({ + scrollButtons: {enable:true}, + theme: "light-thick", + scrollbarPosition: "outside", + scrollEasing: "linear" + }); }); Template.Measures.helpers({ displayNewMeasure: function() { @@ -45,23 +55,16 @@ Template.Measures.helpers({ dbQuery = dbQuery.length > 0 ? {$and: dbQuery} : {}; Session.set(PREFIX + 'measureCount', Meteor.collections.Measures.find(dbQuery).count()); //Always get a full count. - return Meteor.collections.Measures.find(dbQuery, {limit: QUERY_LIMIT, skip: skipCount, sort: {order: 1}}); + return Meteor.collections.Measures.find(dbQuery, {limit: Session.get(PREFIX + "queryLimit"), skip: skipCount, sort: {order: 1}}); }, - disablePrev: function() { - return (Session.get(PREFIX + 'skipCount') || 0) == 0; - }, - disableNext: function() { - return Session.get(PREFIX + 'measureCount') - (Session.get(PREFIX + 'skipCount') || 0) - QUERY_LIMIT <= 0; + disableLoadMore: function() { + return Session.get(PREFIX + 'measureCount') - (Session.get(PREFIX + 'skipCount') || 0) - Session.get(PREFIX + "queryLimit") <= 0; } }); Template.Measures.events({ - 'click .prevMeasures': function(event, template) { - if(!$(event.target).hasClass('disabled')) - Session.set(PREFIX + 'skipCount', Math.max(0, (Session.get(PREFIX + 'skipCount') || 0) - QUERY_LIMIT)); - }, - 'click .nextMeasures': function(event, template) { - if(!$(event.target).hasClass('disabled')) - Session.set(PREFIX + 'skipCount', (Session.get(PREFIX + 'skipCount') || 0) + QUERY_LIMIT); + 'click .loadMoreLink': function(event, template) { + event.preventDefault(); + Session.set(PREFIX + 'queryLimit', Session.get(PREFIX + "queryLimit") + QUERY_LIMIT_INCREMENT); }, 'click .newMeasureButton': function(event, template) { if(template.$('.newMeasureButton').hasClass('active')) { @@ -150,7 +153,7 @@ Template.Measure.events({ "click .actionEdit": function(event, template) { Session.set(PREFIX + "editedMeasure", this._id); Session.set(PREFIX + 'displayNewMeasure', false); //Ensure the new measure editor is closed. - template.$('.newMeasureButton').removeClass('active'); + template.parentTemplate().$('.newMeasureButton').removeClass('active'); }, "click .actionRemove": function(event, template) { Meteor.call('deactivateMeasure', this._id, function(error, result) { diff --git a/imports/ui/Pricing.html b/imports/ui/Pricing.html index f71822a..1aaf878 100644 --- a/imports/ui/Pricing.html +++ b/imports/ui/Pricing.html @@ -6,7 +6,7 @@ @@ -28,23 +28,26 @@ - - Prev - Next - + + +
+
Name {{>MeasureSearch columnName='name'}}Postfix {{>MeasureSearch columnName='postfix'}}Actions
{{name}}{{postfix}}{{name}}{{postfix}} /  /  /  /  /  /  /  / 
+ + + + + + + + +
NameCurrentChange DatePrevious
-
+
- - - - - - - - {{#each product}} {{> PricingForProduct}} @@ -61,9 +64,9 @@ \ No newline at end of file diff --git a/imports/ui/Pricing.import.styl b/imports/ui/Pricing.import.styl index d5e8573..059cea7 100644 --- a/imports/ui/Pricing.import.styl +++ b/imports/ui/Pricing.import.styl @@ -18,6 +18,8 @@ width: 240px select width: 100% + option.deactivated + color: #a6a6a6 .controlGroup padding: 4px 8px margin: 4px 8px @@ -62,7 +64,38 @@ display: inline-block .resetButton margin-left: 20px + .contentControls + vertical-align: bottom + display: table-cell + text-align: right + a + font-size: 12px + font-family: "Arial", san-serif + font-weight: 800 + color: #2d1b8c + text-decoration: none + a:hover + text-decoration: underline + a.disabled + visibility: hidden + .table + table-layout: fixed + min-width: 100% + thead, tbody + tr + > .name + width: 100% + min-width: 100px + > .current + width: 200px + min-width: 200px + > .previous + width: 200px + min-width: 200px + > .changeDate + width: 200px + min-width: 200px .listRow display: table-row .listCell @@ -85,15 +118,8 @@ table-layout: fixed width: 100% > thead - > tr - > th.name - width: auto - > th.current - width: 200px - > th.previous - width: 200px - > th.changeDate - width: 200px + visibility: hidden + display: none > tbody > tr.deactivated background-color: #fac0d1 diff --git a/imports/ui/Pricing.js b/imports/ui/Pricing.js index b15eff0..244374d 100644 --- a/imports/ui/Pricing.js +++ b/imports/ui/Pricing.js @@ -8,7 +8,8 @@ import './Pricing.html'; * Because the structure of the Product object is so complicated, the normal checking that is done by the framework cannot be used. */ -let QUERY_LIMIT = 20; +let QUERY_LIMIT = 100; +let QUERY_LIMIT_INCREMENT = 100; let PREFIX = "Pricing."; Meteor.subscribe("products"); @@ -24,14 +25,22 @@ Tracker.autorun(function() { }); Template.Pricing.onCreated(function() { + Session.set(PREFIX + "queryLimit", QUERY_LIMIT); }); Template.Pricing.onRendered(function() { this.$('input[name="date"]').val(new Date().toDateInputValue()); // this>$('select[name="measures"]').val() + + $(".tableContainer").mCustomScrollbar({ + scrollButtons: {enable:true}, + theme: "light-thick", + scrollbarPosition: "outside", + scrollEasing: "linear" + }); }); Template.Pricing.helpers({ measures: function() { - let measures = Meteor.collections.Measures.find({}, {sort: {order: 1}}).fetch(); + let measures = Meteor.collections.Measures.find({$or: [{hidden: false}, {hidden: {$exists: false}}]}, {sort: {order: 1}}).fetch(); for(let i = 0; i < measures; i++) { if(Meteor.collections.Products.find({measures: {$all: [measures[i]._id]}}, {sort: {name: 1}}).count() == 0) @@ -46,18 +55,20 @@ Template.Pricing.helpers({ let dbQuery = {measures: {$all: [measureId]}, $or: [{hidden: false}, {hidden: {$exists:false}}]}; Session.set(PREFIX + 'productCount', Meteor.collections.Products.find(dbQuery).count()); //Always get a full count. - return Meteor.collections.Products.find(dbQuery, {limit: QUERY_LIMIT, skip: skipCount, sort: {name: 1}}); + return Meteor.collections.Products.find(dbQuery, {limit: Session.get(PREFIX + "queryLimit"), skip: skipCount, sort: {name: 1}}); }, - disablePrev: function() { - return (Session.get(PREFIX + 'skipCount') || 0) == 0; - }, - disableNext: function() { - return Session.get(PREFIX + 'productCount') - (Session.get(PREFIX + 'skipCount') || 0) - QUERY_LIMIT <= 0; + disableLoadMore: function() { + return Session.get(PREFIX + 'productCount') - (Session.get(PREFIX + 'skipCount') || 0) - Session.get(PREFIX + "queryLimit") <= 0; } }); Template.Pricing.events({ + 'click .loadMoreLink': function(event, template) { + event.preventDefault(); + Session.set(PREFIX + 'queryLimit', Session.get(PREFIX + "queryLimit") + QUERY_LIMIT_INCREMENT); + }, 'change select[name="measures"]': function(event, template) { - Session.get(PREFIX + 'skipCount', 0); + Session.set(PREFIX + 'skipCount', 0); + Session.set(PREFIX + 'queryLimit', QUERY_LIMIT); Session.set(PREFIX + "selectedMeasure", $(event.target).val()); }, 'click .applyButton': function(event, template) { @@ -95,14 +106,6 @@ Template.Pricing.events({ template.$('input.price').val(0); template.$('input.date').val(new Date().toDateInputValue()); template.$('input[name="setPrevious"]').removeProp('checked'); - }, - 'click .prevProducts': function(event, template) { - if(!$(event.target).hasClass('disabled')) - Session.set(PREFIX + 'skipCount', Math.max(0, (Session.get(PREFIX + 'skipCount') || 0) - QUERY_LIMIT)); - }, - 'click .nextProducts': function(event, template) { - if(!$(event.target).hasClass('disabled')) - Session.set(PREFIX + 'skipCount', (Session.get(PREFIX + 'skipCount') || 0) + QUERY_LIMIT); } }); diff --git a/imports/ui/ProductTags.html b/imports/ui/ProductTags.html index ecbbf39..42fd498 100644 --- a/imports/ui/ProductTags.html +++ b/imports/ui/ProductTags.html @@ -20,22 +20,25 @@ {{> ProductTag}} {{/each}} - - Prev - Next - + +
+
NameCurrentChange DatePrevious
+ + + + + + +
Name {{>ProductTag_ProductSearch columnName='name'}}Tags {{>ProductTag_ProductSearch columnName='tags' collectionQueryColumnName='name' collection='ProductTags' collectionResultColumnName='_id'}}
+
-
+
- - - - - - {{#each products}} {{> ProductTag_Product}} @@ -56,8 +59,8 @@ diff --git a/imports/ui/ProductTags.import.styl b/imports/ui/ProductTags.import.styl index b368761..7a5414c 100644 --- a/imports/ui/ProductTags.import.styl +++ b/imports/ui/ProductTags.import.styl @@ -106,10 +106,32 @@ border: 0 padding: 0 margin: 0 - .pagination + .contentControls + vertical-align: bottom display: table-cell - width: 240px - vertical-align: bottom; + text-align: right + min-width: 100px + a + font-size: 12px + font-family: "Arial", san-serif + font-weight: 800 + color: #2d1b8c + text-decoration: none + a:hover + text-decoration: underline + a.disabled + visibility: hidden + .table + table-layout: fixed + min-width: 100% + thead, tbody + > tr + > .name + width: 100% + min-width: 100px + > .tags + width: 100% + min-width: 100px .listRow display: table-row .listCell @@ -132,11 +154,6 @@ table-layout: fixed width: 100% > thead - > tr - > th.name - width: auto - > th.tags - width: auto > tbody > tr.deactivated background-color: #fac0d1 diff --git a/imports/ui/ProductTags.js b/imports/ui/ProductTags.js index 6291970..f2d44d2 100644 --- a/imports/ui/ProductTags.js +++ b/imports/ui/ProductTags.js @@ -1,7 +1,8 @@ import './ProductTags.html'; -let QUERY_LIMIT = 20; +let QUERY_LIMIT = 100; +let QUERY_LIMIT_INCREMENT = 100; let PREFIX = "ProductTags."; Tracker.autorun(function() { @@ -11,6 +12,15 @@ Tracker.autorun(function() { Template.ProductTags.onCreated(function() { Session.set(PREFIX + "editTags", false); + Session.set(PREFIX + "queryLimit", QUERY_LIMIT); +}); +Template.ProductTags.onRendered(function() { + $(".tableContainer").mCustomScrollbar({ + scrollButtons: {enable:true}, + theme: "light-thick", + scrollbarPosition: "outside", + scrollEasing: "linear" + }); }); Template.ProductTags.helpers({ productTags: function() { @@ -60,13 +70,10 @@ Template.ProductTags.helpers({ //Collect a count of the products first, and store it in the session. Session.set(PREFIX + 'productCount', Meteor.collections.Products.find(dbQuery).count()); //Always get a full count. - return Meteor.collections.Products.find(dbQuery, {limit: QUERY_LIMIT, skip: skipCount, sort: {name: 1}}); + return Meteor.collections.Products.find(dbQuery, {limit: Session.get(PREFIX + "queryLimit"), skip: skipCount, sort: {name: 1}}); }, - disablePrev: function() { - return (Session.get(PREFIX + 'skipCount') || 0) == 0; - }, - disableNext: function() { - return Session.get(PREFIX + 'productCount') - (Session.get(PREFIX + 'skipCount') || 0) - QUERY_LIMIT <= 0; + disableLoadMore: function() { + return Session.get(PREFIX + 'productCount') - (Session.get(PREFIX + 'skipCount') || 0) - Session.get(PREFIX + "queryLimit") <= 0; } }); Template.ProductTags.events({ @@ -86,14 +93,10 @@ Template.ProductTags.events({ } }); }, - 'click .prevProducts': function(event, template) { - if(!$(event.target).hasClass('disabled')) - Session.set(PREFIX + 'skipCount', Math.max(0, (Session.get(PREFIX + 'skipCount') || 0) - QUERY_LIMIT)); + 'click .loadMoreLink': function(event, template) { + event.preventDefault(); + Session.set(PREFIX + 'queryLimit', Session.get(PREFIX + "queryLimit") + QUERY_LIMIT_INCREMENT); }, - 'click .nextProducts': function(event, template) { - if(!$(event.target).hasClass('disabled')) - Session.set(PREFIX + 'skipCount', (Session.get(PREFIX + 'skipCount') || 0) + QUERY_LIMIT); - } }); Template.ProductTag.onCreated(function() { diff --git a/imports/ui/Products.html b/imports/ui/Products.html index 371c1fc..9d015e7 100644 --- a/imports/ui/Products.html +++ b/imports/ui/Products.html @@ -2,31 +2,35 @@
{{#if Template.subscriptionsReady}}
- Show Hidden -
- +
+ Show Hidden +
+ +
- - Prev - Next - + +
+
+
Name {{>ProductTag_ProductSearch columnName='name'}}Tags {{>ProductTag_ProductSearch columnName='tags' collectionQueryColumnName='name' collection='ProductTags' collectionResultColumnName='_id'}}
+ + + + + + + + + +
Name {{>ProductSearch columnName='name'}}Tags {{>ProductSearch columnName='tags' collectionQueryColumnName='name' collection='ProductTags' collectionResultColumnName='_id'}}Aliases {{>ProductSearch columnName='aliases'}}Measures {{>ProductSearch columnName='measures' collectionQueryColumnName='name' collection='Measures' collectionResultColumnName='_id'}}Actions
-
+
- - - - - - - - - - {{#if displayNewProduct}} {{> ProductEditor isNew=true}} @@ -52,17 +56,17 @@ {{#if converting}} {{> ConvertProduct}} {{else}} - - - - + + + + {{#if hidden}} - + {{else}} {{#if deactivated}} - + {{else}} - + {{/if}} {{/if}} {{/if}} diff --git a/imports/ui/Products.import.styl b/imports/ui/Products.import.styl index b070679..2673ba2 100644 --- a/imports/ui/Products.import.styl +++ b/imports/ui/Products.import.styl @@ -9,18 +9,80 @@ .tableControls text-align: right margin-right: 20px - .controlLabel - font-size: 9px - font-weight: 700 - color: #5a5a5a - position: relative - top: -2px - .toggleShowHidden - margin: 0 40px 0 0 - position: relative - top: -4px - display: inline-block + margin-bottom: 4px + display: table + width: 100% + .showHidden + display: table-cell + text-align: right + width: 100% + .controlLabel + font-size: 9px + font-weight: 700 + color: #5a5a5a + position: relative + top: -2px + .toggleShowHidden + margin: 0 40px 0 0 + position: relative + top: -4px + display: inline-block + .contentControls + vertical-align: bottom + display: table-cell + text-align: right + min-width: 100px + a + font-size: 12px + font-family: "Arial", san-serif + font-weight: 800 + color: #2d1b8c + text-decoration: none + a:hover + text-decoration: underline + a.disabled + visibility: hidden + .table + table-layout: fixed + min-width: 100% + thead, tbody + > tr + > .name + //width: auto + width: 100% + > .tags + width: 220px + min-width: 220px + > .aliases + width: 220px + min-width: 220px + > .measures + width: 220px + min-width: 220px + > .actions + width: 90px + min-width: 90px + .separatedTableHeader + table + thead + > tr + > th.actions + text-align: center + .newProductButton + margin-top: 4px + padding: 0 12px + .fa-plus-circle + display: inline-block + .fa-times-circle + display: none + .newProductButton:active + background-color: #fb557b + color: black + .fa-times-circle + display: inline-block + .fa-plus-circle + display: none .listRow display: table-row .listCell @@ -40,8 +102,9 @@ font-size: 12.5px overflow-y: auto table - table-layout: fixed - width: 100% + thead + visibility: hidden + display: none .productSearch margin: 3px 0 2px 1px .productEditorTd @@ -56,33 +119,6 @@ padding-bottom: 4px select2 font-size: .4em - > thead - > tr - > th.name - width: auto - > th.tags - width: 220px - > th.aliases - width: 220px - > th.measures - width: 220px - > th.actions - width: 90px - text-align: center - .newProductButton - margin-top: 4px - padding: 0px 12px - .fa-plus-circle - display: inline-block - .fa-times-circle - display: none - .newProductButton:active - background-color: #fb557b - color: black - .fa-times-circle - display: inline-block - .fa-plus-circle - display: none > tbody > tr .actionRemove diff --git a/imports/ui/Products.js b/imports/ui/Products.js index ff37f54..9894dcc 100644 --- a/imports/ui/Products.js +++ b/imports/ui/Products.js @@ -1,7 +1,8 @@ import './Products.html'; -let QUERY_LIMIT = 20; +let QUERY_LIMIT = 100; +let QUERY_LIMIT_INCREMENT = 100; let PREFIX = "Products."; Tracker.autorun(function() { @@ -13,6 +14,15 @@ Tracker.autorun(function() { Template.Products.onCreated(function() { Session.set(PREFIX + "displayNewProduct", false); Session.set(PREFIX + "showHidden", false); + Session.set(PREFIX + "queryLimit", QUERY_LIMIT); +}); +Template.Products.onRendered(function() { + $(".tableContainer").mCustomScrollbar({ + scrollButtons: {enable:true}, + theme: "light-thick", + scrollbarPosition: "outside", + scrollEasing: "linear" + }); }); Template.Products.helpers({ displayNewProduct: function() { @@ -47,23 +57,16 @@ Template.Products.helpers({ dbQuery = dbQuery.length > 0 ? {$and: dbQuery} : {}; Session.set(PREFIX + 'productCount', Meteor.collections.Products.find(dbQuery).count()); //Always get a full count. - return Meteor.collections.Products.find(dbQuery, {limit: QUERY_LIMIT, skip: skipCount, sort: {name: 1}}); + return Meteor.collections.Products.find(dbQuery, {limit: Session.get(PREFIX + "queryLimit"), skip: skipCount, sort: {name: 1}}); }, - disablePrev: function() { - return (Session.get(PREFIX + 'skipCount') || 0) == 0; - }, - disableNext: function() { - return Session.get(PREFIX + 'productCount') - (Session.get(PREFIX + 'skipCount') || 0) - QUERY_LIMIT <= 0; + disableLoadMore: function() { + return Session.get(PREFIX + 'productCount') - (Session.get(PREFIX + 'skipCount') || 0) - Session.get(PREFIX + "queryLimit") <= 0; } }); Template.Products.events({ - 'click .prevProducts': function(event, template) { - if(!$(event.target).hasClass('disabled')) - Session.set(PREFIX + 'skipCount', Math.max(0, (Session.get(PREFIX + 'skipCount') || 0) - QUERY_LIMIT)); - }, - 'click .nextProducts': function(event, template) { - if(!$(event.target).hasClass('disabled')) - Session.set(PREFIX + 'skipCount', (Session.get(PREFIX + 'skipCount') || 0) + QUERY_LIMIT); + 'click .loadMoreLink': function(event, template) { + event.preventDefault(); + Session.set(PREFIX + 'queryLimit', Session.get(PREFIX + "queryLimit") + QUERY_LIMIT_INCREMENT); }, 'click .newProductButton': function(event, template) { if(template.$('.newProductButton').hasClass('active')) { @@ -181,7 +184,7 @@ Template.Product.events({ Session.set(PREFIX + "editedProduct", this._id); Session.set(PREFIX + 'displayNewProduct', false); //Ensure the new product editor is closed. Session.set(PREFIX + "convertedProduct", undefined); //Clear the converted product so that only one editor is open at a time. - template.$('.newProductButton').removeClass('active'); + template.parentTemplate().$('.newProductButton').removeClass('active'); }, "click .actionDeactivate": function(event, template) { Meteor.call('deactivateProduct', this._id, function(error, result) { diff --git a/imports/ui/Sales.html b/imports/ui/Sales.html index df60d11..742e0dd 100644 --- a/imports/ui/Sales.html +++ b/imports/ui/Sales.html @@ -36,18 +36,6 @@
Name {{>ProductSearch columnName='name'}}Tags {{>ProductSearch columnName='tags' collectionQueryColumnName='name' collection='ProductTags' collectionResultColumnName='_id'}}Aliases {{>ProductSearch columnName='aliases'}}Measures {{>ProductSearch columnName='measures' collectionQueryColumnName='name' collection='Measures' collectionResultColumnName='_id'}}Actions
{{name}}{{tags}}{{aliases}}{{measures}}{{name}}{{tags}}{{aliases}}{{measures}} /  /  /  /  /  /  /  /  /  / 
- - - - - - - - - - - - {{#if displayNewSale}} {{> InsertSale}} @@ -71,14 +59,14 @@ @@ -115,7 +103,7 @@