Fixed all known bugs; Modified the menu to hide; Fixed the tables to scroll with a fixed header.
This commit is contained in:
@@ -153,6 +153,10 @@ body
|
|||||||
overflow: visible !important
|
overflow: visible !important
|
||||||
max-width: none !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/effects.import.styl"
|
||||||
@import "../imports/ui/styles/buttons.import.styl"
|
@import "../imports/ui/styles/buttons.import.styl"
|
||||||
@import "../imports/ui/styles/maxHeightLayout.import.styl"
|
@import "../imports/ui/styles/maxHeightLayout.import.styl"
|
||||||
|
|||||||
@@ -296,7 +296,7 @@ if(Meteor.isServer) {
|
|||||||
comment: Match.Optional(String)
|
comment: Match.Optional(String)
|
||||||
});
|
});
|
||||||
|
|
||||||
let dateString = date.toString();
|
let dateString = sale.date.toString();
|
||||||
|
|
||||||
sale.createdAt = new Date();
|
sale.createdAt = new Date();
|
||||||
sale.timestamp = new Date(dateString.substring(0, 4) + "-" + dateString.substring(4, 6) + "-" + dateString.substring(6, 8) + "T00:00:00Z");
|
sale.timestamp = new Date(dateString.substring(0, 4) + "-" + dateString.substring(4, 6) + "-" + dateString.substring(6, 8) + "T00:00:00Z");
|
||||||
|
|||||||
@@ -9,22 +9,22 @@ if(Meteor.isServer) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Meteor.methods({
|
Meteor.methods({
|
||||||
"insertUser": function(user, roles) {
|
"insertUser": function(user) {
|
||||||
check(user, {
|
check(user, {
|
||||||
username: String,
|
username: String,
|
||||||
email: String
|
email: String,
|
||||||
|
roles: [String]
|
||||||
});
|
});
|
||||||
check(roles, [String]);
|
|
||||||
|
|
||||||
//Verify the currently logged in user has authority to manage users.
|
//Verify the currently logged in user has authority to manage users.
|
||||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_MANAGE])) {
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_MANAGE])) {
|
||||||
//Verify the user name isn't already used.
|
//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 pwd = Random.secret(20);
|
||||||
let id = Accounts.createUser({password: pwd, username: user.username, email: user.email});
|
let id = Accounts.createUser({password: pwd, username: user.username, email: user.email});
|
||||||
|
|
||||||
//Requires the alanning:roles package.
|
//Requires the alanning:roles package.
|
||||||
Roles.addUsersToRoles(id, roles);
|
Roles.addUsersToRoles(id, user.roles);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new Meteor.Error(400, "User already exists.");
|
throw new Meteor.Error(400, "User already exists.");
|
||||||
|
|||||||
@@ -2,20 +2,19 @@
|
|||||||
<div id="measures">
|
<div id="measures">
|
||||||
{{#if Template.subscriptionsReady}}
|
{{#if Template.subscriptionsReady}}
|
||||||
<div class="tableControls">
|
<div class="tableControls">
|
||||||
|
<div class="showHidden">
|
||||||
<span class="controlLabel">Show Hidden</span>
|
<span class="controlLabel">Show Hidden</span>
|
||||||
<div class="toggleShowHidden checkbox checkbox-slider--b-flat">
|
<div class="toggleShowHidden checkbox checkbox-slider--b-flat">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" name="showHidden"><span></span>
|
<input type="checkbox" name="showHidden"><span></span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<span class="pagination">
|
|
||||||
<span class="prevMeasures noselect {{#if disablePrev}}disabled{{/if}}"><i class="fa fa-long-arrow-left" aria-hidden="true"></i> Prev</span>
|
|
||||||
<span class="nextMeasures noselect {{#if disableNext}}disabled{{/if}}">Next <i class="fa fa-long-arrow-right" aria-hidden="true"></i></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="listRow">
|
<div class="contentControls">
|
||||||
<div class="listCell">
|
<a class="loadMoreLink {{#if disableLoadMore}}disabled{{/if}}" href="javascript:">Load More...</a>
|
||||||
<div class="tableContainer">
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="separatedTableHeader">
|
||||||
<table class="table table-striped table-hover">
|
<table class="table table-striped table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -23,11 +22,16 @@
|
|||||||
<th class="postfix">Postfix {{>MeasureSearch columnName='postfix'}}</th>
|
<th class="postfix">Postfix {{>MeasureSearch columnName='postfix'}}</th>
|
||||||
<th class="actions">Actions <span class="newMeasureButton btn btn-success"><i class="fa fa-plus-circle" aria-hidden="true"></i><i class="fa fa-times-circle" aria-hidden="true"></i></span></th>
|
<th class="actions">Actions <span class="newMeasureButton btn btn-success"><i class="fa fa-plus-circle" aria-hidden="true"></i><i class="fa fa-times-circle" aria-hidden="true"></i></span></th>
|
||||||
</tr>
|
</tr>
|
||||||
<!--<button type="button" name="newMeasureButton"><i class="fa fa-plus-circle" aria-hidden="true"></i></button>-->
|
|
||||||
</thead>
|
</thead>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="listRow">
|
||||||
|
<div class="listCell">
|
||||||
|
<div class="tableContainer mCustomScrollbar" data-mcs-theme="dark">
|
||||||
|
<table class="table table-striped table-hover">
|
||||||
<tbody>
|
<tbody>
|
||||||
{{#if displayNewMeasure}}
|
{{#if displayNewMeasure}}
|
||||||
{{> MeasureEditor isNew=true}}
|
<tr>{{> MeasureEditor isNew=true}}</tr>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#each measures}}
|
{{#each measures}}
|
||||||
{{> Measure}}
|
{{> Measure}}
|
||||||
@@ -47,15 +51,15 @@
|
|||||||
{{#if editing}}
|
{{#if editing}}
|
||||||
{{> MeasureEditor}}
|
{{> MeasureEditor}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<td class="noselect nonclickable left">{{name}}</td>
|
<td class="name noselect nonclickable left">{{name}}</td>
|
||||||
<td class="noselect nonclickable left">{{postfix}}</td>
|
<td class="postfix noselect nonclickable left">{{postfix}}</td>
|
||||||
{{#if hidden}}
|
{{#if hidden}}
|
||||||
<td class="center"><i class="actionEdit fa fa-pencil-square-o fa-lg noselect clickable" title="Edit" aria-hidden="true"></i> / <i class="actionShow fa fa-eye fa-lg noselect clickable" title="Show" aria-hidden="true"></i></td>
|
<td class="actions center"><i class="actionEdit fa fa-pencil-square-o fa-lg noselect clickable" title="Edit" aria-hidden="true"></i> / <i class="actionShow fa fa-eye fa-lg noselect clickable" title="Show" aria-hidden="true"></i></td>
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#if deactivated}}
|
{{#if deactivated}}
|
||||||
<td class="center"><i class="actionEdit fa fa-pencil-square-o fa-lg noselect clickable" title="Edit" aria-hidden="true"></i> / <i class="actionActivate fa fa-toggle-on fa-lg noselect clickable" title="Activate" aria-hidden="true"></i> / <i class="actionHide fa fa-eye-slash fa-lg noselect clickable" title="Hide" aria-hidden="true"></i></td>
|
<td class="actions center"><i class="actionEdit fa fa-pencil-square-o fa-lg noselect clickable" title="Edit" aria-hidden="true"></i> / <i class="actionActivate fa fa-toggle-on fa-lg noselect clickable" title="Activate" aria-hidden="true"></i> / <i class="actionHide fa fa-eye-slash fa-lg noselect clickable" title="Hide" aria-hidden="true"></i></td>
|
||||||
{{else}}
|
{{else}}
|
||||||
<td class="center"><i class="actionEdit fa fa-pencil-square-o fa-lg noselect clickable" title="Edit" aria-hidden="true"></i> / <i class="actionRemove fa fa-times-circle fa-lg noselect clickable" title="Deactivate" aria-hidden="true"></i></td>
|
<td class="actions center"><i class="actionEdit fa fa-pencil-square-o fa-lg noselect clickable" title="Edit" aria-hidden="true"></i> / <i class="actionRemove fa fa-times-circle fa-lg noselect clickable" title="Deactivate" aria-hidden="true"></i></td>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|||||||
77
imports/ui/Measures.import.styl
vendored
77
imports/ui/Measures.import.styl
vendored
@@ -7,8 +7,13 @@
|
|||||||
text-align: left
|
text-align: left
|
||||||
|
|
||||||
.tableControls
|
.tableControls
|
||||||
|
display: table
|
||||||
|
width: 100%
|
||||||
text-align: right
|
text-align: right
|
||||||
margin-right: 20px
|
margin-right: 20px
|
||||||
|
.showHidden
|
||||||
|
display: table-cell
|
||||||
|
width: 100%
|
||||||
.controlLabel
|
.controlLabel
|
||||||
font-size: 9px
|
font-size: 9px
|
||||||
font-weight: 700
|
font-weight: 700
|
||||||
@@ -20,7 +25,55 @@
|
|||||||
position: relative
|
position: relative
|
||||||
top: -4px
|
top: -4px
|
||||||
display: inline-block
|
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
|
.listRow
|
||||||
display: table-row
|
display: table-row
|
||||||
.listCell
|
.listCell
|
||||||
@@ -57,28 +110,8 @@
|
|||||||
select2
|
select2
|
||||||
font-size: .4em
|
font-size: .4em
|
||||||
> thead
|
> 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
|
> tbody
|
||||||
> tr
|
> tr
|
||||||
.actionRemove
|
.actionRemove
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
|
|
||||||
import './Measures.html';
|
import './Measures.html';
|
||||||
|
|
||||||
let QUERY_LIMIT = 20;
|
let QUERY_LIMIT = 100;
|
||||||
|
let QUERY_LIMIT_INCREMENT = 100;
|
||||||
let PREFIX = "Measures.";
|
let PREFIX = "Measures.";
|
||||||
|
|
||||||
Tracker.autorun(function() {
|
Tracker.autorun(function() {
|
||||||
@@ -11,6 +12,15 @@ Tracker.autorun(function() {
|
|||||||
Template.Measures.onCreated(function() {
|
Template.Measures.onCreated(function() {
|
||||||
Session.set(PREFIX + "displayNewMeasure", false);
|
Session.set(PREFIX + "displayNewMeasure", false);
|
||||||
Session.set(PREFIX + "showHidden", 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({
|
Template.Measures.helpers({
|
||||||
displayNewMeasure: function() {
|
displayNewMeasure: function() {
|
||||||
@@ -45,23 +55,16 @@ Template.Measures.helpers({
|
|||||||
|
|
||||||
dbQuery = dbQuery.length > 0 ? {$and: dbQuery} : {};
|
dbQuery = dbQuery.length > 0 ? {$and: dbQuery} : {};
|
||||||
Session.set(PREFIX + 'measureCount', Meteor.collections.Measures.find(dbQuery).count()); //Always get a full count.
|
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() {
|
disableLoadMore: function() {
|
||||||
return (Session.get(PREFIX + 'skipCount') || 0) == 0;
|
return Session.get(PREFIX + 'measureCount') - (Session.get(PREFIX + 'skipCount') || 0) - Session.get(PREFIX + "queryLimit") <= 0;
|
||||||
},
|
|
||||||
disableNext: function() {
|
|
||||||
return Session.get(PREFIX + 'measureCount') - (Session.get(PREFIX + 'skipCount') || 0) - QUERY_LIMIT <= 0;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Template.Measures.events({
|
Template.Measures.events({
|
||||||
'click .prevMeasures': function(event, template) {
|
'click .loadMoreLink': function(event, template) {
|
||||||
if(!$(event.target).hasClass('disabled'))
|
event.preventDefault();
|
||||||
Session.set(PREFIX + 'skipCount', Math.max(0, (Session.get(PREFIX + 'skipCount') || 0) - QUERY_LIMIT));
|
Session.set(PREFIX + 'queryLimit', Session.get(PREFIX + "queryLimit") + QUERY_LIMIT_INCREMENT);
|
||||||
},
|
|
||||||
'click .nextMeasures': function(event, template) {
|
|
||||||
if(!$(event.target).hasClass('disabled'))
|
|
||||||
Session.set(PREFIX + 'skipCount', (Session.get(PREFIX + 'skipCount') || 0) + QUERY_LIMIT);
|
|
||||||
},
|
},
|
||||||
'click .newMeasureButton': function(event, template) {
|
'click .newMeasureButton': function(event, template) {
|
||||||
if(template.$('.newMeasureButton').hasClass('active')) {
|
if(template.$('.newMeasureButton').hasClass('active')) {
|
||||||
@@ -150,7 +153,7 @@ Template.Measure.events({
|
|||||||
"click .actionEdit": function(event, template) {
|
"click .actionEdit": function(event, template) {
|
||||||
Session.set(PREFIX + "editedMeasure", this._id);
|
Session.set(PREFIX + "editedMeasure", this._id);
|
||||||
Session.set(PREFIX + 'displayNewMeasure', false); //Ensure the new measure editor is closed.
|
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) {
|
"click .actionRemove": function(event, template) {
|
||||||
Meteor.call('deactivateMeasure', this._id, function(error, result) {
|
Meteor.call('deactivateMeasure', this._id, function(error, result) {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<label class='controlLabel'>Selected Measure: </label>
|
<label class='controlLabel'>Selected Measure: </label>
|
||||||
<select name="measures">
|
<select name="measures">
|
||||||
{{#each measures}}
|
{{#each measures}}
|
||||||
<option value="{{_id}}">{{name}}</option>
|
<option class="{{#if deactivated}}deactivated{{/if}}" value="{{_id}}">{{name}}</option>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
@@ -28,14 +28,11 @@
|
|||||||
<input type="date" class="form-control" name="date" data-schema-key='date' required>
|
<input type="date" class="form-control" name="date" data-schema-key='date' required>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span class="pagination">
|
<div class="contentControls">
|
||||||
<span class="prevProducts noselect {{#if disablePrev}}disabled{{/if}}"><i class="fa fa-long-arrow-left" aria-hidden="true"></i> Prev</span>
|
<a class="loadMoreLink {{#if disableLoadMore}}disabled{{/if}}" href="javascript:">Load More...</a>
|
||||||
<span class="nextProducts noselect {{#if disableNext}}disabled{{/if}}">Next <i class="fa fa-long-arrow-right" aria-hidden="true"></i></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="listRow">
|
</div>
|
||||||
<div class="listCell">
|
<div class="separatedTableHeader">
|
||||||
<div class="tableContainer">
|
|
||||||
<table class="table table-striped table-hover">
|
<table class="table table-striped table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -45,6 +42,12 @@
|
|||||||
<th class="previous">Previous</th>
|
<th class="previous">Previous</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="listRow">
|
||||||
|
<div class="listCell">
|
||||||
|
<div class="tableContainer mCustomScrollbar" data-mcs-theme="dark">
|
||||||
|
<table class="table table-striped table-hover">
|
||||||
<tbody>
|
<tbody>
|
||||||
{{#each product}}
|
{{#each product}}
|
||||||
{{> PricingForProduct}}
|
{{> PricingForProduct}}
|
||||||
@@ -61,9 +64,9 @@
|
|||||||
|
|
||||||
<template name="PricingForProduct">
|
<template name="PricingForProduct">
|
||||||
<tr class="clickable noselect {{rowClass}}">
|
<tr class="clickable noselect {{rowClass}}">
|
||||||
<td class="tdLarge noselect nonclickable left">{{name}}</td>
|
<td class="name tdLarge noselect nonclickable left">{{name}}</td>
|
||||||
<td class="tdLarge noselect nonclickable left">{{currentPrice}}</td>
|
<td class="current tdLarge noselect nonclickable left">{{currentPrice}}</td>
|
||||||
<td class="tdLarge noselect nonclickable left">{{priceChangeDate}}</td>
|
<td class="changeDate tdLarge noselect nonclickable left">{{priceChangeDate}}</td>
|
||||||
<td class="tdLarge noselect nonclickable left">{{previousPrice}}</td>
|
<td class="previous tdLarge noselect nonclickable left">{{previousPrice}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
44
imports/ui/Pricing.import.styl
vendored
44
imports/ui/Pricing.import.styl
vendored
@@ -18,6 +18,8 @@
|
|||||||
width: 240px
|
width: 240px
|
||||||
select
|
select
|
||||||
width: 100%
|
width: 100%
|
||||||
|
option.deactivated
|
||||||
|
color: #a6a6a6
|
||||||
.controlGroup
|
.controlGroup
|
||||||
padding: 4px 8px
|
padding: 4px 8px
|
||||||
margin: 4px 8px
|
margin: 4px 8px
|
||||||
@@ -62,7 +64,38 @@
|
|||||||
display: inline-block
|
display: inline-block
|
||||||
.resetButton
|
.resetButton
|
||||||
margin-left: 20px
|
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
|
.listRow
|
||||||
display: table-row
|
display: table-row
|
||||||
.listCell
|
.listCell
|
||||||
@@ -85,15 +118,8 @@
|
|||||||
table-layout: fixed
|
table-layout: fixed
|
||||||
width: 100%
|
width: 100%
|
||||||
> thead
|
> thead
|
||||||
> tr
|
visibility: hidden
|
||||||
> th.name
|
display: none
|
||||||
width: auto
|
|
||||||
> th.current
|
|
||||||
width: 200px
|
|
||||||
> th.previous
|
|
||||||
width: 200px
|
|
||||||
> th.changeDate
|
|
||||||
width: 200px
|
|
||||||
> tbody
|
> tbody
|
||||||
> tr.deactivated
|
> tr.deactivated
|
||||||
background-color: #fac0d1
|
background-color: #fac0d1
|
||||||
|
|||||||
@@ -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.
|
* 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.";
|
let PREFIX = "Pricing.";
|
||||||
|
|
||||||
Meteor.subscribe("products");
|
Meteor.subscribe("products");
|
||||||
@@ -24,14 +25,22 @@ Tracker.autorun(function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Template.Pricing.onCreated(function() {
|
Template.Pricing.onCreated(function() {
|
||||||
|
Session.set(PREFIX + "queryLimit", QUERY_LIMIT);
|
||||||
});
|
});
|
||||||
Template.Pricing.onRendered(function() {
|
Template.Pricing.onRendered(function() {
|
||||||
this.$('input[name="date"]').val(new Date().toDateInputValue());
|
this.$('input[name="date"]').val(new Date().toDateInputValue());
|
||||||
// this>$('select[name="measures"]').val()
|
// this>$('select[name="measures"]').val()
|
||||||
|
|
||||||
|
$(".tableContainer").mCustomScrollbar({
|
||||||
|
scrollButtons: {enable:true},
|
||||||
|
theme: "light-thick",
|
||||||
|
scrollbarPosition: "outside",
|
||||||
|
scrollEasing: "linear"
|
||||||
|
});
|
||||||
});
|
});
|
||||||
Template.Pricing.helpers({
|
Template.Pricing.helpers({
|
||||||
measures: function() {
|
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++) {
|
for(let i = 0; i < measures; i++) {
|
||||||
if(Meteor.collections.Products.find({measures: {$all: [measures[i]._id]}}, {sort: {name: 1}}).count() == 0)
|
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}}]};
|
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.
|
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() {
|
disableLoadMore: function() {
|
||||||
return (Session.get(PREFIX + 'skipCount') || 0) == 0;
|
return Session.get(PREFIX + 'productCount') - (Session.get(PREFIX + 'skipCount') || 0) - Session.get(PREFIX + "queryLimit") <= 0;
|
||||||
},
|
|
||||||
disableNext: function() {
|
|
||||||
return Session.get(PREFIX + 'productCount') - (Session.get(PREFIX + 'skipCount') || 0) - QUERY_LIMIT <= 0;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Template.Pricing.events({
|
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) {
|
'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());
|
Session.set(PREFIX + "selectedMeasure", $(event.target).val());
|
||||||
},
|
},
|
||||||
'click .applyButton': function(event, template) {
|
'click .applyButton': function(event, template) {
|
||||||
@@ -95,14 +106,6 @@ Template.Pricing.events({
|
|||||||
template.$('input.price').val(0);
|
template.$('input.price').val(0);
|
||||||
template.$('input.date').val(new Date().toDateInputValue());
|
template.$('input.date').val(new Date().toDateInputValue());
|
||||||
template.$('input[name="setPrevious"]').removeProp('checked');
|
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);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -20,15 +20,12 @@
|
|||||||
{{> ProductTag}}
|
{{> ProductTag}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</span>
|
</span>
|
||||||
<span class="pagination">
|
<div class="contentControls">
|
||||||
<span class="prevProducts noselect {{#if disablePrev}}disabled{{/if}}"><i class="fa fa-long-arrow-left" aria-hidden="true"></i> Prev</span>
|
<a class="loadMoreLink {{#if disableLoadMore}}disabled{{/if}}" href="javascript:">Load More...</a>
|
||||||
<span class="nextProducts noselect {{#if disableNext}}disabled{{/if}}">Next <i class="fa fa-long-arrow-right" aria-hidden="true"></i></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="listRow">
|
</div>
|
||||||
<div class="listCell">
|
<div class="separatedTableHeader">
|
||||||
<div class="tableContainer">
|
|
||||||
<table class="table table-striped table-hover">
|
<table class="table table-striped table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -36,6 +33,12 @@
|
|||||||
<th class="tags">Tags {{>ProductTag_ProductSearch columnName='tags' collectionQueryColumnName='name' collection='ProductTags' collectionResultColumnName='_id'}}</th>
|
<th class="tags">Tags {{>ProductTag_ProductSearch columnName='tags' collectionQueryColumnName='name' collection='ProductTags' collectionResultColumnName='_id'}}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="listRow">
|
||||||
|
<div class="listCell">
|
||||||
|
<div class="tableContainer mCustomScrollbar" data-mcs-theme="dark">
|
||||||
|
<table class="table table-striped table-hover">
|
||||||
<tbody>
|
<tbody>
|
||||||
{{#each products}}
|
{{#each products}}
|
||||||
{{> ProductTag_Product}}
|
{{> ProductTag_Product}}
|
||||||
@@ -56,8 +59,8 @@
|
|||||||
|
|
||||||
<template name="ProductTag_Product">
|
<template name="ProductTag_Product">
|
||||||
<tr class="{{rowClass}}">
|
<tr class="{{rowClass}}">
|
||||||
<td class="tdLarge noselect nonclickable left">{{name}}</td>
|
<td class="name tdLarge noselect nonclickable left">{{name}}</td>
|
||||||
<td class="tdLarge noselect nonclickable left">{{tags}}</td>
|
<td class="tags tdLarge noselect nonclickable left">{{tags}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
33
imports/ui/ProductTags.import.styl
vendored
33
imports/ui/ProductTags.import.styl
vendored
@@ -106,10 +106,32 @@
|
|||||||
border: 0
|
border: 0
|
||||||
padding: 0
|
padding: 0
|
||||||
margin: 0
|
margin: 0
|
||||||
.pagination
|
.contentControls
|
||||||
|
vertical-align: bottom
|
||||||
display: table-cell
|
display: table-cell
|
||||||
width: 240px
|
text-align: right
|
||||||
vertical-align: bottom;
|
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
|
.listRow
|
||||||
display: table-row
|
display: table-row
|
||||||
.listCell
|
.listCell
|
||||||
@@ -132,11 +154,6 @@
|
|||||||
table-layout: fixed
|
table-layout: fixed
|
||||||
width: 100%
|
width: 100%
|
||||||
> thead
|
> thead
|
||||||
> tr
|
|
||||||
> th.name
|
|
||||||
width: auto
|
|
||||||
> th.tags
|
|
||||||
width: auto
|
|
||||||
> tbody
|
> tbody
|
||||||
> tr.deactivated
|
> tr.deactivated
|
||||||
background-color: #fac0d1
|
background-color: #fac0d1
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
|
|
||||||
import './ProductTags.html';
|
import './ProductTags.html';
|
||||||
|
|
||||||
let QUERY_LIMIT = 20;
|
let QUERY_LIMIT = 100;
|
||||||
|
let QUERY_LIMIT_INCREMENT = 100;
|
||||||
let PREFIX = "ProductTags.";
|
let PREFIX = "ProductTags.";
|
||||||
|
|
||||||
Tracker.autorun(function() {
|
Tracker.autorun(function() {
|
||||||
@@ -11,6 +12,15 @@ Tracker.autorun(function() {
|
|||||||
|
|
||||||
Template.ProductTags.onCreated(function() {
|
Template.ProductTags.onCreated(function() {
|
||||||
Session.set(PREFIX + "editTags", false);
|
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({
|
Template.ProductTags.helpers({
|
||||||
productTags: function() {
|
productTags: function() {
|
||||||
@@ -60,13 +70,10 @@ Template.ProductTags.helpers({
|
|||||||
//Collect a count of the products first, and store it in the session.
|
//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.
|
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() {
|
disableLoadMore: function() {
|
||||||
return (Session.get(PREFIX + 'skipCount') || 0) == 0;
|
return Session.get(PREFIX + 'productCount') - (Session.get(PREFIX + 'skipCount') || 0) - Session.get(PREFIX + "queryLimit") <= 0;
|
||||||
},
|
|
||||||
disableNext: function() {
|
|
||||||
return Session.get(PREFIX + 'productCount') - (Session.get(PREFIX + 'skipCount') || 0) - QUERY_LIMIT <= 0;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Template.ProductTags.events({
|
Template.ProductTags.events({
|
||||||
@@ -86,14 +93,10 @@ Template.ProductTags.events({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
'click .prevProducts': function(event, template) {
|
'click .loadMoreLink': function(event, template) {
|
||||||
if(!$(event.target).hasClass('disabled'))
|
event.preventDefault();
|
||||||
Session.set(PREFIX + 'skipCount', Math.max(0, (Session.get(PREFIX + 'skipCount') || 0) - QUERY_LIMIT));
|
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() {
|
Template.ProductTag.onCreated(function() {
|
||||||
|
|||||||
@@ -2,20 +2,19 @@
|
|||||||
<div id="products">
|
<div id="products">
|
||||||
{{#if Template.subscriptionsReady}}
|
{{#if Template.subscriptionsReady}}
|
||||||
<div class="tableControls">
|
<div class="tableControls">
|
||||||
|
<div class="showHidden">
|
||||||
<span class="controlLabel">Show Hidden</span>
|
<span class="controlLabel">Show Hidden</span>
|
||||||
<div class="toggleShowHidden checkbox checkbox-slider--b-flat">
|
<div class="toggleShowHidden checkbox checkbox-slider--b-flat">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" name="showHidden"><span></span>
|
<input type="checkbox" name="showHidden"><span></span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<span class="pagination">
|
|
||||||
<span class="prevProducts noselect {{#if disablePrev}}disabled{{/if}}"><i class="fa fa-long-arrow-left" aria-hidden="true"></i> Prev</span>
|
|
||||||
<span class="nextProducts noselect {{#if disableNext}}disabled{{/if}}">Next <i class="fa fa-long-arrow-right" aria-hidden="true"></i></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="listRow">
|
<div class="contentControls">
|
||||||
<div class="listCell">
|
<a class="loadMoreLink {{#if disableLoadMore}}disabled{{/if}}" href="javascript:">Load More...</a>
|
||||||
<div class="tableContainer">
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="separatedTableHeader">
|
||||||
<table class="table table-striped table-hover">
|
<table class="table table-striped table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -25,8 +24,13 @@
|
|||||||
<th class="measures">Measures {{>ProductSearch columnName='measures' collectionQueryColumnName='name' collection='Measures' collectionResultColumnName='_id'}}</th>
|
<th class="measures">Measures {{>ProductSearch columnName='measures' collectionQueryColumnName='name' collection='Measures' collectionResultColumnName='_id'}}</th>
|
||||||
<th class="actions">Actions <span class="newProductButton btn btn-success"><i class="fa fa-plus-circle" aria-hidden="true"></i><i class="fa fa-times-circle" aria-hidden="true"></i></span></th>
|
<th class="actions">Actions <span class="newProductButton btn btn-success"><i class="fa fa-plus-circle" aria-hidden="true"></i><i class="fa fa-times-circle" aria-hidden="true"></i></span></th>
|
||||||
</tr>
|
</tr>
|
||||||
<!--<button type="button" name="newProductButton"><i class="fa fa-plus-circle" aria-hidden="true"></i></button>-->
|
|
||||||
</thead>
|
</thead>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="listRow">
|
||||||
|
<div class="listCell">
|
||||||
|
<div class="tableContainer mCustomScrollbar" data-mcs-theme="dark">
|
||||||
|
<table class="table table-striped table-hover">
|
||||||
<tbody>
|
<tbody>
|
||||||
{{#if displayNewProduct}}
|
{{#if displayNewProduct}}
|
||||||
{{> ProductEditor isNew=true}}
|
{{> ProductEditor isNew=true}}
|
||||||
@@ -52,17 +56,17 @@
|
|||||||
{{#if converting}}
|
{{#if converting}}
|
||||||
{{> ConvertProduct}}
|
{{> ConvertProduct}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<td class="noselect nonclickable left">{{name}}</td>
|
<td class="name noselect nonclickable left">{{name}}</td>
|
||||||
<td class="noselect nonclickable left">{{tags}}</td>
|
<td class="tags noselect nonclickable left">{{tags}}</td>
|
||||||
<td class="noselect nonclickable left">{{aliases}}</td>
|
<td class="aliases noselect nonclickable left">{{aliases}}</td>
|
||||||
<td class="noselect nonclickable left">{{measures}}</td>
|
<td class="measures noselect nonclickable left">{{measures}}</td>
|
||||||
{{#if hidden}}
|
{{#if hidden}}
|
||||||
<td class="center"><i class="actionEdit fa fa-pencil-square-o fa-lg noselect clickable" title="Edit" aria-hidden="true"></i> / <i class="actionShow fa fa-eye fa-lg noselect clickable" title="Show" aria-hidden="true"></i> / <i class="actionConvert fa fa-exclamation-triangle fa-lg noselect clickable" title="Convert" aria-hidden="true"></i></td>
|
<td class="actions center"><i class="actionEdit fa fa-pencil-square-o fa-lg noselect clickable" title="Edit" aria-hidden="true"></i> / <i class="actionShow fa fa-eye fa-lg noselect clickable" title="Show" aria-hidden="true"></i> / <i class="actionConvert fa fa-exclamation-triangle fa-lg noselect clickable" title="Convert" aria-hidden="true"></i></td>
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#if deactivated}}
|
{{#if deactivated}}
|
||||||
<td class="center"><i class="actionEdit fa fa-pencil-square-o fa-lg noselect clickable" title="Edit" aria-hidden="true"></i> / <i class="actionActivate fa fa-toggle-on fa-lg noselect clickable" title="Activate" aria-hidden="true"></i> / <i class="actionHide fa fa-eye-slash fa-lg noselect clickable" title="Hide" aria-hidden="true"></i></td>
|
<td class="actions center"><i class="actionEdit fa fa-pencil-square-o fa-lg noselect clickable" title="Edit" aria-hidden="true"></i> / <i class="actionActivate fa fa-toggle-on fa-lg noselect clickable" title="Activate" aria-hidden="true"></i> / <i class="actionHide fa fa-eye-slash fa-lg noselect clickable" title="Hide" aria-hidden="true"></i></td>
|
||||||
{{else}}
|
{{else}}
|
||||||
<td class="center"><i class="actionEdit fa fa-pencil-square-o fa-lg noselect clickable" title="Edit" aria-hidden="true"></i> / <i class="actionDeactivate fa fa-times-circle fa-lg noselect clickable" title="Deactivate" aria-hidden="true"></i></td>
|
<td class="actions center"><i class="actionEdit fa fa-pencil-square-o fa-lg noselect clickable" title="Edit" aria-hidden="true"></i> / <i class="actionDeactivate fa fa-times-circle fa-lg noselect clickable" title="Deactivate" aria-hidden="true"></i></td>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|||||||
94
imports/ui/Products.import.styl
vendored
94
imports/ui/Products.import.styl
vendored
@@ -9,6 +9,13 @@
|
|||||||
.tableControls
|
.tableControls
|
||||||
text-align: right
|
text-align: right
|
||||||
margin-right: 20px
|
margin-right: 20px
|
||||||
|
margin-bottom: 4px
|
||||||
|
display: table
|
||||||
|
width: 100%
|
||||||
|
.showHidden
|
||||||
|
display: table-cell
|
||||||
|
text-align: right
|
||||||
|
width: 100%
|
||||||
.controlLabel
|
.controlLabel
|
||||||
font-size: 9px
|
font-size: 9px
|
||||||
font-weight: 700
|
font-weight: 700
|
||||||
@@ -20,7 +27,62 @@
|
|||||||
position: relative
|
position: relative
|
||||||
top: -4px
|
top: -4px
|
||||||
display: inline-block
|
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
|
.listRow
|
||||||
display: table-row
|
display: table-row
|
||||||
.listCell
|
.listCell
|
||||||
@@ -40,8 +102,9 @@
|
|||||||
font-size: 12.5px
|
font-size: 12.5px
|
||||||
overflow-y: auto
|
overflow-y: auto
|
||||||
table
|
table
|
||||||
table-layout: fixed
|
thead
|
||||||
width: 100%
|
visibility: hidden
|
||||||
|
display: none
|
||||||
.productSearch
|
.productSearch
|
||||||
margin: 3px 0 2px 1px
|
margin: 3px 0 2px 1px
|
||||||
.productEditorTd
|
.productEditorTd
|
||||||
@@ -56,33 +119,6 @@
|
|||||||
padding-bottom: 4px
|
padding-bottom: 4px
|
||||||
select2
|
select2
|
||||||
font-size: .4em
|
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
|
> tbody
|
||||||
> tr
|
> tr
|
||||||
.actionRemove
|
.actionRemove
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
|
|
||||||
import './Products.html';
|
import './Products.html';
|
||||||
|
|
||||||
let QUERY_LIMIT = 20;
|
let QUERY_LIMIT = 100;
|
||||||
|
let QUERY_LIMIT_INCREMENT = 100;
|
||||||
let PREFIX = "Products.";
|
let PREFIX = "Products.";
|
||||||
|
|
||||||
Tracker.autorun(function() {
|
Tracker.autorun(function() {
|
||||||
@@ -13,6 +14,15 @@ Tracker.autorun(function() {
|
|||||||
Template.Products.onCreated(function() {
|
Template.Products.onCreated(function() {
|
||||||
Session.set(PREFIX + "displayNewProduct", false);
|
Session.set(PREFIX + "displayNewProduct", false);
|
||||||
Session.set(PREFIX + "showHidden", 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({
|
Template.Products.helpers({
|
||||||
displayNewProduct: function() {
|
displayNewProduct: function() {
|
||||||
@@ -47,23 +57,16 @@ Template.Products.helpers({
|
|||||||
|
|
||||||
dbQuery = dbQuery.length > 0 ? {$and: dbQuery} : {};
|
dbQuery = dbQuery.length > 0 ? {$and: dbQuery} : {};
|
||||||
Session.set(PREFIX + 'productCount', Meteor.collections.Products.find(dbQuery).count()); //Always get a full count.
|
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() {
|
disableLoadMore: function() {
|
||||||
return (Session.get(PREFIX + 'skipCount') || 0) == 0;
|
return Session.get(PREFIX + 'productCount') - (Session.get(PREFIX + 'skipCount') || 0) - Session.get(PREFIX + "queryLimit") <= 0;
|
||||||
},
|
|
||||||
disableNext: function() {
|
|
||||||
return Session.get(PREFIX + 'productCount') - (Session.get(PREFIX + 'skipCount') || 0) - QUERY_LIMIT <= 0;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Template.Products.events({
|
Template.Products.events({
|
||||||
'click .prevProducts': function(event, template) {
|
'click .loadMoreLink': function(event, template) {
|
||||||
if(!$(event.target).hasClass('disabled'))
|
event.preventDefault();
|
||||||
Session.set(PREFIX + 'skipCount', Math.max(0, (Session.get(PREFIX + 'skipCount') || 0) - QUERY_LIMIT));
|
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);
|
|
||||||
},
|
},
|
||||||
'click .newProductButton': function(event, template) {
|
'click .newProductButton': function(event, template) {
|
||||||
if(template.$('.newProductButton').hasClass('active')) {
|
if(template.$('.newProductButton').hasClass('active')) {
|
||||||
@@ -181,7 +184,7 @@ Template.Product.events({
|
|||||||
Session.set(PREFIX + "editedProduct", this._id);
|
Session.set(PREFIX + "editedProduct", this._id);
|
||||||
Session.set(PREFIX + 'displayNewProduct', false); //Ensure the new product editor is closed.
|
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.
|
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) {
|
"click .actionDeactivate": function(event, template) {
|
||||||
Meteor.call('deactivateProduct', this._id, function(error, result) {
|
Meteor.call('deactivateProduct', this._id, function(error, result) {
|
||||||
|
|||||||
@@ -36,18 +36,6 @@
|
|||||||
<div class="listCell">
|
<div class="listCell">
|
||||||
<div class="tableContainer mCustomScrollbar" data-mcs-theme="dark">
|
<div class="tableContainer mCustomScrollbar" data-mcs-theme="dark">
|
||||||
<table class="table table-striped table-hover">
|
<table class="table table-striped table-hover">
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class="amount"></th>
|
|
||||||
<th class="product"></th>
|
|
||||||
<th class="price"></th>
|
|
||||||
<th class="measure"></th>
|
|
||||||
<th class="saleDate"></th>
|
|
||||||
<th class="createdDate"></th>
|
|
||||||
<th class="venue"></th>
|
|
||||||
<th class="actions"></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
<tbody>
|
||||||
{{#if displayNewSale}}
|
{{#if displayNewSale}}
|
||||||
{{> InsertSale}}
|
{{> InsertSale}}
|
||||||
@@ -71,14 +59,14 @@
|
|||||||
|
|
||||||
<template name="Sale">
|
<template name="Sale">
|
||||||
<tr>
|
<tr>
|
||||||
<td class="tdLarge noselect nonclickable center">{{amount}}</td>
|
<td class="amount tdLarge noselect nonclickable center">{{amount}}</td>
|
||||||
<td class="tdLarge noselect nonclickable left">{{productName productId}}</td>
|
<td class="product tdLarge noselect nonclickable left">{{productName productId}}</td>
|
||||||
<td class="tdLarge noselect nonclickable left">{{formatPrice price}}{{#if showTotalPrice amount}} ({{formatTotalPrice price amount}}){{/if}}</td>
|
<td class="price tdLarge noselect nonclickable left">{{formatPrice price}}{{#if showTotalPrice amount}} ({{formatTotalPrice price amount}}){{/if}}</td>
|
||||||
<td class="tdLarge noselect nonclickable left">{{measureName measureId}}</td>
|
<td class="measure tdLarge noselect nonclickable left">{{measureName measureId}}</td>
|
||||||
<td class="tdLarge noselect nonclickable left">{{formatDateAndWeek date}}</td>
|
<td class="saleDate tdLarge noselect nonclickable left">{{formatDateAndWeek date weekOfYear}}</td>
|
||||||
<td class="tdLarge noselect nonclickable left">{{formatDateTime createdAt}}</td>
|
<td class="createdDate tdLarge noselect nonclickable left">{{formatDateTime createdAt}}</td>
|
||||||
<td class="tdLarge noselect nonclickable left">{{venueName venueId}}</td>
|
<td class="venue tdLarge noselect nonclickable left">{{venueName venueId}}</td>
|
||||||
<td class="tdLarge noselect left"><i class="fa fa-pencil-square-o fa-lg actionEdit noselect clickable" title="Edit" aria-hidden="true"></i> <i class="fa fa-commenting fa-lg editComment noselect clickable {{commentClass}}" aria-hidden="true"></i> <i class="fa fa-times-circle fa-lg saleRemove noselect clickable" aria-hidden="true"></i></td>
|
<td class="actions tdLarge noselect left"><i class="fa fa-pencil-square-o fa-lg actionEdit noselect clickable" title="Edit" aria-hidden="true"></i> <i class="fa fa-commenting fa-lg editComment noselect clickable {{commentClass}}" aria-hidden="true"></i> <i class="fa fa-times-circle fa-lg saleRemove noselect clickable" aria-hidden="true"></i></td>
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -115,7 +103,7 @@
|
|||||||
<template name="InsertSale">
|
<template name="InsertSale">
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="8">
|
<td colspan="8">
|
||||||
<form class="insertSaleForm" autocomplete="off">
|
<form name="insertSaleForm" class="insertSaleForm" autocomplete="off">
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<div class="col-4-12">
|
<div class="col-4-12">
|
||||||
<div class="formGroupHeading">New Sale</div>
|
<div class="formGroupHeading">New Sale</div>
|
||||||
|
|||||||
49
imports/ui/Sales.import.styl
vendored
49
imports/ui/Sales.import.styl
vendored
@@ -22,37 +22,44 @@
|
|||||||
.table
|
.table
|
||||||
table-layout: fixed
|
table-layout: fixed
|
||||||
min-width: 100%
|
min-width: 100%
|
||||||
thead
|
thead, tbody
|
||||||
> tr
|
> tr
|
||||||
> th.amount
|
> .amount
|
||||||
width: 90px
|
width: 90px
|
||||||
> th.product
|
min-width: 90px
|
||||||
width: auto
|
> .product
|
||||||
|
width: 100%
|
||||||
min-width: 140px
|
min-width: 140px
|
||||||
> th.price
|
> .price
|
||||||
width: 140px
|
width: 140px
|
||||||
> th.measure
|
min-width: 140px
|
||||||
|
> .measure
|
||||||
width: 100px
|
width: 100px
|
||||||
> th.saleDate
|
min-width: 100px
|
||||||
width: 140px
|
> .saleDate
|
||||||
> th.createdDate
|
width: 150px
|
||||||
|
min-width: 150px
|
||||||
|
> .createdDate
|
||||||
width: 100px
|
width: 100px
|
||||||
> th.venue
|
min-width: 100px
|
||||||
|
> .venue
|
||||||
width: 160px
|
width: 160px
|
||||||
> th.actions
|
min-width: 160px
|
||||||
|
> .actions
|
||||||
width: 90px
|
width: 90px
|
||||||
|
min-width: 90px
|
||||||
.separatedTableHeader
|
.separatedTableHeader
|
||||||
table
|
table
|
||||||
thead
|
thead
|
||||||
> tr
|
> tr
|
||||||
> th.actions
|
> th.actions
|
||||||
.newSaleButton
|
.newSaleButton
|
||||||
padding: 0px 12px
|
padding: 0 12px
|
||||||
.fa-plus-circle
|
.fa-plus-circle
|
||||||
display: inline-block
|
display: inline-block
|
||||||
.fa-times-circle
|
.fa-times-circle
|
||||||
display: none
|
display: none
|
||||||
.newSaleButton:active
|
.newSaleButton.active
|
||||||
background-color: #fb557b
|
background-color: #fb557b
|
||||||
color: black
|
color: black
|
||||||
.fa-times-circle
|
.fa-times-circle
|
||||||
@@ -67,6 +74,9 @@
|
|||||||
text-shadow: 0px 0px 10px #ff6d1f
|
text-shadow: 0px 0px 10px #ff6d1f
|
||||||
.showOnlyComments.on
|
.showOnlyComments.on
|
||||||
color: white
|
color: white
|
||||||
|
> th.saleDate
|
||||||
|
input
|
||||||
|
width: 130px
|
||||||
.listRow
|
.listRow
|
||||||
display: table-row
|
display: table-row
|
||||||
.listCell
|
.listCell
|
||||||
@@ -82,16 +92,16 @@
|
|||||||
right: 0
|
right: 0
|
||||||
width: auto
|
width: auto
|
||||||
height: auto
|
height: auto
|
||||||
//width: 100%
|
|
||||||
//margin-bottom: 20px
|
|
||||||
border: 0
|
border: 0
|
||||||
font-size: 12.5px
|
font-size: 12.5px
|
||||||
overflow-y: scroll
|
overflow-y: scroll
|
||||||
//height: 100%
|
|
||||||
label
|
label
|
||||||
font-size: 10px
|
font-size: 10px
|
||||||
font-weight: 800
|
font-weight: 800
|
||||||
table
|
table
|
||||||
|
thead
|
||||||
|
visibility: hidden
|
||||||
|
display: none
|
||||||
.saleRemove
|
.saleRemove
|
||||||
color: red
|
color: red
|
||||||
margin-left: 8px
|
margin-left: 8px
|
||||||
@@ -102,9 +112,10 @@
|
|||||||
color: green
|
color: green
|
||||||
.editorCancel
|
.editorCancel
|
||||||
color: red
|
color: red
|
||||||
thead
|
.saleDate
|
||||||
visibility: hidden
|
text-align: left
|
||||||
display: none
|
.createdDate
|
||||||
|
text-align: left
|
||||||
.editComment
|
.editComment
|
||||||
color: grey
|
color: grey
|
||||||
.hasComment
|
.hasComment
|
||||||
|
|||||||
@@ -38,18 +38,12 @@ Template.Sales.onCreated(function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
Template.Sales.onRendered(function() {
|
Template.Sales.onRendered(function() {
|
||||||
//$('.tableContainer').mCustomScrollbar();
|
|
||||||
$(".tableContainer").mCustomScrollbar({
|
$(".tableContainer").mCustomScrollbar({
|
||||||
scrollButtons: {enable:true},
|
scrollButtons: {enable:true},
|
||||||
theme: "light-thick",
|
theme: "light-thick",
|
||||||
scrollbarPosition:"outside"
|
scrollbarPosition: "outside",
|
||||||
|
scrollEasing: "linear"
|
||||||
});
|
});
|
||||||
//(function($){
|
|
||||||
// $(window).on("load",function(){
|
|
||||||
// $(".tableContainer").mCustomScrollbar();
|
|
||||||
// });
|
|
||||||
//})(jQuery);
|
|
||||||
//$('#test').mCustomScrollbar();
|
|
||||||
});
|
});
|
||||||
Template.Sales.onDestroyed(function() {
|
Template.Sales.onDestroyed(function() {
|
||||||
if(Template.Sales.salesSubscription) {
|
if(Template.Sales.salesSubscription) {
|
||||||
@@ -85,6 +79,11 @@ Template.Sales.events({
|
|||||||
else {
|
else {
|
||||||
Session.set(PREFIX + 'displayNewSale', true);
|
Session.set(PREFIX + 'displayNewSale', true);
|
||||||
Session.set(PREFIX + "editedSale", undefined); //Clear the edited sale so that only one editor is open at a time.
|
Session.set(PREFIX + "editedSale", undefined); //Clear the edited sale so that only one editor is open at a time.
|
||||||
|
|
||||||
|
//Set the focus to the date field of the form. Put this in a timeout so that it is queued for processing after the form is added to the DOM.
|
||||||
|
setTimeout(function() {
|
||||||
|
$("form[name='insertSaleForm'] input[name='date']").focus();
|
||||||
|
}, 10);
|
||||||
}
|
}
|
||||||
template.$('.newSaleButton').toggleClass('active');
|
template.$('.newSaleButton').toggleClass('active');
|
||||||
},
|
},
|
||||||
@@ -123,8 +122,8 @@ Template.Sale.helpers({
|
|||||||
productName: function(id) {
|
productName: function(id) {
|
||||||
return Meteor.collections.Products.findOne({_id: id}, {fields: {name: 1}}).name;
|
return Meteor.collections.Products.findOne({_id: id}, {fields: {name: 1}}).name;
|
||||||
},
|
},
|
||||||
formatDateAndWeek: function(date) {
|
formatDateAndWeek: function(date, weekOfYear) {
|
||||||
return moment.utc(date.toString(), "YYYYMMDD").utc().format("MM/DD/YYYY (w)");
|
return moment.utc(date.toString(), "YYYYMMDD").utc().format("MM/DD/YYYY") + "(" + weekOfYear + ")";
|
||||||
},
|
},
|
||||||
formatDateTime: function(date) {
|
formatDateTime: function(date) {
|
||||||
return moment.utc(date).format("MM/DD/YYYY");
|
return moment.utc(date).format("MM/DD/YYYY");
|
||||||
@@ -146,7 +145,7 @@ Template.Sale.events({
|
|||||||
"click .actionEdit": function(event, template) {
|
"click .actionEdit": function(event, template) {
|
||||||
Session.set(PREFIX + "editedSale", this._id);
|
Session.set(PREFIX + "editedSale", this._id);
|
||||||
Session.set(PREFIX + 'displayNewSale', false); //Ensure the new sale editor is closed.
|
Session.set(PREFIX + 'displayNewSale', false); //Ensure the new sale editor is closed.
|
||||||
template.$('.newSaleButton').removeClass('active');
|
template.parentTemplate().$('.newSaleButton').removeClass('active');
|
||||||
},
|
},
|
||||||
"click .saleRemove": function(event, template) {
|
"click .saleRemove": function(event, template) {
|
||||||
let _this = this;
|
let _this = this;
|
||||||
@@ -441,7 +440,6 @@ Template.InsertSale.events({
|
|||||||
if(error) sAlert.error("Failed to insert the sale!\n" + error);
|
if(error) sAlert.error("Failed to insert the sale!\n" + error);
|
||||||
else {
|
else {
|
||||||
sAlert.success("Sale Created");
|
sAlert.success("Sale Created");
|
||||||
nextMeasure.find(".amount").val(0);
|
|
||||||
|
|
||||||
//Clear the measure quantity fields so the user can enter another sale without the quantities already set.
|
//Clear the measure quantity fields so the user can enter another sale without the quantities already set.
|
||||||
for(let next = 0; next < insertSaleMeasures.length; next++) {
|
for(let next = 0; next < insertSaleMeasures.length; next++) {
|
||||||
@@ -449,6 +447,11 @@ Template.InsertSale.events({
|
|||||||
|
|
||||||
nextMeasure.find(".amount").val(0);
|
nextMeasure.find(".amount").val(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Set the focus to the product field of the form.
|
||||||
|
$("form[name='insertSaleForm'] input[name='product']").focus();
|
||||||
|
//Clear the product since it is highly unlikely the same product will be added twice for the same date and market.
|
||||||
|
$("form[name='insertSaleForm'] input[name='product']").val("");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,7 +70,7 @@
|
|||||||
<template name="SalesSheetEditorConfigurationRow">
|
<template name="SalesSheetEditorConfigurationRow">
|
||||||
{{#if isProduct}} {{! PRODUCT }}
|
{{#if isProduct}} {{! PRODUCT }}
|
||||||
<div class="product columnContent noselect" data-model="{{productId}}">
|
<div class="product columnContent noselect" data-model="{{productId}}">
|
||||||
<div class="name clickable">{{name}}</div>
|
<div class="name clickable"></div>
|
||||||
<div class="nameEditor"><input class="form-control" name="name" type="text" tabindex="1" value="{{name}}"/> <i class="fa fa-check-circle accept" aria-hidden="true"></i> <i class="fa fa-times-circle reject" aria-hidden="true"></i></div>
|
<div class="nameEditor"><input class="form-control" name="name" type="text" tabindex="1" value="{{name}}"/> <i class="fa fa-check-circle accept" aria-hidden="true"></i> <i class="fa fa-times-circle reject" aria-hidden="true"></i></div>
|
||||||
{{#if showMeasures}}
|
{{#if showMeasures}}
|
||||||
<div class="measures">
|
<div class="measures">
|
||||||
@@ -82,7 +82,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{{else}} {{! HEADING }}
|
{{else}} {{! HEADING }}
|
||||||
<div class="heading columnContent noselect">
|
<div class="heading columnContent noselect">
|
||||||
<div class="headingNameRow"><span class="name clickable">{{name}}</span><span class="sort clickable noselect"><i class="fa fa-arrow-down" aria-hidden="true"></i> sort <i class="fa fa-arrow-up" aria-hidden="true"></i></span></div>
|
<div class="headingNameRow"><span class="name clickable"></span><span class="sort clickable noselect"><i class="fa fa-arrow-down" aria-hidden="true"></i> sort <i class="fa fa-arrow-up" aria-hidden="true"></i></span></div>
|
||||||
<div class="nameEditor"><input class="form-control" name="name" type="text" tabindex="1" value="{{name}}"/> <i class="fa fa-check-circle accept" aria-hidden="true"></i> <i class="fa fa-times-circle reject" aria-hidden="true"></i></div>
|
<div class="nameEditor"><input class="form-control" name="name" type="text" tabindex="1" value="{{name}}"/> <i class="fa fa-check-circle accept" aria-hidden="true"></i> <i class="fa fa-times-circle reject" aria-hidden="true"></i></div>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|||||||
@@ -354,6 +354,40 @@ Template.SalesSheetEditorConfigurationRow.onCreated(function() {
|
|||||||
template.$('.product .name').text(name);
|
template.$('.product .name').text(name);
|
||||||
template.$('.product .nameEditor, .product .name').removeClass('edit');
|
template.$('.product .nameEditor, .product .name').removeClass('edit');
|
||||||
};
|
};
|
||||||
|
this.handleHeadingSort = function(event) {
|
||||||
|
let width = event.currentTarget.offsetWidth;
|
||||||
|
let x = event.pageX - event.currentTarget.offsetLeft;
|
||||||
|
let sortAlphabetical = x <= (width / 2);
|
||||||
|
let headingIndex = template.$(event.target).closest(".heading").index();
|
||||||
|
let firstIndex = headingIndex + 1;
|
||||||
|
let products = template.parentTemplate(1).salesSheet.products;
|
||||||
|
let length = 0;
|
||||||
|
|
||||||
|
while(firstIndex + length < products.length && products[firstIndex + length].productId) {
|
||||||
|
length++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Sort the part of the array that contains products under the sorted heading.
|
||||||
|
products.partialSort(firstIndex, length, function(a, b) {
|
||||||
|
return sortAlphabetical ? (a.name < b.name ? -1 : 1) : (a.name > b.name ? -1 : 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
//Notify anything depending on the products list that they have been modified.
|
||||||
|
template.parentTemplate(1).productsDependency.changed();
|
||||||
|
};
|
||||||
|
});
|
||||||
|
Template.SalesSheetEditorConfigurationRow.onRendered(function() {
|
||||||
|
let template = this;
|
||||||
|
|
||||||
|
Tracker.autorun(function() {
|
||||||
|
let data = Blaze.getData(template.view);
|
||||||
|
|
||||||
|
template.parentTemplate(1).productsDependency.depend();
|
||||||
|
|
||||||
|
if(data) {
|
||||||
|
template.$('.heading .name, .product .name').text(data.name);
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
Template.SalesSheetEditorConfigurationRow.helpers({
|
Template.SalesSheetEditorConfigurationRow.helpers({
|
||||||
measureName: function(measureId) {
|
measureName: function(measureId) {
|
||||||
@@ -436,24 +470,6 @@ Template.SalesSheetEditorConfigurationRow.events({
|
|||||||
this.measureIds.add(measureId);
|
this.measureIds.add(measureId);
|
||||||
},
|
},
|
||||||
'click .heading .sort': function(event, template) {
|
'click .heading .sort': function(event, template) {
|
||||||
let width = event.currentTarget.offsetWidth;
|
template.handleHeadingSort(event);
|
||||||
let x = event.pageX - event.currentTarget.offsetLeft;
|
|
||||||
let sortAlphabetical = x <= (width / 2);
|
|
||||||
let headingIndex = template.$(event.target).closest(".heading").index();
|
|
||||||
let firstIndex = headingIndex + 1;
|
|
||||||
let products = template.parentTemplate(1).salesSheet.products;
|
|
||||||
let length = 0;
|
|
||||||
|
|
||||||
while(firstIndex + length < products.length && products[firstIndex + length].productId) {
|
|
||||||
length++;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Sort the part of the array that contains products under the sorted heading.
|
|
||||||
products.partialSort(firstIndex, length, function(a, b) {
|
|
||||||
return sortAlphabetical ? (a.name < b.name ? -1 : 1) : (a.name > b.name ? -1 : 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
//Notify anything depending on the products list that they have been modified.
|
|
||||||
template.parentTemplate(1).productsDependency.changed();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -29,19 +29,28 @@ Template.SalesSheetForm.onCreated(function() {
|
|||||||
// Place the sales sheet in a reactive var and put the setting of the reactive var in an autorun.
|
// Place the sales sheet in a reactive var and put the setting of the reactive var in an autorun.
|
||||||
// The autorun is needed apparently to ensure changes to the data force a change in the reactive var.
|
// The autorun is needed apparently to ensure changes to the data force a change in the reactive var.
|
||||||
Tracker.autorun(function() {
|
Tracker.autorun(function() {
|
||||||
|
let data = Blaze.getData(template.view);
|
||||||
|
//****
|
||||||
|
// Note: I have commented the code below out because I was unable to get Meteor to properly (according to their docs on Template.currentData() being reactive) call my code when the template's input data changes.
|
||||||
|
// Because of this I have instead used the parent template's session variable "selectedSheet" to detect and handle the template data changing.
|
||||||
|
// To avoid session variable conflicts, I have been using a session variable name prefix that is the template's name followed by a '.' as a convention.
|
||||||
|
//****
|
||||||
|
|
||||||
//Force this to be reactive on the current data.
|
//Force this to be reactive on the current data.
|
||||||
try {
|
//try {
|
||||||
Template.currentData();
|
// Template.currentData();
|
||||||
} catch(err) {
|
//} catch(err) {
|
||||||
// Ignore it. This always has an error accessing the currentData as the template is destroyed.
|
// // Ignore it. This always has an error accessing the currentData as the template is destroyed.
|
||||||
}
|
//}
|
||||||
|
|
||||||
//For some reason the current data is not always set, and does not always equal the template.data. We will use the template.data to get the actual ID of the sales sheet for the query.
|
//For some reason the current data is not always set, and does not always equal the template.data. We will use the template.data to get the actual ID of the sales sheet for the query.
|
||||||
template.salesSheet.set(Meteor.collections.SalesSheets.findOne(template.data));
|
//template.salesSheet.set(Template.instance() ? Meteor.collections.SalesSheets.findOne(Template.currentData()) : null);
|
||||||
|
//template.salesSheet.set(Session.get("SalesSheets." + "selectedSheet"));
|
||||||
|
template.salesSheet.set(Meteor.collections.SalesSheets.findOne(data));
|
||||||
});
|
});
|
||||||
|
|
||||||
Tracker.autorun(function() {
|
Tracker.autorun(function() {
|
||||||
let products = template.salesSheet.get().products;
|
let products = template.salesSheet.get() ? template.salesSheet.get().products : [];
|
||||||
let index = 1;
|
let index = 1;
|
||||||
|
|
||||||
// Note: We will ignore orphaned data in the dictionary so we don't have to clear the dictionary, or identify the orphans. The orphans are just a few extra product id's mapped to booleans, and should be fairly rare anyway.
|
// Note: We will ignore orphaned data in the dictionary so we don't have to clear the dictionary, or identify the orphans. The orphans are just a few extra product id's mapped to booleans, and should be fairly rare anyway.
|
||||||
@@ -103,7 +112,7 @@ Template.SalesSheetForm.events({
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
template.$('.sheetHeader').data('bs.validator').validate(function(isValid) {
|
template.$('.sheetHeader').data('bs.validator').validate(function(isValid) {
|
||||||
if(isValid) {
|
if(isValid) {
|
||||||
let date = template.selectedDate.get();
|
let date = ~~(moment(template.selectedDate.get()).format("YYYYMMDD"));
|
||||||
let venueId = template.selectedVenue.get()._id;
|
let venueId = template.selectedVenue.get()._id;
|
||||||
// Track the inserts and errors, display output to the user and log when everything is done.
|
// Track the inserts and errors, display output to the user and log when everything is done.
|
||||||
let insertMetadata = {
|
let insertMetadata = {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
<label style="margin-right: 10px">Selected Sheet</label>
|
<label style="margin-right: 10px">Selected Sheet</label>
|
||||||
<select name="sheetSelection" class="form-control">
|
<select name="sheetSelection" class="form-control">
|
||||||
{{#each sheets}}
|
{{#each sheets}}
|
||||||
<option value="{{_id}}" {{sheetsSelectIsSelected this isFirst}}>{{name}}</option>
|
<option value="{{_id}}" {{isSheetSelected}}>{{name}}</option>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</select>
|
</select>
|
||||||
<i class="fa fa-wrench editSheet noselect clickable {{#if disableButtons}}disabled{{/if}} {{#if isEditingSheet}}selected{{/if}}" aria-hidden="true">
|
<i class="fa fa-wrench editSheet noselect clickable {{#if disableButtons}}disabled{{/if}} {{#if isEditingSheet}}selected{{/if}}" aria-hidden="true">
|
||||||
@@ -27,8 +27,8 @@
|
|||||||
<div class="separator" style="width: 50%; opacity: .25"></div>
|
<div class="separator" style="width: 50%; opacity: .25"></div>
|
||||||
</section>
|
</section>
|
||||||
<section class="tabSection verticalStack vscExpand">
|
<section class="tabSection verticalStack vscExpand">
|
||||||
{{#if isSheetSelected}}
|
{{#if hasSelectedSheet}}
|
||||||
{{>Template.dynamic template=tab data=tabData}}
|
{{>Template.dynamic template=activeTemplateName data=selectedSheetId}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
@@ -15,7 +15,7 @@ Template.SalesSheets.onCreated(function() {
|
|||||||
Template.SalesSheets.onDestroyed(function() {
|
Template.SalesSheets.onDestroyed(function() {
|
||||||
// Reset the view's session variables used for navigation.
|
// Reset the view's session variables used for navigation.
|
||||||
Session.set(PREFIX + "currentFormName", undefined);
|
Session.set(PREFIX + "currentFormName", undefined);
|
||||||
Session.set(PREFIX + "tab", undefined);
|
Session.set(PREFIX + "activeTemplateName", undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
//******************************************************************
|
//******************************************************************
|
||||||
@@ -24,10 +24,11 @@ Template.SalesSheets.onDestroyed(function() {
|
|||||||
Template.SalesSheetsMain.onCreated(function() {
|
Template.SalesSheetsMain.onCreated(function() {
|
||||||
//Save the previous session state - whether we are editing the selected sheet.
|
//Save the previous session state - whether we are editing the selected sheet.
|
||||||
//The name of the currently active page tab. This will either be the SalesSheetForm or the SalesSheetEditor.
|
//The name of the currently active page tab. This will either be the SalesSheetForm or the SalesSheetEditor.
|
||||||
if(!Session.get(PREFIX + "tab")) Session.set(PREFIX + "tab", "SalesSheetForm");
|
if(!Session.get(PREFIX + "activeTemplateName")) Session.set(PREFIX + "activeTemplateName", "SalesSheetForm");
|
||||||
if(!Session.get(PREFIX + 'selectedSheet')) {
|
|
||||||
Session.set(PREFIX + 'selectedSheet', Meteor.collections.SalesSheets.findOne({}, {sort: {name: 1}}));
|
this.sheets = Meteor.collections.SalesSheets.find({}, {sort: {name: 1}});
|
||||||
}
|
let sheetArray = this.sheets.fetch();
|
||||||
|
Session.set(PREFIX + 'selectedSheet', sheetArray.length > 0 ? sheetArray[0] : null);
|
||||||
});
|
});
|
||||||
Template.SalesSheetsMain.helpers({
|
Template.SalesSheetsMain.helpers({
|
||||||
sheets: function() {
|
sheets: function() {
|
||||||
@@ -36,35 +37,27 @@ Template.SalesSheetsMain.helpers({
|
|||||||
//if(sheets && sheets.length > 0) sheets[0].isFirst = true;
|
//if(sheets && sheets.length > 0) sheets[0].isFirst = true;
|
||||||
//
|
//
|
||||||
//return sheets;
|
//return sheets;
|
||||||
return Meteor.collections.SalesSheets.find({}, {sort: {name: 1}});
|
return Template.instance().sheets;
|
||||||
},
|
},
|
||||||
sheetsSelectIsSelected: function(sheet, isFirst) {
|
isSheetSelected: function() { // Determines if the passed sheet is the selected sheet and returns either "selected" or "".
|
||||||
let selectedSheet = Session.get(PREFIX + "selectedSheet");
|
let selectedSheet = Session.get(PREFIX + "selectedSheet");
|
||||||
|
|
||||||
if(!selectedSheet && isFirst) Session.set(PREFIX + "selectedSheet", selectedSheet = sheet);
|
return selectedSheet == this ? "selected" : "";
|
||||||
|
|
||||||
return selectedSheet == sheet ? "selected" : "";
|
|
||||||
},
|
},
|
||||||
disableButtons: function() {
|
disableButtons: function() { // Disable the edit & delete functionality if nothing is selected.
|
||||||
//Disable the edit & delete functionality if nothing is selected.
|
|
||||||
return !Session.get(PREFIX + "selectedSheet");
|
return !Session.get(PREFIX + "selectedSheet");
|
||||||
},
|
},
|
||||||
selected: function() {
|
activeTemplateName: function() { // The name of the template actively being shown to the user in the content area.
|
||||||
//Get whether the current sheet is selected and return the string for use in the option tag.
|
return Session.get(PREFIX + "activeTemplateName");
|
||||||
//return this.isSelected ? "selected" : "";
|
|
||||||
return this._id == Session.get(PREFIX + 'selectedSheet')._id;
|
|
||||||
},
|
},
|
||||||
tab: function() {
|
selectedSheetId: function() { // Gets the ID of the sheet currently selected. This is passed to the template being actively show to the user.
|
||||||
return Session.get(PREFIX + "tab");
|
return Session.get(PREFIX + "selectedSheet") ? Session.get(PREFIX + "selectedSheet")._id : null;
|
||||||
},
|
},
|
||||||
tabData: function() {
|
hasSelectedSheet: function() { // Determines whether any sheet has been selected.
|
||||||
return Session.get(PREFIX + "selectedSheet")._id;
|
|
||||||
},
|
|
||||||
isSheetSelected: function() {
|
|
||||||
return Session.get(PREFIX + "selectedSheet");
|
return Session.get(PREFIX + "selectedSheet");
|
||||||
},
|
},
|
||||||
isEditingSheet: function() {
|
isEditingSheet: function() {
|
||||||
return Session.get(PREFIX + "tab") == "SalesSheetEditor";
|
return Session.get(PREFIX + "activeTemplateName") == "SalesSheetEditor";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Template.SalesSheetsMain.events({
|
Template.SalesSheetsMain.events({
|
||||||
@@ -74,16 +67,16 @@ Template.SalesSheetsMain.events({
|
|||||||
|
|
||||||
Session.set(PREFIX + "selectedSheet", selected);
|
Session.set(PREFIX + "selectedSheet", selected);
|
||||||
// Reset the editor button & the displayed tab.
|
// Reset the editor button & the displayed tab.
|
||||||
Session.set(PREFIX + "tab", "SalesSheetForm");
|
Session.set(PREFIX + "activeTemplateName", "SalesSheetForm");
|
||||||
},
|
},
|
||||||
'click .editSheet': function(event, template) {
|
'click .editSheet': function(event, template) {
|
||||||
if(!$(event.target).hasClass("selected")) {
|
if(!$(event.target).hasClass("selected")) {
|
||||||
// Display the editor for the sheet.
|
// Display the editor for the sheet.
|
||||||
Session.set(PREFIX + "tab", "SalesSheetEditor");
|
Session.set(PREFIX + "activeTemplateName", "SalesSheetEditor");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Remove the sheet editor and show the form to fill out the sheet.
|
// Remove the sheet editor and show the form to fill out the sheet.
|
||||||
Session.set(PREFIX + "tab", "SalesSheetForm");
|
Session.set(PREFIX + "activeTemplateName", "SalesSheetForm");
|
||||||
// Reset the editor session variables.
|
// Reset the editor session variables.
|
||||||
Session.set(PREFIX + "currentFormName", undefined);
|
Session.set(PREFIX + "currentFormName", undefined);
|
||||||
}
|
}
|
||||||
@@ -137,7 +130,7 @@ Template.SalesSheetsMain.events({
|
|||||||
template.$('select[name="sheetSelection"]').val(id);
|
template.$('select[name="sheetSelection"]').val(id);
|
||||||
Session.set(PREFIX + "selectedSheet", selected);
|
Session.set(PREFIX + "selectedSheet", selected);
|
||||||
//Display the editor tab.
|
//Display the editor tab.
|
||||||
Session.set(PREFIX + "tab", "SalesSheetEditor");
|
Session.set(PREFIX + "activeTemplateName", "SalesSheetEditor");
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
}
|
}
|
||||||
else count++;
|
else count++;
|
||||||
|
|||||||
@@ -1,32 +1,39 @@
|
|||||||
<template name="UserManagement">
|
<template name="UserManagement">
|
||||||
<div id="userManagement">
|
<div id="userManagement">
|
||||||
{{#if Template.subscriptionsReady}}
|
{{#if Template.subscriptionsReady}}
|
||||||
<div class="insert">
|
<div class="tableControls">
|
||||||
{{>UserInsert}}
|
<div class="contentControls">
|
||||||
|
<a class="loadMoreLink {{#if disableLoadMore}}disabled{{/if}}" href="javascript:">Load More...</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="tableContainer">
|
</div>
|
||||||
<table class="dataTable table table-striped table-hover">
|
<div class="separatedTableHeader">
|
||||||
|
<table class="table table-striped table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="headers">
|
<tr>
|
||||||
<th class="username">Username</th>
|
<th class="username">Username {{>UserSearch columnName='username'}}</th>
|
||||||
<th class="email">Email</th>
|
<th class="email">Email {{>UserSearch columnName='email' collectionQueryColumnName='name' collection='Items' collectionResultColumnName='_id'}}</th>
|
||||||
<th class="roles">Roles</th>
|
<th class="roles">Roles</th>
|
||||||
<th class="actions">Actions</th>
|
<th class="actions">Actions <span class="newUserButton btn btn-success"><i class="fa fa-plus-circle" aria-hidden="true"></i><i class="fa fa-times-circle" aria-hidden="true"></i></span></th>
|
||||||
</tr>
|
|
||||||
<tr class="footers">
|
|
||||||
<th>{{>UserSearch columnName='username'}}</th>
|
|
||||||
<th>{{>UserSearch columnName='email' collectionQueryColumnName='name' collection='Items' collectionResultColumnName='_id'}}</th>
|
|
||||||
<th></th>
|
|
||||||
<th></th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="listRow">
|
||||||
|
<div class="listCell">
|
||||||
|
<div class="tableContainer mCustomScrollbar" data-mcs-theme="dark">
|
||||||
|
<table class="dataTable table table-striped table-hover">
|
||||||
<tbody>
|
<tbody>
|
||||||
|
{{#if displayNewUser}}
|
||||||
|
<tr>{{> UserEditor isNew=true}}</tr>
|
||||||
|
{{/if}}
|
||||||
{{#each users}}
|
{{#each users}}
|
||||||
{{> User}}
|
{{> User}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
@@ -35,21 +42,31 @@
|
|||||||
<template name="User">
|
<template name="User">
|
||||||
<tr>
|
<tr>
|
||||||
{{#if editing}}
|
{{#if editing}}
|
||||||
<td><input name="username" class="form-control" type="text" value="{{username}}" required></td>
|
{{> UserEditor}}
|
||||||
<td><input name="email" class="form-control" type="text" value="{{email}}" required></td>
|
{{else}}
|
||||||
<td class="roles center" style="font-size: 1.2em">
|
<td class="username tdLarge noselect nonclickable">{{username}}</td>
|
||||||
|
<td class="email tdLarge noselect nonclickable">{{email}}</td>
|
||||||
|
<td class="roles tdLarge noselect nonclickable">{{roles}}</td>
|
||||||
|
<td class="actions center tdLarge"><i class="userRemove fa fa-times-circle fa-lg noselect clickable" aria-hidden="true"></i> / <i class="userEdit fa fa-pencil-square-o fa-lg noselect clickable" aria-hidden="true"></i></td>
|
||||||
|
{{/if}}
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="UserEditor">
|
||||||
|
<td colspan="3" class="userEditor measureEditorTd">
|
||||||
|
<div>
|
||||||
|
<div class="username editorDiv"><label>User Name:</label><input name="username" class="form-control" type="text" value="{{username}}" autocomplete="off" required></div>
|
||||||
|
<div class="email editorDiv"><label>User Email:</label><input name="email" class="form-control" type="text" value="{{email}}" autocomplete="off" required></div>
|
||||||
|
<div class="rolesContainer editorDiv"><label>Roles:</label>
|
||||||
|
<div class="roles center" style="font-size: 1.2em">
|
||||||
{{#each allRoles}}
|
{{#each allRoles}}
|
||||||
<span class="role {{getRoleState this}} noselect">{{name}}</span>
|
<span class="role {{getRoleState this}} noselect">{{name}}</span>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="center tdLarge"><i class="editorApply fa fa-check-square-o fa-lg noselect clickable" aria-hidden="true"></i> / <i class="editorCancel fa fa-times-circle fa-lg noselect clickable" aria-hidden="true"></i></td>
|
<td class="actions center measureEditorTd"><i class="editorApply fa fa-check-square-o fa-lg noselect clickable" aria-hidden="true"></i> / <i class="editorCancel fa fa-times-circle fa-lg noselect clickable" aria-hidden="true"></i></td>
|
||||||
{{else}}
|
|
||||||
<td class="tdLarge noselect nonclickable">{{username}}</td>
|
|
||||||
<td class="tdLarge noselect nonclickable">{{email}}</td>
|
|
||||||
<td class="tdLarge noselect nonclickable">{{roles}}</td>
|
|
||||||
<td class="center tdLarge"><i class="userRemove fa fa-times-circle fa-lg noselect clickable" aria-hidden="true"></i> / <i class="userEdit fa fa-pencil-square-o fa-lg noselect clickable" aria-hidden="true"></i></td>
|
|
||||||
{{/if}}
|
|
||||||
</tr>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template name="UserSearch">
|
<template name="UserSearch">
|
||||||
@@ -57,34 +74,3 @@
|
|||||||
<input type="text" class="searchInput" placeholder="Filter..." value="{{searchValue}}" style="width: 90%"/>
|
<input type="text" class="searchInput" placeholder="Filter..." value="{{searchValue}}" style="width: 90%"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template name="UserInsert">
|
|
||||||
<form name="insert" autocomplete="off">
|
|
||||||
<div class="grid">
|
|
||||||
<div class="col-3-12"></div>
|
|
||||||
<div class="col-6-12">
|
|
||||||
<div class="formGroupHeading">New User</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label class='control-label'>User Name</label>
|
|
||||||
<input name="username" type="text" class="form-control" required>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label class='control-label'>Email</label>
|
|
||||||
<input name="email" class="form-control" type="text" required/>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label class='control-label'>Roles</label>
|
|
||||||
<div class="roles">
|
|
||||||
{{#each allRoles}}
|
|
||||||
<span class="role">{{name}}</span>
|
|
||||||
{{/each}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<input type="submit" class="btn btn-success" value="Create">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-3-12"></div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</template>
|
|
||||||
108
imports/ui/UserManagement.import.styl
vendored
108
imports/ui/UserManagement.import.styl
vendored
@@ -1,19 +1,31 @@
|
|||||||
#userManagement
|
#userManagement
|
||||||
margin: 20px 20px
|
display: table
|
||||||
|
content-box: border-box
|
||||||
|
padding: 10px 20px
|
||||||
height: 100%
|
height: 100%
|
||||||
//Flex container options.
|
width: 100%
|
||||||
flex-flow: column nowrap
|
|
||||||
justify-content: space-around //Spacing between sales along the primary axis. (vertical spacing for a column layout)
|
|
||||||
align-items: flex-start //Align the sales within a line along the primary axis. (horizontal alignment for a column layout)
|
|
||||||
align-content: center //Spacing between lines along the secondary axis. (spacing between columns for a column layout)
|
|
||||||
display: -webkit-box
|
|
||||||
display: -moz-box
|
|
||||||
display: -ms-flexbox
|
|
||||||
display: -moz-flex
|
|
||||||
display: -webkit-flex
|
|
||||||
display: flex
|
|
||||||
text-align: left
|
text-align: left
|
||||||
|
|
||||||
|
.tableControls
|
||||||
|
display: table
|
||||||
|
width: 100%
|
||||||
|
text-align: right
|
||||||
|
margin-right: 20px
|
||||||
|
.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
|
||||||
.editor
|
.editor
|
||||||
height: 100%
|
height: 100%
|
||||||
overflow-y: auto
|
overflow-y: auto
|
||||||
@@ -33,26 +45,64 @@
|
|||||||
font-style: normal
|
font-style: normal
|
||||||
font-variant: normal
|
font-variant: normal
|
||||||
font-weight: 500
|
font-weight: 500
|
||||||
.tableContainer
|
.table
|
||||||
width: 100%
|
table-layout: fixed
|
||||||
|
min-width: 100%
|
||||||
|
thead, tbody
|
||||||
|
> tr
|
||||||
|
> .username
|
||||||
|
width: 50%
|
||||||
|
min-width: 100px
|
||||||
|
> .email
|
||||||
|
width: 50%
|
||||||
|
min-width: 100px
|
||||||
|
> .roles
|
||||||
|
width: 260px
|
||||||
|
min-width: 260px
|
||||||
|
> .actions
|
||||||
|
width: 80px
|
||||||
|
min-width: 80px
|
||||||
|
.separatedTableHeader
|
||||||
|
.actions
|
||||||
|
text-align: center
|
||||||
|
.newUserButton
|
||||||
|
margin-top: 4px
|
||||||
|
padding: 0 12px
|
||||||
|
.fa-plus-circle
|
||||||
|
display: inline-block
|
||||||
|
.fa-times-circle
|
||||||
|
display: none
|
||||||
|
.newUserButton.active
|
||||||
|
background-color: #fb557b
|
||||||
|
color: black
|
||||||
|
.fa-times-circle
|
||||||
|
display: inline-block
|
||||||
|
.fa-plus-circle
|
||||||
|
display: none
|
||||||
|
.listRow
|
||||||
|
display: table-row
|
||||||
|
.listCell
|
||||||
|
display: table-cell
|
||||||
|
position: relative
|
||||||
height: 100%
|
height: 100%
|
||||||
margin-top: 20px
|
width: 100%
|
||||||
margin-bottom: 20px
|
.tableContainer
|
||||||
|
position: absolute
|
||||||
|
top: 0
|
||||||
|
bottom: 0
|
||||||
|
left: 0
|
||||||
|
right: 0
|
||||||
|
width: auto
|
||||||
|
height: auto
|
||||||
border: 0
|
border: 0
|
||||||
font-size: 12.5px
|
font-size: 12.5px
|
||||||
|
overflow-y: auto
|
||||||
table
|
table
|
||||||
table-layout: fixed
|
table-layout: fixed
|
||||||
width: 100%
|
width: 100%
|
||||||
thead
|
thead
|
||||||
> tr
|
display: none
|
||||||
> th.username
|
visibility: hidden
|
||||||
width: auto
|
|
||||||
> th.email
|
|
||||||
width: auto
|
|
||||||
> th.roles
|
|
||||||
width: 260px
|
|
||||||
> th.actions
|
|
||||||
width: 80px
|
|
||||||
.userRemove
|
.userRemove
|
||||||
color: red
|
color: red
|
||||||
.userEdit
|
.userEdit
|
||||||
@@ -61,6 +111,14 @@
|
|||||||
color: green
|
color: green
|
||||||
.editorCancel
|
.editorCancel
|
||||||
color: red
|
color: red
|
||||||
|
.userEditor > div
|
||||||
|
display: table
|
||||||
|
> div
|
||||||
|
display: table-cell
|
||||||
|
padding: 10px
|
||||||
|
.roles
|
||||||
|
.role
|
||||||
|
vertical-align: middle
|
||||||
td.roles
|
td.roles
|
||||||
.role
|
.role
|
||||||
padding: 4px 4px
|
padding: 4px 4px
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
import './UserManagement.html';
|
import './UserManagement.html';
|
||||||
import '/imports/util/selectize/selectize.js'
|
import '/imports/util/selectize/selectize.js'
|
||||||
|
|
||||||
|
let QUERY_LIMIT = 100;
|
||||||
|
let QUERY_LIMIT_INCREMENT = 100;
|
||||||
let PREFIX = "UserManagement";
|
let PREFIX = "UserManagement";
|
||||||
|
|
||||||
Tracker.autorun(function() {
|
Tracker.autorun(function() {
|
||||||
@@ -9,9 +11,71 @@ Tracker.autorun(function() {
|
|||||||
Meteor.subscribe("roles");
|
Meteor.subscribe("roles");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Template.UserManagement.onCreated(function() {
|
||||||
|
Session.set(PREFIX + "displayNewUser", false);
|
||||||
|
Session.set(PREFIX + "queryLimit", QUERY_LIMIT);
|
||||||
|
});
|
||||||
|
Template.UserManagement.onRendered(function() {
|
||||||
|
$(".tableContainer").mCustomScrollbar({
|
||||||
|
scrollButtons: {enable:true},
|
||||||
|
theme: "light-thick",
|
||||||
|
scrollbarPosition: "outside",
|
||||||
|
scrollEasing: "linear"
|
||||||
|
});
|
||||||
|
});
|
||||||
Template.UserManagement.helpers({
|
Template.UserManagement.helpers({
|
||||||
|
displayNewUser: function() {
|
||||||
|
return Session.get(PREFIX + "displayNewUser");
|
||||||
|
},
|
||||||
users: function() {
|
users: function() {
|
||||||
return Meteor.collections.Users.find({}, {sort: {username: 1}});
|
let skipCount = Session.get(PREFIX + 'skipCount') || 0;
|
||||||
|
let query = Session.get(PREFIX + 'searchQuery');
|
||||||
|
let dbQuery = [];
|
||||||
|
|
||||||
|
if(query) {
|
||||||
|
_.each(_.keys(query), function(key) {
|
||||||
|
if(_.isFunction(query[key])) dbQuery.push({[key]: query[key]}); //dbQuery[key] = query[key]();
|
||||||
|
else if(_.isObject(query[key])) dbQuery.push({[key]: query[key]}); //dbQuery[key] = query[key]; //Will look something like: {$in: [xxx,xxx,xxx]}
|
||||||
|
else if(_.isNumber(query[key])) dbQuery.push({[key]: query[key]}); //dbQuery[key] = query[key];
|
||||||
|
else {
|
||||||
|
//dbQuery[key] = {$regex: query[key], $options: 'i'};
|
||||||
|
let searchValue = query[key];
|
||||||
|
let searches = searchValue && searchValue.length > 0 ? searchValue.split(/\s+/) : undefined;
|
||||||
|
|
||||||
|
for(let search of searches) {
|
||||||
|
dbQuery.push({[key]: {$regex: '\\b' + search, $options: 'i'}});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!Session.get(PREFIX + "showHidden")) {
|
||||||
|
//Ignore any hidden elements by showing those not hidden, or those without the hidden field.
|
||||||
|
dbQuery.push({$or: [{hidden: false}, {hidden: {$exists:false}}]});
|
||||||
|
}
|
||||||
|
|
||||||
|
dbQuery = dbQuery.length > 0 ? {$and: dbQuery} : {};
|
||||||
|
Session.set(PREFIX + 'userCount', Meteor.collections.Users.find(dbQuery).count()); //Always get a full count.
|
||||||
|
return Meteor.collections.Users.find(dbQuery, {limit: Session.get(PREFIX + "queryLimit"), skip: skipCount, sort: {username: 1}});
|
||||||
|
},
|
||||||
|
disableLoadMore: function() {
|
||||||
|
return Session.get(PREFIX + 'userCount') - (Session.get(PREFIX + 'skipCount') || 0) - Session.get(PREFIX + "queryLimit") <= 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Template.UserManagement.events({
|
||||||
|
'click .loadMoreLink': function(event, template) {
|
||||||
|
event.preventDefault();
|
||||||
|
Session.set(PREFIX + 'queryLimit', Session.get(PREFIX + "queryLimit") + QUERY_LIMIT_INCREMENT);
|
||||||
|
},
|
||||||
|
'click .newUserButton': function(event, template) {
|
||||||
|
if(template.$('.newUserButton').hasClass('active')) {
|
||||||
|
Session.set(PREFIX + 'displayNewUser', false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Session.set(PREFIX + 'displayNewUser', true);
|
||||||
|
Session.set(PREFIX + "editedUser", undefined); //Clear the edited user so that only one editor is open at a time.
|
||||||
|
}
|
||||||
|
template.$('.newUserButton').toggleClass('active');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -20,7 +84,10 @@ Template.User.onCreated(function() {
|
|||||||
});
|
});
|
||||||
Template.User.events({
|
Template.User.events({
|
||||||
"click .userEdit": function(event, template) {
|
"click .userEdit": function(event, template) {
|
||||||
template.edited.set(this);
|
//template.edited.set(this);
|
||||||
|
Session.set(PREFIX + "editedUser", this._id);
|
||||||
|
Session.set(PREFIX + 'displayNewUser', false); //Ensure the new measure editor is closed.
|
||||||
|
template.parentTemplate().$('.newUserButton').removeClass('active');
|
||||||
},
|
},
|
||||||
"click .userRemove": function(event, template) {
|
"click .userRemove": function(event, template) {
|
||||||
let _this = this;
|
let _this = this;
|
||||||
@@ -40,48 +107,6 @@ Template.User.events({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
|
||||||
"click .editorCancel": function(event, template) {
|
|
||||||
template.edited.set(undefined);
|
|
||||||
},
|
|
||||||
"click .editorApply": function(event, template) {
|
|
||||||
let username = template.$("input[name='username']").val().trim();
|
|
||||||
let email = template.$("input[name='email']").val().trim();
|
|
||||||
let roleSpans = template.$(".roles > span");
|
|
||||||
let roles = [];
|
|
||||||
|
|
||||||
for(let i = 0; i < roleSpans.length; i++) {
|
|
||||||
if($(roleSpans[i]).hasClass("selected")) {
|
|
||||||
roles.push($(roleSpans[i]).text());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Basic validation.
|
|
||||||
if(username && username.length > 0 && email && email.length > 0) {
|
|
||||||
let emails = _.clone(this.emails);
|
|
||||||
|
|
||||||
if(!emails || emails.length == 0) {
|
|
||||||
emails = [{address: email, verified: true}];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
emails[0].address = email;
|
|
||||||
emails[0].verified = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Meteor.call("updateUser", {_id: this._id, username: username, emails: emails, roles: roles}, function(error, result) {
|
|
||||||
if(error) {
|
|
||||||
sAlert.error(error);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sAlert.success("User updated.");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
template.edited.set(undefined);
|
|
||||||
},
|
|
||||||
"click .role": function(event, template) {
|
|
||||||
$(event.target).toggleClass("selected");
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Template.User.helpers({
|
Template.User.helpers({
|
||||||
@@ -89,7 +114,15 @@ Template.User.helpers({
|
|||||||
return this.emails && this.emails.length > 0 ? this.emails[0].address : "";
|
return this.emails && this.emails.length > 0 ? this.emails[0].address : "";
|
||||||
},
|
},
|
||||||
editing: function() {
|
editing: function() {
|
||||||
return Template.instance().edited.get() == this;
|
let editedUser = Session.get(PREFIX + "editedUser");
|
||||||
|
|
||||||
|
return editedUser == this._id;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.UserEditor.helpers({
|
||||||
|
email: function() {
|
||||||
|
return this.emails && this.emails.length > 0 ? this.emails[0].address : "";
|
||||||
},
|
},
|
||||||
allRoles: function() {
|
allRoles: function() {
|
||||||
return Meteor.collections.UserRoles.find();
|
return Meteor.collections.UserRoles.find();
|
||||||
@@ -97,7 +130,56 @@ Template.User.helpers({
|
|||||||
getRoleState: function(role) {
|
getRoleState: function(role) {
|
||||||
let user = Template.parentData(1);
|
let user = Template.parentData(1);
|
||||||
|
|
||||||
return user.roles.includes(role.name) ? "selected" : "";
|
return !user.isNew && user.roles.includes(role.name) ? "selected" : "";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Template.UserEditor.events({
|
||||||
|
"click .editorCancel": function(event, template) {
|
||||||
|
Session.set(PREFIX + "editedUser", undefined);
|
||||||
|
Session.set(PREFIX + 'displayNewUser', false);
|
||||||
|
template.parentTemplate().$('.newUserButton').removeClass('active');
|
||||||
|
},
|
||||||
|
"click .editorApply": function(event, template) {
|
||||||
|
let user = {};
|
||||||
|
let roles = [];
|
||||||
|
|
||||||
|
user.username = template.$('input[name="username"]').val();
|
||||||
|
user.email = template.$('input[name="email"]').val();
|
||||||
|
|
||||||
|
let roleSpans = template.$('.role.selected');
|
||||||
|
for(let i = 0; i < roleSpans.length; i++) {
|
||||||
|
roles.push($(roleSpans[i]).text());
|
||||||
|
}
|
||||||
|
|
||||||
|
user.roles = roles;
|
||||||
|
|
||||||
|
if(Session.get(PREFIX + 'displayNewUser')) {
|
||||||
|
Meteor.call('insertUser', user, function(error, result) {
|
||||||
|
if(error) {
|
||||||
|
sAlert.error(error);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sAlert.success("User created.");
|
||||||
|
Session.set(PREFIX + 'displayNewUser', false);
|
||||||
|
template.parentTemplate().$('.newUserButton').removeClass('active');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
user._id = this._id;
|
||||||
|
Meteor.call("updateUser", user, function(error, result) {
|
||||||
|
if(error) sAlert.error(error);
|
||||||
|
else {
|
||||||
|
sAlert.success("User updated.");
|
||||||
|
Session.set(PREFIX + "editedUser", undefined);
|
||||||
|
template.parentTemplate().$('.newUserButton').removeClass('active');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
"click .role": function(event, template) {
|
||||||
|
$(event.target).toggleClass("selected");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -139,43 +221,3 @@ Template.UserSearch.helpers({
|
|||||||
return (searchFields && searchFields[this.columnName]) ? searchFields[this.columnName] : '';
|
return (searchFields && searchFields[this.columnName]) ? searchFields[this.columnName] : '';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.UserInsert.onRendered(function() {
|
|
||||||
this.$('form[name="insert"]').validator();
|
|
||||||
});
|
|
||||||
Template.UserInsert.events({
|
|
||||||
'click input[type="submit"]': function(event, template) {
|
|
||||||
event.preventDefault();
|
|
||||||
template.$('form[name="insert"]').data('bs.validator').validate(function(isValid) {
|
|
||||||
if(isValid) {
|
|
||||||
let user = {};
|
|
||||||
let roles = [];
|
|
||||||
|
|
||||||
user.username = template.$('input[name="username"]').val();
|
|
||||||
user.email = template.$('input[name="email"]').val();
|
|
||||||
|
|
||||||
let roleSpans = template.$('.role.selected');
|
|
||||||
for(let i = 0; i < roleSpans.length; i++) {
|
|
||||||
roles.push($(roleSpans[i]).text());
|
|
||||||
}
|
|
||||||
|
|
||||||
Meteor.call('insertUser', user, roles, function(error, result) {
|
|
||||||
if(error) {
|
|
||||||
sAlert.error(error);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sAlert.success("User created.");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
"click .role": function(event, template) {
|
|
||||||
$(event.target).toggleClass("selected");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Template.UserInsert.helpers({
|
|
||||||
allRoles: function() {
|
|
||||||
return Meteor.collections.UserRoles.find();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -2,20 +2,19 @@
|
|||||||
<div id="venues">
|
<div id="venues">
|
||||||
{{#if Template.subscriptionsReady}}
|
{{#if Template.subscriptionsReady}}
|
||||||
<div class="tableControls">
|
<div class="tableControls">
|
||||||
|
<div class="showHidden">
|
||||||
<span class="controlLabel">Show Hidden</span>
|
<span class="controlLabel">Show Hidden</span>
|
||||||
<div class="toggleShowHidden checkbox checkbox-slider--b-flat">
|
<div class="toggleShowHidden checkbox checkbox-slider--b-flat">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" name="showHidden"><span></span>
|
<input type="checkbox" name="showHidden"><span></span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<span class="pagination">
|
|
||||||
<span class="prevVenues noselect {{#if disablePrev}}disabled{{/if}}"><i class="fa fa-long-arrow-left" aria-hidden="true"></i> Prev</span>
|
|
||||||
<span class="nextVenues noselect {{#if disableNext}}disabled{{/if}}">Next <i class="fa fa-long-arrow-right" aria-hidden="true"></i></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="listRow">
|
<div class="contentControls">
|
||||||
<div class="listCell">
|
<a class="loadMoreLink {{#if disableLoadMore}}disabled{{/if}}" href="javascript:">Load More...</a>
|
||||||
<div class="tableContainer">
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="separatedTableHeader">
|
||||||
<table class="table table-striped table-hover">
|
<table class="table table-striped table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -23,8 +22,13 @@
|
|||||||
<th class="type">Type {{>VenueSearch columnName='type'}}</th>
|
<th class="type">Type {{>VenueSearch columnName='type'}}</th>
|
||||||
<th class="actions">Actions <span class="newVenueButton btn btn-success"><i class="fa fa-plus-circle" aria-hidden="true"></i><i class="fa fa-times-circle" aria-hidden="true"></i></span></th>
|
<th class="actions">Actions <span class="newVenueButton btn btn-success"><i class="fa fa-plus-circle" aria-hidden="true"></i><i class="fa fa-times-circle" aria-hidden="true"></i></span></th>
|
||||||
</tr>
|
</tr>
|
||||||
<!--<button type="button" name="newVenueButton"><i class="fa fa-plus-circle" aria-hidden="true"></i></button>-->
|
|
||||||
</thead>
|
</thead>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="listRow">
|
||||||
|
<div class="listCell">
|
||||||
|
<div class="tableContainer mCustomScrollbar" data-mcs-theme="dark">
|
||||||
|
<table class="table table-striped table-hover">
|
||||||
<tbody>
|
<tbody>
|
||||||
{{#if displayNewVenue}}
|
{{#if displayNewVenue}}
|
||||||
{{> VenueEditor isNew=true}}
|
{{> VenueEditor isNew=true}}
|
||||||
@@ -47,15 +51,15 @@
|
|||||||
{{#if editing}}
|
{{#if editing}}
|
||||||
{{> VenueEditor}}
|
{{> VenueEditor}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<td class="noselect nonclickable left">{{name}}</td>
|
<td class="name noselect nonclickable left">{{name}}</td>
|
||||||
<td class="noselect nonclickable left">{{type}}</td>
|
<td class="type noselect nonclickable left">{{type}}</td>
|
||||||
{{#if hidden}}
|
{{#if hidden}}
|
||||||
<td class="center"><i class="actionEdit fa fa-pencil-square-o fa-lg noselect clickable" title="Edit" aria-hidden="true"></i> / <i class="actionShow fa fa-eye fa-lg noselect clickable" title="Show" aria-hidden="true"></i></td>
|
<td class="actions center"><i class="actionEdit fa fa-pencil-square-o fa-lg noselect clickable" title="Edit" aria-hidden="true"></i> / <i class="actionShow fa fa-eye fa-lg noselect clickable" title="Show" aria-hidden="true"></i></td>
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#if deactivated}}
|
{{#if deactivated}}
|
||||||
<td class="center"><i class="actionEdit fa fa-pencil-square-o fa-lg noselect clickable" title="Edit" aria-hidden="true"></i> / <i class="actionActivate fa fa-toggle-on fa-lg noselect clickable" title="Activate" aria-hidden="true"></i> / <i class="actionHide fa fa-eye-slash fa-lg noselect clickable" title="Hide" aria-hidden="true"></i></td>
|
<td class="actions center"><i class="actionEdit fa fa-pencil-square-o fa-lg noselect clickable" title="Edit" aria-hidden="true"></i> / <i class="actionActivate fa fa-toggle-on fa-lg noselect clickable" title="Activate" aria-hidden="true"></i> / <i class="actionHide fa fa-eye-slash fa-lg noselect clickable" title="Hide" aria-hidden="true"></i></td>
|
||||||
{{else}}
|
{{else}}
|
||||||
<td class="center"><i class="actionEdit fa fa-pencil-square-o fa-lg noselect clickable" title="Edit" aria-hidden="true"></i> / <i class="actionRemove fa fa-times-circle fa-lg noselect clickable" title="Deactivate" aria-hidden="true"></i></td>
|
<td class="actions center"><i class="actionEdit fa fa-pencil-square-o fa-lg noselect clickable" title="Edit" aria-hidden="true"></i> / <i class="actionRemove fa fa-times-circle fa-lg noselect clickable" title="Deactivate" aria-hidden="true"></i></td>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|||||||
77
imports/ui/Venues.import.styl
vendored
77
imports/ui/Venues.import.styl
vendored
@@ -7,8 +7,13 @@
|
|||||||
text-align: left
|
text-align: left
|
||||||
|
|
||||||
.tableControls
|
.tableControls
|
||||||
|
display: table
|
||||||
|
width: 100%
|
||||||
text-align: right
|
text-align: right
|
||||||
margin-right: 20px
|
margin-right: 20px
|
||||||
|
.showHidden
|
||||||
|
display: table-cell
|
||||||
|
width: 100%
|
||||||
.controlLabel
|
.controlLabel
|
||||||
font-size: 9px
|
font-size: 9px
|
||||||
font-weight: 700
|
font-weight: 700
|
||||||
@@ -20,7 +25,55 @@
|
|||||||
position: relative
|
position: relative
|
||||||
top: -4px
|
top: -4px
|
||||||
display: inline-block
|
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
|
||||||
|
> .type
|
||||||
|
width: 50%
|
||||||
|
min-width: 100px
|
||||||
|
> .actions
|
||||||
|
width: 90px
|
||||||
|
min-width: 90px
|
||||||
|
.separatedTableHeader
|
||||||
|
table
|
||||||
|
thead
|
||||||
|
> tr
|
||||||
|
.actions
|
||||||
|
text-align: center
|
||||||
|
.newVenueButton
|
||||||
|
margin-top: 4px
|
||||||
|
padding: 0px 12px
|
||||||
|
.fa-plus-circle
|
||||||
|
display: inline-block
|
||||||
|
.fa-times-circle
|
||||||
|
display: none
|
||||||
|
.newVenueButton.active
|
||||||
|
background-color: #fb557b
|
||||||
|
color: black
|
||||||
|
.fa-times-circle
|
||||||
|
display: inline-block
|
||||||
|
.fa-plus-circle
|
||||||
|
display: none
|
||||||
.listRow
|
.listRow
|
||||||
display: table-row
|
display: table-row
|
||||||
.listCell
|
.listCell
|
||||||
@@ -57,28 +110,8 @@
|
|||||||
select2
|
select2
|
||||||
font-size: .4em
|
font-size: .4em
|
||||||
> thead
|
> thead
|
||||||
> tr
|
|
||||||
> th.name
|
|
||||||
width: auto
|
|
||||||
> th.type
|
|
||||||
width: auto
|
|
||||||
> th.actions
|
|
||||||
width: 90px
|
|
||||||
text-align: center
|
|
||||||
.newVenueButton
|
|
||||||
margin-top: 4px
|
|
||||||
padding: 0px 12px
|
|
||||||
.fa-plus-circle
|
|
||||||
display: inline-block
|
|
||||||
.fa-times-circle
|
|
||||||
display: none
|
|
||||||
.newVenueButton.active
|
|
||||||
background-color: #fb557b
|
|
||||||
color: black
|
|
||||||
.fa-times-circle
|
|
||||||
display: inline-block
|
|
||||||
.fa-plus-circle
|
|
||||||
display: none
|
display: none
|
||||||
|
visibility: hidden
|
||||||
> tbody
|
> tbody
|
||||||
> tr
|
> tr
|
||||||
.actionRemove
|
.actionRemove
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
|
|
||||||
import './Venues.html';
|
import './Venues.html';
|
||||||
|
|
||||||
let QUERY_LIMIT = 20;
|
let QUERY_LIMIT = 100;
|
||||||
|
let QUERY_LIMIT_INCREMENT = 100;
|
||||||
let PREFIX = "Venues.";
|
let PREFIX = "Venues.";
|
||||||
|
|
||||||
Tracker.autorun(function() {
|
Tracker.autorun(function() {
|
||||||
@@ -11,6 +12,15 @@ Tracker.autorun(function() {
|
|||||||
Template.Venues.onCreated(function() {
|
Template.Venues.onCreated(function() {
|
||||||
Session.set(PREFIX + "displayNewVenue", false);
|
Session.set(PREFIX + "displayNewVenue", false);
|
||||||
Session.set(PREFIX + "showHidden", false);
|
Session.set(PREFIX + "showHidden", false);
|
||||||
|
Session.set(PREFIX + "queryLimit", QUERY_LIMIT);
|
||||||
|
});
|
||||||
|
Template.Venues.onRendered(function() {
|
||||||
|
$(".tableContainer").mCustomScrollbar({
|
||||||
|
scrollButtons: {enable:true},
|
||||||
|
theme: "light-thick",
|
||||||
|
scrollbarPosition: "outside",
|
||||||
|
scrollEasing: "linear"
|
||||||
|
});
|
||||||
});
|
});
|
||||||
Template.Venues.helpers({
|
Template.Venues.helpers({
|
||||||
displayNewVenue: function() {
|
displayNewVenue: function() {
|
||||||
@@ -45,23 +55,16 @@ Template.Venues.helpers({
|
|||||||
|
|
||||||
dbQuery = dbQuery.length > 0 ? {$and: dbQuery} : {};
|
dbQuery = dbQuery.length > 0 ? {$and: dbQuery} : {};
|
||||||
Session.set(PREFIX + 'venueCount', Meteor.collections.Venues.find(dbQuery).count()); //Always get a full count.
|
Session.set(PREFIX + 'venueCount', Meteor.collections.Venues.find(dbQuery).count()); //Always get a full count.
|
||||||
return Meteor.collections.Venues.find(dbQuery, {limit: QUERY_LIMIT, skip: skipCount, sort: {order: 1}});
|
return Meteor.collections.Venues.find(dbQuery, {limit: Session.get(PREFIX + "queryLimit"), skip: skipCount, sort: {order: 1}});
|
||||||
},
|
},
|
||||||
disablePrev: function() {
|
disableLoadMore: function() {
|
||||||
return (Session.get(PREFIX + 'skipCount') || 0) == 0;
|
return Session.get(PREFIX + 'venueCount') - (Session.get(PREFIX + 'skipCount') || 0) - Session.get(PREFIX + "queryLimit") <= 0;
|
||||||
},
|
|
||||||
disableNext: function() {
|
|
||||||
return Session.get(PREFIX + 'venueCount') - (Session.get(PREFIX + 'skipCount') || 0) - QUERY_LIMIT <= 0;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Template.Venues.events({
|
Template.Venues.events({
|
||||||
'click .prevVenues': function(event, template) {
|
'click .loadMoreLink': function(event, template) {
|
||||||
if(!$(event.target).hasClass('disabled'))
|
event.preventDefault();
|
||||||
Session.set(PREFIX + 'skipCount', Math.max(0, (Session.get(PREFIX + 'skipCount') || 0) - QUERY_LIMIT));
|
Session.set(PREFIX + 'queryLimit', Session.get(PREFIX + "queryLimit") + QUERY_LIMIT_INCREMENT);
|
||||||
},
|
|
||||||
'click .nextVenues': function(event, template) {
|
|
||||||
if(!$(event.target).hasClass('disabled'))
|
|
||||||
Session.set(PREFIX + 'skipCount', (Session.get(PREFIX + 'skipCount') || 0) + QUERY_LIMIT);
|
|
||||||
},
|
},
|
||||||
'click .newVenueButton': function(event, template) {
|
'click .newVenueButton': function(event, template) {
|
||||||
if(template.$('.newVenueButton').hasClass('active')) {
|
if(template.$('.newVenueButton').hasClass('active')) {
|
||||||
@@ -150,7 +153,7 @@ Template.Venue.events({
|
|||||||
"click .actionEdit": function(event, template) {
|
"click .actionEdit": function(event, template) {
|
||||||
Session.set(PREFIX + "editedVenue", this._id);
|
Session.set(PREFIX + "editedVenue", this._id);
|
||||||
Session.set(PREFIX + 'displayNewVenue', false); //Ensure the new venue editor is closed.
|
Session.set(PREFIX + 'displayNewVenue', false); //Ensure the new venue editor is closed.
|
||||||
template.$('.newVenueButton').removeClass('active');
|
template.parentTemplate().$('.newVenueButton').removeClass('active');
|
||||||
},
|
},
|
||||||
"click .actionRemove": function(event, template) {
|
"click .actionRemove": function(event, template) {
|
||||||
Meteor.call('deactivateVenue', this._id, function(error, result) {
|
Meteor.call('deactivateVenue', this._id, function(error, result) {
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
<template name="Body">
|
<template name="Body">
|
||||||
{{> sAlert}}
|
{{> sAlert}}
|
||||||
<!--<div id="layoutBody" class="verticalStack">-->
|
<div id="mainBody" class="mainBody">
|
||||||
<div id="mainBody" class="mainBody verticalStack vscExpand">
|
<nav class="leftSidebarContainer">
|
||||||
<div class="leftSidebar vscFixed">
|
<a href="javascript:" class="fa fa-bars leftSidebarMenuButton" aria-hidden="true"></a>
|
||||||
|
<div class="leftSidebar">
|
||||||
<div class="logoArea">
|
<div class="logoArea">
|
||||||
<i class="fa fa-sign-out fa-2x signOut" aria-hidden="true"></i>
|
<i class="fa fa-sign-out fa-2x signOut" aria-hidden="true"></i>
|
||||||
<div class="logo">
|
<div class="logo">
|
||||||
@@ -74,11 +75,11 @@
|
|||||||
© Petit Teton LLC 2017
|
© Petit Teton LLC 2017
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</nav>
|
||||||
<div class="contentBody verticalStack">
|
<div class="contentBody verticalStack">
|
||||||
{{> Template.dynamic template=content}}
|
{{> Template.dynamic template=content}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!--</div>-->
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!--<template name="Body">-->
|
<!--<template name="Body">-->
|
||||||
|
|||||||
261
imports/ui/layouts/Body.import.styl
vendored
261
imports/ui/layouts/Body.import.styl
vendored
@@ -9,8 +9,8 @@
|
|||||||
|
|
||||||
#mainBody
|
#mainBody
|
||||||
//position: relative
|
//position: relative
|
||||||
display: flex;
|
//display: flex;
|
||||||
flex-flow: row;
|
//flex-flow: row;
|
||||||
//display: inline-block // Requried by Firefox for absolute positioning.
|
//display: inline-block // Requried by Firefox for absolute positioning.
|
||||||
margin: 0
|
margin: 0
|
||||||
padding: 0
|
padding: 0
|
||||||
@@ -18,6 +18,69 @@
|
|||||||
height: 100%
|
height: 100%
|
||||||
width: 100%
|
width: 100%
|
||||||
|
|
||||||
|
nav.leftSidebarContainer
|
||||||
|
z-index:999
|
||||||
|
position: fixed
|
||||||
|
top: 0
|
||||||
|
width: 220px
|
||||||
|
padding: 0
|
||||||
|
height: 100%
|
||||||
|
border: 0
|
||||||
|
vertical-align: top
|
||||||
|
text-align: left
|
||||||
|
background-color: #90b272 //Old browsers
|
||||||
|
background: -moz-linear-gradient(-180deg, #90b272 0%, #4d7727 100%) //FF3.6-15
|
||||||
|
background: -webkit-linear-gradient(-180deg, #90b272 0%,#4d7727 100%) //Chrome10-25,Safari5.1-6
|
||||||
|
background: linear-gradient(180deg, #90b272 0%,#4d7727 100%) //W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+
|
||||||
|
font-size: 14px
|
||||||
|
font-weight: 700
|
||||||
|
overflow: visible
|
||||||
|
margin: 0 0 0 -220px
|
||||||
|
-webkit-transition: .5s ease-in
|
||||||
|
-moz-transition: .5s ease-in
|
||||||
|
-o-transition: .5s ease-in
|
||||||
|
-ms-transition: .5s ease-in
|
||||||
|
transition: .5s ease-in
|
||||||
|
.leftSidebarMenuButton
|
||||||
|
position: absolute
|
||||||
|
right: -30px
|
||||||
|
top: 10px
|
||||||
|
-webkit-transition: .25s ease-in
|
||||||
|
-moz-transition: .25s ease-in
|
||||||
|
-o-transition: .25s ease-in
|
||||||
|
-ms-transition: .25s ease-in
|
||||||
|
transition: .25s ease-in
|
||||||
|
-webkit-border-top-right-radius: 5px
|
||||||
|
-webkit-border-bottom-right-radius: 5px
|
||||||
|
-moz-border-radius-topright: 5px
|
||||||
|
-moz-border-radius-bottomright: 5px
|
||||||
|
border-top-right-radius: 5px
|
||||||
|
border-bottom-right-radius: 5px
|
||||||
|
color: black
|
||||||
|
font-size: 20px
|
||||||
|
line-height: 20px
|
||||||
|
font-weight: 900
|
||||||
|
text-align: center
|
||||||
|
text-decoration: none
|
||||||
|
width: 30px
|
||||||
|
height: 30px
|
||||||
|
padding: 5px 0
|
||||||
|
background-color: #90b272
|
||||||
|
display: block
|
||||||
|
.leftSidebarMenuButton:hover
|
||||||
|
color: rgba(150,0,0,.5)
|
||||||
|
nav.menuShow
|
||||||
|
margin: 0
|
||||||
|
nav.menuShow .leftSidebarMenuButton
|
||||||
|
right: -15px
|
||||||
|
-webkit-transform: rotate(45deg) !important
|
||||||
|
-moz-transform: rotate(45deg) !important
|
||||||
|
-o-transform: rotate(45deg) !important
|
||||||
|
-ms-transform: rotate(45deg) !important
|
||||||
|
transform: rotate(45deg) !important
|
||||||
|
-moz-border-radius-bottomright: 0
|
||||||
|
border-top-right-radius: 0
|
||||||
|
border-bottom-right-radius: 0
|
||||||
.leftSidebar
|
.leftSidebar
|
||||||
flex: 0 0 auto
|
flex: 0 0 auto
|
||||||
display: flex
|
display: flex
|
||||||
@@ -118,198 +181,4 @@
|
|||||||
-webkit-box-shadow: inset 4px 2px 10px -3px rgba(168,165,168,1)
|
-webkit-box-shadow: inset 4px 2px 10px -3px rgba(168,165,168,1)
|
||||||
-moz-box-shadow: inset 4px 2px 10px -3px rgba(168,165,168,1)
|
-moz-box-shadow: inset 4px 2px 10px -3px rgba(168,165,168,1)
|
||||||
box-shadow: inset 8px 0px 10px -3px rgba(168,165,168,1)
|
box-shadow: inset 8px 0px 10px -3px rgba(168,165,168,1)
|
||||||
//position: absolute
|
|
||||||
//top: 0
|
|
||||||
//bottom: 0
|
|
||||||
//left: 220px
|
|
||||||
//right: 0
|
|
||||||
overflow: hidden
|
overflow: hidden
|
||||||
|
|
||||||
//.contentBody
|
|
||||||
// //display: table-cell
|
|
||||||
// position: absolute
|
|
||||||
// top: 0
|
|
||||||
// bottom: 0
|
|
||||||
// left: 220px
|
|
||||||
// right: 0
|
|
||||||
// //background: #4d7727
|
|
||||||
//
|
|
||||||
// .contentContainer
|
|
||||||
// display: table
|
|
||||||
// width: 100%
|
|
||||||
// height: 100%
|
|
||||||
// //border-radius 20px
|
|
||||||
// //border: 0;
|
|
||||||
// background: white
|
|
||||||
//
|
|
||||||
// .content
|
|
||||||
// display: table-row
|
|
||||||
// width: 100%
|
|
||||||
// -webkit-box-shadow: inset 4px 2px 10px -3px rgba(168,165,168,1)
|
|
||||||
// -moz-box-shadow: inset 4px 2px 6px 2px rgba(168,165,168,1)
|
|
||||||
// box-shadow: inset 4px 2px 6px 2px rgba(168,165,168,1)
|
|
||||||
|
|
||||||
|
|
||||||
//#layoutBody
|
|
||||||
// width: 100%
|
|
||||||
// height: 100%
|
|
||||||
// display: table
|
|
||||||
// margin: 0
|
|
||||||
// padding: 0
|
|
||||||
// border: 0
|
|
||||||
//
|
|
||||||
// .bodyTable
|
|
||||||
// display: table
|
|
||||||
// margin: 0
|
|
||||||
// padding: 0
|
|
||||||
// border: 0
|
|
||||||
// .bodyTableRow
|
|
||||||
// display: table-row
|
|
||||||
// .bodyTableCell
|
|
||||||
// display: table-cell
|
|
||||||
//
|
|
||||||
// .left
|
|
||||||
// display: table-cell
|
|
||||||
// border: 0
|
|
||||||
// vertical-align: top
|
|
||||||
// padding: 0
|
|
||||||
// text-align: left
|
|
||||||
// width: 220px
|
|
||||||
// height: 100%
|
|
||||||
// //Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#627d4d+0,1f3b08+100;Olive+3D
|
|
||||||
// background: #627d4d //Old browsers
|
|
||||||
// background: -moz-linear-gradient(-180deg, #627d4d 0%, #1f3b08 100%) //FF3.6-15
|
|
||||||
// background: -webkit-linear-gradient(-180deg, #627d4d 0%,#1f3b08 100%) //Chrome10-25,Safari5.1-6
|
|
||||||
// background: linear-gradient(180deg, #627d4d 0%,#1f3b08 100%) //W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+
|
|
||||||
// font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif
|
|
||||||
// font-size: 14px
|
|
||||||
// font-weight: 700
|
|
||||||
//
|
|
||||||
// ul
|
|
||||||
// padding: 50px 0 0 0
|
|
||||||
// margin: 0
|
|
||||||
// list-style: none
|
|
||||||
//
|
|
||||||
// li:first-child
|
|
||||||
// border-top: 1px solid #e4e5e7
|
|
||||||
// li
|
|
||||||
// border-bottom: 1px solid #e4e5e7
|
|
||||||
// color: #96a2ae
|
|
||||||
// text-transform: uppercase
|
|
||||||
// display: block
|
|
||||||
//
|
|
||||||
// a
|
|
||||||
// color: #96a2ae
|
|
||||||
// padding: 15px 20px
|
|
||||||
// cursor: pointer
|
|
||||||
// text-decoration: none
|
|
||||||
// display: block
|
|
||||||
//
|
|
||||||
// .tag
|
|
||||||
// padding: .2em .5em
|
|
||||||
// font-size: .7em
|
|
||||||
// color: #fff
|
|
||||||
// white-space: nowrap
|
|
||||||
// vertical-align: baseline
|
|
||||||
// border-radius: .25em
|
|
||||||
// border: 1px solid #000000
|
|
||||||
// float: right
|
|
||||||
// li:hover
|
|
||||||
// background-color: #333
|
|
||||||
// li.active
|
|
||||||
// background-color: #333
|
|
||||||
//
|
|
||||||
// .header
|
|
||||||
// height: 1px
|
|
||||||
// background: #627d4d
|
|
||||||
// width: 100%
|
|
||||||
// .content
|
|
||||||
// background: white
|
|
||||||
// .footer
|
|
||||||
// text-align: center
|
|
||||||
// height: 1px;
|
|
||||||
// background: #1f3b08
|
|
||||||
// color: white
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
//.header
|
|
||||||
// display: table-row
|
|
||||||
// height: 1px
|
|
||||||
// background: #627d4d
|
|
||||||
//
|
|
||||||
//#layoutBody.body
|
|
||||||
// display: table
|
|
||||||
// margin: 0
|
|
||||||
// padding: 0
|
|
||||||
// width: 100%
|
|
||||||
// height: 100%
|
|
||||||
//
|
|
||||||
// .body
|
|
||||||
// display: table-row
|
|
||||||
// width: 100%
|
|
||||||
//
|
|
||||||
// .left
|
|
||||||
// display: table-cell
|
|
||||||
// border: 0
|
|
||||||
// vertical-align: top
|
|
||||||
// padding: 0
|
|
||||||
// text-align: left
|
|
||||||
// width: 220px
|
|
||||||
// //Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#627d4d+0,1f3b08+100;Olive+3D
|
|
||||||
// background: #627d4d //Old browsers
|
|
||||||
// background: -moz-linear-gradient(-180deg, #627d4d 0%, #1f3b08 100%) //FF3.6-15
|
|
||||||
// background: -webkit-linear-gradient(-180deg, #627d4d 0%,#1f3b08 100%) //Chrome10-25,Safari5.1-6
|
|
||||||
// background: linear-gradient(180deg, #627d4d 0%,#1f3b08 100%) //W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+
|
|
||||||
// font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif
|
|
||||||
// font-size: 14px;
|
|
||||||
// font-weight: 700
|
|
||||||
//
|
|
||||||
// ul
|
|
||||||
// padding: 50px 0 0 0
|
|
||||||
// margin: 0
|
|
||||||
// list-style: none
|
|
||||||
//
|
|
||||||
// li:first-child
|
|
||||||
// border-top: 1px solid #e4e5e7
|
|
||||||
// li
|
|
||||||
// border-bottom: 1px solid #e4e5e7
|
|
||||||
// color: #96a2ae
|
|
||||||
// text-transform: uppercase
|
|
||||||
// display: block
|
|
||||||
//
|
|
||||||
// a
|
|
||||||
// color: #96a2ae
|
|
||||||
// padding: 15px 20px
|
|
||||||
// cursor: pointer
|
|
||||||
// text-decoration: none
|
|
||||||
// display: block
|
|
||||||
//
|
|
||||||
// .tag
|
|
||||||
// padding: .2em .5em
|
|
||||||
// font-size: .7em
|
|
||||||
// color: #fff
|
|
||||||
// white-space: nowrap
|
|
||||||
// vertical-align: baseline
|
|
||||||
// border-radius: .25em
|
|
||||||
// border: 1px solid #000000
|
|
||||||
// float: right
|
|
||||||
// li:hover
|
|
||||||
// background-color: #333
|
|
||||||
// li.active
|
|
||||||
// background-color: #333
|
|
||||||
// .main
|
|
||||||
// display: table-row
|
|
||||||
// background: white
|
|
||||||
// border: 0
|
|
||||||
// vertical-align: top
|
|
||||||
// padding: 0
|
|
||||||
// text-align: left
|
|
||||||
//
|
|
||||||
// .footer
|
|
||||||
// display: table-row
|
|
||||||
// text-align: center
|
|
||||||
// height: 1px;
|
|
||||||
// background: #1f3b08
|
|
||||||
// color: white
|
|
||||||
@@ -5,5 +5,12 @@ import './Body.html';
|
|||||||
Template.Body.events({
|
Template.Body.events({
|
||||||
"click .signOut": function(event, template) {
|
"click .signOut": function(event, template) {
|
||||||
AccountsTemplates.logout();
|
AccountsTemplates.logout();
|
||||||
|
},
|
||||||
|
"click .leftSidebarMenuButton": function(event, template) {
|
||||||
|
event.preventDefault();
|
||||||
|
$('nav.leftSidebarContainer').toggleClass('menuShow');
|
||||||
|
},
|
||||||
|
"click .menuArea a": function(event, template) {
|
||||||
|
$('nav.leftSidebarContainer').toggleClass('menuShow');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -38,3 +38,34 @@ Date.prototype.getWeek = function() {
|
|||||||
|
|
||||||
return weeknum;
|
return weeknum;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Date.prototype.getUTCWeek = function() {
|
||||||
|
let dowOffset = 1; // I am fixing this to indicate that the first day of the week is always Monday (weeks end on Sunday), for this application. This was a parameter in the original code.
|
||||||
|
|
||||||
|
//dowOffset = typeof(dowOffset) == 'number' ? dowOffset : 0; //default dowOffset to zero - This should check to ensure that dowOffset is between 0..6
|
||||||
|
let newYear = new Date(this.getUTCFullYear(),0,1);
|
||||||
|
let day = newYear.getDay() - dowOffset; //the day of week the year begins on
|
||||||
|
day = (day >= 0 ? day : day + 7);
|
||||||
|
// The number of days from the beginning of the year to this.day
|
||||||
|
let daynum = Math.floor((this.getTime() - newYear.getTime() - (this.getTimezoneOffset() - newYear.getTimezoneOffset())*60000)/86400000) + 1;
|
||||||
|
let weeknum;
|
||||||
|
|
||||||
|
// I have removed the mid-week starting cutoff detection because in this app we always want to start with week #1 (never have a week zero).
|
||||||
|
//if(day < 4) { //if the year starts before the middle of a week
|
||||||
|
weeknum = Math.floor((daynum + day - 1) / 7) + 1;
|
||||||
|
|
||||||
|
// I have turned off the detection of whether the last days of the year belong to this year's last week or next year's first week. This gets too confusing and does not result in any additional usefulness.
|
||||||
|
//if(weeknum > 52) {
|
||||||
|
// nYear = new Date(this.getFullYear() + 1, 0, 1);
|
||||||
|
// nday = nYear.getDay() - dowOffset;
|
||||||
|
// nday = nday >= 0 ? nday : nday + 7;
|
||||||
|
// // if the next year starts before the middle of the week, it is week #1 of that year
|
||||||
|
// weeknum = nday < 4 ? 1 : 53;
|
||||||
|
//}
|
||||||
|
//}
|
||||||
|
//else {
|
||||||
|
// weeknum = Math.floor((daynum+day-1)/7);
|
||||||
|
//}
|
||||||
|
|
||||||
|
return weeknum;
|
||||||
|
};
|
||||||
@@ -16,14 +16,16 @@ Meteor.methods({
|
|||||||
|
|
||||||
for(let i = 0; i < sales.length; i++) {
|
for(let i = 0; i < sales.length; i++) {
|
||||||
let dateString = sales[i].date.toString();
|
let dateString = sales[i].date.toString();
|
||||||
dateString = dateString.substring(0, 4) + "-" + dateString.substring(4,6) + "-" + dateString.substring(6,8) + "T00:00:00Z";
|
let timestamp = new Date(Date.UTC(parseInt(dateString.substring(0, 4)), parseInt(dateString.substring(4,6)) - 1, parseInt(dateString.substring(6,8))));
|
||||||
let timestamp = new Date(dateString);
|
let weekOfYear = timestamp.getUTCWeek();
|
||||||
let weekOfYear = timestamp.getWeek();
|
|
||||||
|
|
||||||
//console.log("Converted " + sales[i].date + " to " + timestamp + " using " + dateString);
|
if(sales[i]._id === "s9hJLRsQhha3w3ce2") {
|
||||||
|
console.log(parseInt(dateString.substring(6,8)));
|
||||||
|
console.log("Converted " + sales[i].date + " to " + timestamp + " where the week # is " + weekOfYear);
|
||||||
|
}
|
||||||
|
|
||||||
// Save to the database.
|
// Save to the database.
|
||||||
Sales.update(sales[i]._id, {$set: {timestamp, weekOfYear}}, {bypassCollection2: true}, function(err, id) {
|
Sales.update(sales[i]._id, {$set: {"timestamp": timestamp.getTime(), weekOfYear}}, {bypassCollection2: true}, function(err, id) {
|
||||||
if(err) console.log(err);
|
if(err) console.log(err);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user