Added a lot of functionality; Fixed a large number of bugs; Removed Bootstrap from the mix and replaced it with SimpleGrid and some choice bits from the bootstrap system; Pricing, Sales, and Product management all now function at basic levels.
This commit is contained in:
@@ -182,9 +182,7 @@
|
|||||||
<item url="file://C:/Tools/.meteor/packages/spacebars-compiler/1.0.13/web.browser/optimizer.js" />
|
<item url="file://C:/Tools/.meteor/packages/spacebars-compiler/1.0.13/web.browser/optimizer.js" />
|
||||||
<item url="file://C:/Tools/.meteor/packages/templating-runtime/1.2.15/web.browser/dynamic.js" />
|
<item url="file://C:/Tools/.meteor/packages/templating-runtime/1.2.15/web.browser/dynamic.js" />
|
||||||
<item url="file://C:/Tools/.meteor/packages/templating-runtime/1.2.15/web.browser/templating.js" />
|
<item url="file://C:/Tools/.meteor/packages/templating-runtime/1.2.15/web.browser/templating.js" />
|
||||||
<item url="file://C:/Tools/.meteor/packages/twbs_bootstrap/3.3.6/web.browser/dist/js/bootstrap.js" />
|
|
||||||
<item url="file://C:/Tools/.meteor/packages/templating-tools/1.0.5/web.browser/templating-tools.js" />
|
<item url="file://C:/Tools/.meteor/packages/templating-tools/1.0.5/web.browser/templating-tools.js" />
|
||||||
<item url="file://C:/Tools/.meteor/packages/twbs_bootstrap/3.3.6/web.browser/dist/css/bootstrap.css" />
|
|
||||||
<item url="file://C:/Tools/.meteor/packages/templating-tools/1.0.5/web.browser/compile-tags-with-spacebars.js" />
|
<item url="file://C:/Tools/.meteor/packages/templating-tools/1.0.5/web.browser/compile-tags-with-spacebars.js" />
|
||||||
<item url="file://C:/Tools/.meteor/packages/templating-tools/1.0.5/web.browser/html-scanner.js" />
|
<item url="file://C:/Tools/.meteor/packages/templating-tools/1.0.5/web.browser/html-scanner.js" />
|
||||||
<item url="file://C:/Tools/.meteor/packages/templating-tools/1.0.5/web.browser/html-scanner-tests.js" />
|
<item url="file://C:/Tools/.meteor/packages/templating-tools/1.0.5/web.browser/html-scanner-tests.js" />
|
||||||
@@ -593,9 +591,7 @@
|
|||||||
<root url="file://C:/Tools/.meteor/packages/spacebars-compiler/1.0.13/web.browser/optimizer.js" />
|
<root url="file://C:/Tools/.meteor/packages/spacebars-compiler/1.0.13/web.browser/optimizer.js" />
|
||||||
<root url="file://C:/Tools/.meteor/packages/templating-runtime/1.2.15/web.browser/dynamic.js" />
|
<root url="file://C:/Tools/.meteor/packages/templating-runtime/1.2.15/web.browser/dynamic.js" />
|
||||||
<root url="file://C:/Tools/.meteor/packages/templating-runtime/1.2.15/web.browser/templating.js" />
|
<root url="file://C:/Tools/.meteor/packages/templating-runtime/1.2.15/web.browser/templating.js" />
|
||||||
<root url="file://C:/Tools/.meteor/packages/twbs_bootstrap/3.3.6/web.browser/dist/js/bootstrap.js" />
|
|
||||||
<root url="file://C:/Tools/.meteor/packages/templating-tools/1.0.5/web.browser/templating-tools.js" />
|
<root url="file://C:/Tools/.meteor/packages/templating-tools/1.0.5/web.browser/templating-tools.js" />
|
||||||
<root url="file://C:/Tools/.meteor/packages/twbs_bootstrap/3.3.6/web.browser/dist/css/bootstrap.css" />
|
|
||||||
<root url="file://C:/Tools/.meteor/packages/templating-tools/1.0.5/web.browser/compile-tags-with-spacebars.js" />
|
<root url="file://C:/Tools/.meteor/packages/templating-tools/1.0.5/web.browser/compile-tags-with-spacebars.js" />
|
||||||
<root url="file://C:/Tools/.meteor/packages/templating-tools/1.0.5/web.browser/html-scanner.js" />
|
<root url="file://C:/Tools/.meteor/packages/templating-tools/1.0.5/web.browser/html-scanner.js" />
|
||||||
<root url="file://C:/Tools/.meteor/packages/templating-tools/1.0.5/web.browser/html-scanner-tests.js" />
|
<root url="file://C:/Tools/.meteor/packages/templating-tools/1.0.5/web.browser/html-scanner-tests.js" />
|
||||||
|
|||||||
1094
.idea/workspace.xml
generated
1094
.idea/workspace.xml
generated
File diff suppressed because it is too large
Load Diff
@@ -53,7 +53,7 @@ zimme:collection-softremovable
|
|||||||
#aldeed:schema-index # Addon for Collection2-core to use index or unique options.
|
#aldeed:schema-index # Addon for Collection2-core to use index or unique options.
|
||||||
#skehoe1989:autoform-relations # Adds relations to autoform
|
#skehoe1989:autoform-relations # Adds relations to autoform
|
||||||
|
|
||||||
twbs:bootstrap
|
#twbs:bootstrap # Requires jquery 1.9-2.x, not 3+
|
||||||
fortawesome:fontawesome
|
fortawesome:fontawesome
|
||||||
momentjs:moment
|
momentjs:moment
|
||||||
mizzao:bootboxjs # ???
|
mizzao:bootboxjs # ???
|
||||||
|
|||||||
@@ -114,7 +114,6 @@ templating-runtime@1.2.15
|
|||||||
templating-tools@1.0.5
|
templating-tools@1.0.5
|
||||||
tomwasd:history-polyfill@0.0.1
|
tomwasd:history-polyfill@0.0.1
|
||||||
tracker@1.1.1
|
tracker@1.1.1
|
||||||
twbs:bootstrap@3.3.6
|
|
||||||
ui@1.0.12
|
ui@1.0.12
|
||||||
underscore@1.0.10
|
underscore@1.0.10
|
||||||
url@1.0.11
|
url@1.0.11
|
||||||
|
|||||||
54
client/bootstrap.styl
vendored
54
client/bootstrap.styl
vendored
@@ -14,10 +14,10 @@ input[type="search"]:focus,
|
|||||||
input[type="tel"]:focus,
|
input[type="tel"]:focus,
|
||||||
input[type="color"]:focus,
|
input[type="color"]:focus,
|
||||||
.uneditable-input:focus,
|
.uneditable-input:focus,
|
||||||
.list-group:focus {
|
.list-group:focus
|
||||||
border-color: rgba(82, 168, 236, 0.8);
|
border-color: rgba(82, 168, 236, 0.8)
|
||||||
outline: 0;
|
outline: 0
|
||||||
outline: thin dotted \9;
|
outline: thin dotted \9
|
||||||
/* IE6-9 */
|
/* IE6-9 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -25,37 +25,30 @@ input[type="color"]:focus,
|
|||||||
-moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6);
|
-moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6);
|
||||||
box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6);
|
box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6);
|
||||||
*/
|
*/
|
||||||
-webkit-box-shadow: 0px 0px 46px -13px rgba(230,28,230,1) !important;
|
-webkit-box-shadow: 0px 0px 46px -13px rgba(230,28,230,1) !important
|
||||||
-moz-box-shadow: 0px 0px 46px -13px rgba(230,28,230,1) !important;
|
-moz-box-shadow: 0px 0px 46px -13px rgba(230,28,230,1) !important
|
||||||
box-shadow: 0px 0px 46px -13px rgba(230,28,230,1) !important;
|
box-shadow: 0px 0px 46px -13px rgba(230,28,230,1) !important
|
||||||
|
|
||||||
}
|
.form-control
|
||||||
|
font-size: 14px
|
||||||
|
margin-bottom: 0px
|
||||||
|
|
||||||
.form-control, .select2-selection {
|
.input-group
|
||||||
font-size: 14px;
|
margin-bottom: 15px
|
||||||
margin-bottom: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-group {
|
.select2 .select2-selection
|
||||||
margin-bottom: 15px;
|
border-color: #ccc
|
||||||
}
|
|
||||||
|
|
||||||
.select2 .select2-selection {
|
.select2-container--default.select2-container--focus .select2-selection--multiple
|
||||||
border-color: #ccc;
|
border-color: rgba(101, 174, 231, 0.823529)
|
||||||
}
|
outline: 0
|
||||||
|
outline: thin dotted \9
|
||||||
|
-webkit-box-shadow: 0px 0px 46px -11px rgba(230,28,230,1) !important
|
||||||
|
-moz-box-shadow: 0px 0px 46px -11px rgba(230,28,230,1) !important
|
||||||
|
box-shadow: 0px 0px 46px -11px rgba(230,28,230,1) !important
|
||||||
|
|
||||||
.select2-container--default.select2-container--focus .select2-selection--multiple {
|
.has-error
|
||||||
border-color: rgba(101, 174, 231, 0.823529);
|
border-color: #a94442 !important
|
||||||
outline: 0;
|
|
||||||
outline: thin dotted \9;
|
|
||||||
|
|
||||||
-webkit-box-shadow: 0px 0px 46px -11px rgba(230,28,230,1) !important;
|
|
||||||
-moz-box-shadow: 0px 0px 46px -11px rgba(230,28,230,1) !important;
|
|
||||||
box-shadow: 0px 0px 46px -11px rgba(230,28,230,1) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.has-error {
|
|
||||||
border-color: #a94442 !important;
|
|
||||||
/*
|
/*
|
||||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075) !important;
|
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075) !important;
|
||||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075) !important;
|
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075) !important;
|
||||||
@@ -66,4 +59,3 @@ input[type="color"]:focus,
|
|||||||
-moz-box-shadow: 0px 0px 46px -13px rgba(255,28,230,1) !important;
|
-moz-box-shadow: 0px 0px 46px -13px rgba(255,28,230,1) !important;
|
||||||
box-shadow: 0px 0px 46px -13px rgba(255,28,230,1) !important;
|
box-shadow: 0px 0px 46px -13px rgba(255,28,230,1) !important;
|
||||||
*/
|
*/
|
||||||
}
|
|
||||||
@@ -1,17 +1,22 @@
|
|||||||
import {Meteor} from 'meteor/meteor';
|
import {Meteor} from 'meteor/meteor';
|
||||||
import '/imports/startup/client'
|
import '/imports/startup/client';
|
||||||
import '/imports/startup/both'
|
import '/imports/startup/both';
|
||||||
import '/imports/api';
|
import '/imports/api';
|
||||||
import '/imports/ui/helpers.js';
|
import '/imports/ui/helpers.js';
|
||||||
|
// import '/imports/util/normalize.css';
|
||||||
import '/imports/util/validator.js';
|
import '/imports/util/validator.js';
|
||||||
import '/imports/util/blaze.js';
|
import '/imports/util/polyfills/blaze.js';
|
||||||
import '/imports/util/date.js';
|
import '/imports/util/polyfills/date.js';
|
||||||
|
import '/imports/util/polyfills/array.js';
|
||||||
import '/imports/util/de.combo.js';
|
import '/imports/util/de.combo.js';
|
||||||
import '/imports/util/resize/ResizeSensor.js';
|
import '/imports/util/resize/ResizeSensor.js';
|
||||||
import '/imports/util/resize/ElementQueries.js';
|
import '/imports/util/resize/ElementQueries.js';
|
||||||
import '/imports/ui/layouts/Body.js';
|
import '/imports/ui/layouts/Body.js';
|
||||||
import '/imports/ui/layouts/Full.js';
|
import '/imports/ui/layouts/Full.js';
|
||||||
import '/imports/ui/accounts/accounts.js';
|
import '/imports/ui/accounts/accounts.js';
|
||||||
|
import '/imports/util/select2/select2.css';
|
||||||
|
import '/imports/util/select2/select2.full.js';
|
||||||
|
import '/imports/util/simplegrid.css';
|
||||||
|
|
||||||
Blaze._allowJavascriptUrls();
|
Blaze._allowJavascriptUrls();
|
||||||
|
|
||||||
|
|||||||
239
client/main.styl
239
client/main.styl
@@ -1,7 +1,12 @@
|
|||||||
*
|
*
|
||||||
box-sizing: border-box
|
|
||||||
-webkit-tap-highlight-color: transparent
|
-webkit-tap-highlight-color: transparent
|
||||||
-webkit-font-smoothing: antialiased
|
-webkit-font-smoothing: antialiased
|
||||||
|
*, *:after, *:before
|
||||||
|
-webkit-box-sizing: border-box
|
||||||
|
-moz-box-sizing: border-box
|
||||||
|
box-sizing: border-box
|
||||||
|
padding: 0
|
||||||
|
margin: 0
|
||||||
|
|
||||||
html
|
html
|
||||||
scrollbar-face-color: #808080
|
scrollbar-face-color: #808080
|
||||||
@@ -19,7 +24,7 @@ html, body, #archives ul, #overall-footer, #content ul
|
|||||||
|
|
||||||
body
|
body
|
||||||
font-family: verdana, arial, helvetica, sans-serif
|
font-family: verdana, arial, helvetica, sans-serif
|
||||||
font-size: 1.0em
|
font-size: 12px
|
||||||
height: 100%
|
height: 100%
|
||||||
|
|
||||||
#__blaze-root
|
#__blaze-root
|
||||||
@@ -39,6 +44,7 @@ body
|
|||||||
//min-height: 100%;
|
//min-height: 100%;
|
||||||
//min-width: 100%;
|
//min-width: 100%;
|
||||||
|
|
||||||
|
//Standard Stylings
|
||||||
.noselect
|
.noselect
|
||||||
-webkit-touch-callout: none; /* iOS Safari */
|
-webkit-touch-callout: none; /* iOS Safari */
|
||||||
-webkit-user-select: none; /* Chrome/Safari/Opera */
|
-webkit-user-select: none; /* Chrome/Safari/Opera */
|
||||||
@@ -52,20 +58,245 @@ body
|
|||||||
cursor: default
|
cursor: default
|
||||||
.left
|
.left
|
||||||
text-align: left
|
text-align: left
|
||||||
|
.right
|
||||||
|
text-align: right
|
||||||
.center
|
.center
|
||||||
text-align: center
|
text-align: center
|
||||||
|
.floatLeft
|
||||||
|
float: left
|
||||||
|
.floatRight
|
||||||
|
float: right
|
||||||
|
|
||||||
|
//Table Styles
|
||||||
|
.table
|
||||||
|
border: 0
|
||||||
|
padding: 0
|
||||||
|
margin: 0
|
||||||
|
border-collapse: collapse
|
||||||
|
border: 1px solid #ddddf9
|
||||||
|
> thead
|
||||||
|
> tr
|
||||||
|
> th
|
||||||
|
border: 0
|
||||||
|
padding: 4px 4px 8px 4px
|
||||||
|
vertical-align: top
|
||||||
|
color: white
|
||||||
|
background: #6f6fec
|
||||||
|
input
|
||||||
|
padding: 2px
|
||||||
|
border-radius: 3px
|
||||||
|
|
||||||
|
> tbody
|
||||||
|
> tr
|
||||||
|
border-bottom: 1px solid #aaa
|
||||||
|
> td
|
||||||
|
padding: 4px 4px
|
||||||
|
> tr.selected
|
||||||
|
background-attachment: fixed
|
||||||
|
background-repeat: no-repeat
|
||||||
|
background-position: 0 0
|
||||||
|
background-image: linear-gradient(to left, #E0DCBA 70%,#f1da36 100%)
|
||||||
|
> tr:nth-child(odd).selected
|
||||||
|
background-attachment: fixed
|
||||||
|
background-repeat: no-repeat
|
||||||
|
background-position: 0 0
|
||||||
|
background-image: linear-gradient(to left, #FCF8D1 70%,#f1da36 100%)
|
||||||
|
.table-striped > tbody > tr:nth-child(even)
|
||||||
|
background-color: #f4f4f4
|
||||||
|
.table-striped > tbody > tr:nth-child(odd)
|
||||||
|
background-color: white
|
||||||
|
.table-hover > tbody > tr:hover
|
||||||
|
background-color: #ded
|
||||||
|
|
||||||
|
//Form Styles
|
||||||
|
.select2-container
|
||||||
|
font-size: 10px
|
||||||
|
.select2-selection
|
||||||
|
font-size: 13px //Make the font small enough the control can have a height similar to a standard input field.
|
||||||
|
margin-bottom: 0px
|
||||||
|
min-height: 10px !important //This is what really sets the height of the box containing the selection(s)
|
||||||
|
padding-bottom: 2px //Add a little space below the selections to balance it all out.
|
||||||
|
input
|
||||||
|
padding: 6px
|
||||||
|
border-radius: 4px
|
||||||
|
border-width: 1px
|
||||||
|
border-style: solid
|
||||||
|
border-color: #ccc
|
||||||
|
//input[type='button'].btn-success, input[type='submit'].btn-success
|
||||||
|
// background-color: #5cb85c
|
||||||
|
// :hover
|
||||||
|
// background-color:
|
||||||
|
//input[type='button'].btn-danger, input[type='submit'].btn-danger
|
||||||
|
// background-color: #e55b46
|
||||||
|
.form-control, .select2-selection //?
|
||||||
|
font-size: 14px
|
||||||
|
margin-bottom: 0px
|
||||||
|
.form-group
|
||||||
|
margin: 4px 0
|
||||||
|
.has-error .form-control
|
||||||
|
border-color: #a94442
|
||||||
|
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075)
|
||||||
|
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075)
|
||||||
|
|
||||||
|
@media screen and (-webkit-min-device-pixel-ratio: 0)
|
||||||
|
input[type="date"].form-control, input[type="time"].form-control, input[type="datetime-local"].form-control, input[type="month"].form-control
|
||||||
|
line-height: 34px
|
||||||
|
|
||||||
|
.form-control
|
||||||
|
display: block
|
||||||
|
width: 100%
|
||||||
|
height: 34px
|
||||||
|
padding: 6px 12px
|
||||||
|
font-size: 14px
|
||||||
|
line-height: 1.42857143
|
||||||
|
color: #555
|
||||||
|
background-color: #fff
|
||||||
|
background-image: none
|
||||||
|
border: 1px solid #ccc
|
||||||
|
border-radius: 4px
|
||||||
|
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075)
|
||||||
|
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075)
|
||||||
|
-webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s
|
||||||
|
-o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s
|
||||||
|
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s
|
||||||
|
input[type="date" i], input[type="datetime-local" i], input[type="month" i], input[type="time" i], input[type="week" i]
|
||||||
|
align-items: center
|
||||||
|
-webkit-padding-start: 1px
|
||||||
|
overflow: hidden
|
||||||
|
padding-left: 10px
|
||||||
|
input
|
||||||
|
-webkit-appearance: textfield
|
||||||
|
background-color: white
|
||||||
|
-webkit-rtl-ordering: logical
|
||||||
|
user-select: text
|
||||||
|
cursor: auto
|
||||||
|
padding: 1px
|
||||||
|
border-width: 2px
|
||||||
|
border-style: inset
|
||||||
|
border-color: initial
|
||||||
|
border-image: initial
|
||||||
|
.form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control
|
||||||
|
background-color: #eee
|
||||||
|
opacity: 1
|
||||||
|
input, textarea, keygen, select, button
|
||||||
|
text-rendering: auto
|
||||||
|
color: initial
|
||||||
|
letter-spacing: normal
|
||||||
|
word-spacing: normal
|
||||||
|
text-transform: none
|
||||||
|
text-indent: 0px
|
||||||
|
text-shadow: none
|
||||||
|
display: inline-block
|
||||||
|
text-align: start
|
||||||
|
margin: 0em 0em 0em 0em
|
||||||
|
font: 13.3333px Arial
|
||||||
|
input, textarea, keygen, select, button, meter, progress
|
||||||
|
-webkit-writing-mode: horizontal-tb
|
||||||
|
//.btn.disabled, .btn[disabled], fieldset[disabled] .btn
|
||||||
|
// cursor: not-allowed
|
||||||
|
// filter: unquote("alpha(opacity=65)")
|
||||||
|
// -webkit-box-shadow: none
|
||||||
|
// box-shadow: none
|
||||||
|
// opacity: .65
|
||||||
|
//button, html input[type="button"], input[type="reset"], input[type="submit"]
|
||||||
|
// -webkit-appearance: button
|
||||||
|
// cursor: pointer
|
||||||
|
//button, html input[type="button"], input[type="reset"], input[type="submit"]
|
||||||
|
// -webkit-appearance: button
|
||||||
|
// cursor: pointer
|
||||||
|
//.btn
|
||||||
|
// display: inline-block;
|
||||||
|
// padding: 6px 12px;
|
||||||
|
// margin-bottom: 0;
|
||||||
|
// font-size: 14px;
|
||||||
|
// font-weight: normal;
|
||||||
|
// line-height: 1.42857143;
|
||||||
|
// text-align: center;
|
||||||
|
// white-space: nowrap;
|
||||||
|
// vertical-align: middle;
|
||||||
|
// -ms-touch-action: manipulation;
|
||||||
|
// touch-action: manipulation;
|
||||||
|
// cursor: pointer;
|
||||||
|
// -webkit-user-select: none;
|
||||||
|
// -moz-user-select: none;
|
||||||
|
// -ms-user-select: none;
|
||||||
|
// user-select: none;
|
||||||
|
// background-image: none;
|
||||||
|
// border: 1px solid transparent;
|
||||||
|
// border-radius: 4px;
|
||||||
|
|
||||||
|
.pagination
|
||||||
|
text-align: right
|
||||||
|
font-size: 15px
|
||||||
|
line-height: 34px
|
||||||
|
font-family: "Arial Black", "Arial Bold", Gadget, sans-serif
|
||||||
|
margin: 0 0 10px 0
|
||||||
|
overflow: visible
|
||||||
|
whitespace: nowrap
|
||||||
|
span
|
||||||
|
padding: 2px 8px 3px 8px
|
||||||
|
margin: 0 8px
|
||||||
|
border: 2px solid #7b9961
|
||||||
|
border-radius: 5px
|
||||||
|
background-color: #90b272
|
||||||
|
cursor: pointer
|
||||||
|
overflow: visible
|
||||||
|
whitespace: nowrap
|
||||||
|
span:hover
|
||||||
|
background-color: #4ca84c
|
||||||
|
span:active
|
||||||
|
background-color: #3c983c
|
||||||
|
span.disabled
|
||||||
|
background-color: #ccc
|
||||||
|
border-color: #c5c5c5
|
||||||
|
color: white
|
||||||
|
cursor: default
|
||||||
|
span.disabled:hover
|
||||||
|
background-color: #ccc
|
||||||
|
span.disabled:active
|
||||||
|
background-color: #ccc
|
||||||
|
|
||||||
|
//.pagination
|
||||||
|
// width: 100%
|
||||||
|
// text-align: center
|
||||||
|
// font-size: 15px
|
||||||
|
// line-height: 18px
|
||||||
|
// font-family: "Arial Black", "Arial Bold", Gadget, sans-serif
|
||||||
|
// span
|
||||||
|
// padding: 3px 8px 4px 8px
|
||||||
|
// margin: 0 8px
|
||||||
|
// border: 2px solid #4a4
|
||||||
|
// border-radius: 18px
|
||||||
|
// background-color: #5cb85c
|
||||||
|
// cursor: pointer
|
||||||
|
// span:hover
|
||||||
|
// background-color: #4ca84c
|
||||||
|
// span:active
|
||||||
|
// background-color: #3c983c
|
||||||
|
// span.disabled
|
||||||
|
// background-color: #ccc
|
||||||
|
// border-color: #c5c5c5
|
||||||
|
// color: white
|
||||||
|
// cursor: default
|
||||||
|
// span.disabled:hover
|
||||||
|
// background-color: #ccc
|
||||||
|
// span.disabled:active
|
||||||
|
// background-color: #ccc
|
||||||
|
|
||||||
|
//Override the SimpleGrid css
|
||||||
|
.grid
|
||||||
|
overflow: visible !important
|
||||||
|
max-width: none !important
|
||||||
|
|
||||||
//@import "../imports/util/selectize/selectize.default.import.styl"
|
//@import "../imports/util/selectize/selectize.default.import.styl"
|
||||||
//@import "../imports/util/selectize/selectize.import.styl"
|
//@import "../imports/util/selectize/selectize.import.styl"
|
||||||
@import "../imports/util/de.combo.import.styl"
|
@import "../imports/util/de.combo.import.styl"
|
||||||
|
@import "../imports/util/bootstrap-like-btn.import.styl"
|
||||||
|
|
||||||
@import "../imports/ui/layouts/Body.import.styl"
|
@import "../imports/ui/layouts/Body.import.styl"
|
||||||
@import "../imports/ui/layouts/Full.import.styl"
|
@import "../imports/ui/layouts/Full.import.styl"
|
||||||
|
|
||||||
@import "../imports/ui/UserManagement.import.styl"
|
@import "../imports/ui/UserManagement.import.styl"
|
||||||
@import "../imports/ui/Menu.import.styl"
|
|
||||||
@import "../imports/ui/Intro.import.styl"
|
|
||||||
@import "../imports/ui/Measures.import.styl"
|
@import "../imports/ui/Measures.import.styl"
|
||||||
@import "../imports/ui/Products.import.styl"
|
@import "../imports/ui/Products.import.styl"
|
||||||
@import "../imports/ui/ProductTags.import.styl"
|
@import "../imports/ui/ProductTags.import.styl"
|
||||||
|
|||||||
@@ -44,8 +44,9 @@ const ProductsSchema = new SimpleSchema({
|
|||||||
type: Object,
|
type: Object,
|
||||||
//blackbox: true,
|
//blackbox: true,
|
||||||
custom: function() {
|
custom: function() {
|
||||||
console.log("In custom validation for prices");
|
//console.log("In custom validation for prices");
|
||||||
return true;
|
//return true;
|
||||||
|
|
||||||
// if(this.value != undefined) {
|
// if(this.value != undefined) {
|
||||||
// console.log(this.value);
|
// console.log(this.value);
|
||||||
// //check(this, Object);
|
// //check(this, Object);
|
||||||
@@ -120,24 +121,14 @@ const ProductsSchema = new SimpleSchema({
|
|||||||
label: "Updated On",
|
label: "Updated On",
|
||||||
optional: true
|
optional: true
|
||||||
},
|
},
|
||||||
deletedAt: {
|
deactivated: {
|
||||||
type: Date,
|
type: Boolean,
|
||||||
label: "Deleted On",
|
label: "Deactivated",
|
||||||
optional: true
|
optional: true
|
||||||
},
|
},
|
||||||
deletedBy: {
|
hidden: {
|
||||||
type: String,
|
type: Boolean,
|
||||||
label: "Deleted By",
|
label: "Hidden",
|
||||||
optional: true
|
|
||||||
},
|
|
||||||
restoredAt: {
|
|
||||||
type: Date,
|
|
||||||
label: "Restored On",
|
|
||||||
optional: true
|
|
||||||
},
|
|
||||||
restoredBy: {
|
|
||||||
type: String,
|
|
||||||
label: "Restored By",
|
|
||||||
optional: true
|
optional: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -165,74 +156,93 @@ const ProductsSchema = new SimpleSchema({
|
|||||||
//Products.attachSchema(ProductsSchema);
|
//Products.attachSchema(ProductsSchema);
|
||||||
|
|
||||||
//https://github.com/zimme/meteor-collection-softremovable
|
//https://github.com/zimme/meteor-collection-softremovable
|
||||||
Products.attachBehaviour("softRemovable", {
|
// Products.attachBehaviour("softRemovable", {
|
||||||
removed: 'deleted',
|
// removed: 'deleted',
|
||||||
removedAt: 'deletedAt',
|
// removedAt: 'deletedAt',
|
||||||
removedBy: 'removedBy',
|
// removedBy: 'removedBy',
|
||||||
restoredAt: 'restoredAt',
|
// restoredAt: 'restoredAt',
|
||||||
restoredBy: 'restoredBy'
|
// restoredBy: 'restoredBy'
|
||||||
});
|
// });
|
||||||
|
|
||||||
if(Meteor.isServer) {
|
if(Meteor.isServer) {
|
||||||
Meteor.publish('products', function() {
|
Meteor.publish('products', function() {
|
||||||
// let dbQuery = {};
|
|
||||||
//
|
|
||||||
// if(query) {
|
|
||||||
// _.each(_.keys(query), function(key) {
|
|
||||||
// if(_.isObject(query[key])) dbQuery[key] = query[key];
|
|
||||||
// else if(_.isNumber(query[key])) dbQuery[key] = query[key];
|
|
||||||
// else dbQuery[key] = {$regex: RegExp.escape(query[key]), $options: 'i'};
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return Products.find(dbQuery, {sort: {date: -1}});
|
|
||||||
return Products.find({}, {sort: {name: 1}});
|
return Products.find({}, {sort: {name: 1}});
|
||||||
});
|
});
|
||||||
|
|
||||||
Meteor.methods({
|
Meteor.methods({
|
||||||
insertProduct: function(product) {
|
createProduct: function(name, tags, aliases, measures) {
|
||||||
check(product, {
|
check(name, String);
|
||||||
name: String
|
if(tags) check(tags, [String]);
|
||||||
});
|
if(aliases) check(aliases, [String]);
|
||||||
|
if(measures) check(measures, [String]);
|
||||||
product.createdAt = new Date();
|
|
||||||
|
|
||||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||||
Products.insert(product, function(err, id) {
|
Products.insert({name, tags, aliases, measures, createdAt: new Date()}, {bypassCollection2: true}, function(err, id) {
|
||||||
if(err) console.log(err);
|
if(err) console.log(err);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else throw new Meteor.Error(403, "Not authorized.");
|
else throw new Meteor.Error(403, "Not authorized.");
|
||||||
},
|
},
|
||||||
deleteProduct: function(id) {
|
deactivateProduct: function(id) {
|
||||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||||
Products.remove(id);
|
//Products.remove(id);
|
||||||
|
Products.update(id, {$set: {deactivated: true}}, {bypassCollection2: true});
|
||||||
}
|
}
|
||||||
else throw new Meteor.Error(403, "Not authorized.");
|
else throw new Meteor.Error(403, "Not authorized.");
|
||||||
},
|
},
|
||||||
updateProduct: function(product) {
|
reactivateProduct: function(id) {
|
||||||
check(product, {
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||||
_id: String,
|
Products.update(id, {$set: {deactivated: false}}, {bypassCollection2: true});
|
||||||
name: String
|
}
|
||||||
});
|
else throw new Meteor.Error(403, "Not authorized.");
|
||||||
|
},
|
||||||
|
hideProduct: function(id) { //One step past deactivated - will only show in the products list if hidden products are enabled.
|
||||||
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||||
|
//Products.remove(id);
|
||||||
|
Products.update(id, {$set: {hidden: true}}, {bypassCollection2: true});
|
||||||
|
}
|
||||||
|
else throw new Meteor.Error(403, "Not authorized.");
|
||||||
|
},
|
||||||
|
showProduct: function(id) { //Returns the product to being simply deactivated. Will again show in lists.
|
||||||
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||||
|
Products.update(id, {$set: {hidden: false}}, {bypassCollection2: true});
|
||||||
|
}
|
||||||
|
else throw new Meteor.Error(403, "Not authorized.");
|
||||||
|
},
|
||||||
|
updateProduct: function(id, name, tags, aliases, measures) {
|
||||||
|
check(id, String);
|
||||||
|
check(name, String);
|
||||||
|
if(tags) check(tags, [String]);
|
||||||
|
if(aliases) check(aliases, [String]);
|
||||||
|
if(measures) check(measures, [String]);
|
||||||
|
|
||||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||||
Products.update(id, {$set: {name: product.name, updateAt: new Date()}});
|
Products.update(id, {$set: {name: name, tags: tags, aliases: aliases, measures: measures, updateAt: new Date()}}, {bypassCollection2: true});
|
||||||
}
|
}
|
||||||
else throw new Meteor.Error(403, "Not authorized.");
|
else throw new Meteor.Error(403, "Not authorized.");
|
||||||
},
|
},
|
||||||
setProductPrice: function(productId, measureId, price, setPrevious, effectiveDate) {
|
clearProductPrice: function(productIds, measureId) {
|
||||||
check(productId, String);
|
check(productIds, [String]);
|
||||||
|
check(measureId, String);
|
||||||
|
|
||||||
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||||
|
let attr = "prices." + measureId;
|
||||||
|
|
||||||
|
Products.update({_id: {$in: productIds}}, {$unset: {[attr]: true}}, {validate: false, bypassCollection2: true});
|
||||||
|
}
|
||||||
|
else throw new Meteor.Error(403, "Not authorized.");
|
||||||
|
},
|
||||||
|
setProductPrice: function(productIds, measureId, price, setPrevious, effectiveDate) {
|
||||||
|
check(productIds, [String]);
|
||||||
check(measureId, String);
|
check(measureId, String);
|
||||||
check(price, Number);
|
check(price, Number);
|
||||||
check(setPrevious, Boolean);
|
if(setPrevious) check(setPrevious, Boolean);
|
||||||
check(effectiveDate, Date);
|
if(effectiveDate) check(effectiveDate, Date);
|
||||||
|
|
||||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||||
let product = Products.findOne(productId, {fields: {prices: 1}});
|
let products = Products.find({_id: {$in: productIds}}, {fields: {prices: 1}}).fetch();
|
||||||
|
|
||||||
if(product) {
|
for(let product of products) {
|
||||||
console.log("Product: " + JSON.stringify(product));
|
|
||||||
let prices = product.prices ? product.prices : {};
|
let prices = product.prices ? product.prices : {};
|
||||||
let measurePriceData = prices[measureId];
|
let measurePriceData = prices[measureId];
|
||||||
|
|
||||||
@@ -240,7 +250,6 @@ if(Meteor.isServer) {
|
|||||||
measurePriceData = {};
|
measurePriceData = {};
|
||||||
prices[measureId] = measurePriceData;
|
prices[measureId] = measurePriceData;
|
||||||
}
|
}
|
||||||
console.log("Old Price Data: " + JSON.stringify(prices));
|
|
||||||
|
|
||||||
if(setPrevious && measurePriceData.price) {
|
if(setPrevious && measurePriceData.price) {
|
||||||
measurePriceData.previousPrice = measurePriceData.price;
|
measurePriceData.previousPrice = measurePriceData.price;
|
||||||
@@ -248,17 +257,29 @@ if(Meteor.isServer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
measurePriceData.price = price;
|
measurePriceData.price = price;
|
||||||
console.log("New Price Data: " + JSON.stringify(prices));
|
|
||||||
//console.log(ProductsSchema.validate(product));
|
|
||||||
//
|
|
||||||
// check(prices, ProductsSchema);
|
|
||||||
if(ProductsSchema.newContext().isValid()) {
|
if(ProductsSchema.newContext().isValid()) {
|
||||||
console.log("Valid schema for product");
|
Products.update(product._id, {$set: {prices: prices, updateAt: new Date()}}, {validate: false, bypassCollection2: true});
|
||||||
Products.update(productId, {$set: {prices: prices, updateAt: new Date()}}, {validate: false, bypassCollection2: true});
|
|
||||||
}
|
}
|
||||||
else console.log("Invalid schema for product");
|
else console.log("Invalid schema for product");
|
||||||
}
|
}
|
||||||
else throw new Meteor.ERROR(400, "Could not find the requested product: " + productId);
|
}
|
||||||
|
else throw new Meteor.Error(403, "Not authorized.");
|
||||||
|
},
|
||||||
|
tagProducts: function(productIds, tagId) {
|
||||||
|
//Tags the products if any products don't have the tag, otherwise removes the tag from all products.
|
||||||
|
check(productIds, [String]);
|
||||||
|
check(tagId, String);
|
||||||
|
|
||||||
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||||
|
let productsWithTag = Products.find({_id: {$in: productIds}, tags: {$all: [tagId]}}).count();
|
||||||
|
|
||||||
|
if(productsWithTag == productIds.length) {
|
||||||
|
Products.update({_id: {$in: productIds}}, {$pullAll: {tags: [tagId]}}, {bypassCollection2: true, multi: true});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Products.update({_id: {$in: productIds}}, {$addToSet: {tags: tagId}}, {bypassCollection2: true, multi: true});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else throw new Meteor.Error(403, "Not authorized.");
|
else throw new Meteor.Error(403, "Not authorized.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,25 @@ if(Meteor.isServer) {
|
|||||||
check(id, String);
|
check(id, String);
|
||||||
|
|
||||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||||
|
//Remove all references to the tag in the products.
|
||||||
|
Meteor.collections.Products.update({tags: {$all: [id]}}, {$pullAll: {tags: [id]}}, {bypassCollection2: true, multi: true});
|
||||||
|
// let products = Meteor.collections.Products.find({tags: {$all: [id]}}, {_id: 1, tags: 1}).fetch();
|
||||||
|
//
|
||||||
|
// //Try to remove all tags from products. Log/Ignore any errors.
|
||||||
|
// for(let product of products) {
|
||||||
|
// try {
|
||||||
|
// let index = product.tags.indexOf(id);
|
||||||
|
//
|
||||||
|
// if(index >= 0) {
|
||||||
|
// product.tags.splice(index, 1);
|
||||||
|
// Meteor.collections.Products.update(products._id, {$set: {tags: product.tags}}, {bypassCollection2: true, multi: true});
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// catch(err) {
|
||||||
|
// console.log(err);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
ProductTags.remove(id);
|
ProductTags.remove(id);
|
||||||
}
|
}
|
||||||
else throw new Meteor.Error(403, "Not authorized.");
|
else throw new Meteor.Error(403, "Not authorized.");
|
||||||
|
|||||||
@@ -62,23 +62,42 @@ let SalesSchema = new SimpleSchema({
|
|||||||
Sales.attachSchema(SalesSchema);
|
Sales.attachSchema(SalesSchema);
|
||||||
|
|
||||||
if(Meteor.isServer) {
|
if(Meteor.isServer) {
|
||||||
Meteor.publish('sales', function(query, limit = 100) {
|
Meteor.publish('sales', function(query, limit = 100, skipCount) {
|
||||||
let dbQuery = {};
|
let dbQuery = [];
|
||||||
|
|
||||||
if(query) {
|
if(query) {
|
||||||
|
// _.each(_.keys(query), function(key) {
|
||||||
|
// if(_.isObject(query[key])) dbQuery[key] = query[key];
|
||||||
|
// else if(_.isNumber(query[key])) dbQuery[key] = query[key];
|
||||||
|
// else dbQuery[key] = {$regex: RegExp.escape(query[key]), $options: 'i'};
|
||||||
|
// });
|
||||||
|
|
||||||
_.each(_.keys(query), function(key) {
|
_.each(_.keys(query), function(key) {
|
||||||
if(_.isObject(query[key])) dbQuery[key] = query[key];
|
if(_.isObject(query[key])) dbQuery.push({[key]: query[key]});
|
||||||
else if(_.isNumber(query[key])) dbQuery[key] = query[key];
|
else if(_.isNumber(query[key])) dbQuery.push({[key]: query[key]});
|
||||||
else dbQuery[key] = {$regex: RegExp.escape(query[key]), $options: 'i'};
|
else {
|
||||||
})
|
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(!_.isNumber(limit)) limit = 100;
|
if(!_.isNumber(limit)) limit = 100;
|
||||||
|
if(!_.isNumber(skipCount) || skipCount < 0) skipCount = 0;
|
||||||
|
|
||||||
return Meteor.collections.Sales.find(dbQuery, {limit: limit, sort: {date: -1}});
|
dbQuery = dbQuery.length > 0 ? {$and: dbQuery} : {};
|
||||||
|
return Meteor.collections.Sales.find(dbQuery, {limit: limit, sort: {date: -1, createdAt: -1}, skip: skipCount});
|
||||||
});
|
});
|
||||||
|
|
||||||
Meteor.methods({
|
Meteor.methods({
|
||||||
|
getSalesCount: function(query) {
|
||||||
|
//TODO: Validate the query?
|
||||||
|
return Sales.find(query).count();
|
||||||
|
},
|
||||||
insertSale: function(sale) {
|
insertSale: function(sale) {
|
||||||
//TODO: Check the structure of sale. Use: check(sale, {name: String, ...});
|
//TODO: Check the structure of sale. Use: check(sale, {name: String, ...});
|
||||||
sale.createdAt = new Date();
|
sale.createdAt = new Date();
|
||||||
|
|||||||
@@ -8,20 +8,6 @@ pri.route('/', {
|
|||||||
triggersEnter: [function(context, redirect) {redirect("/sales");}]
|
triggersEnter: [function(context, redirect) {redirect("/sales");}]
|
||||||
});
|
});
|
||||||
|
|
||||||
pri.route('/menu', {
|
|
||||||
name: 'Menu',
|
|
||||||
action: function(params, queryParams) {
|
|
||||||
require("/imports/ui/Menu.js");
|
|
||||||
BlazeLayout.render('Body', {content: 'Menu'});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
pri.route('/admin', {
|
|
||||||
name: 'UserManager',
|
|
||||||
action: function(params, queryParams) {
|
|
||||||
require("/imports/ui/UserManager.js");
|
|
||||||
BlazeLayout.render('Body', {content: 'UserManager'});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
pri.route('/measures', {
|
pri.route('/measures', {
|
||||||
name: 'Measures',
|
name: 'Measures',
|
||||||
action: function(params, queryParams) {
|
action: function(params, queryParams) {
|
||||||
@@ -43,13 +29,6 @@ pri.route('/productTags', {
|
|||||||
BlazeLayout.render('Body', {content: 'ProductTags'});
|
BlazeLayout.render('Body', {content: 'ProductTags'});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// pri.route('/subcategories', {
|
|
||||||
// name: 'Items',
|
|
||||||
// action: function(params, queryParams) {
|
|
||||||
// require("/imports/ui/Subcategories.js");
|
|
||||||
// BlazeLayout.render('Body', {content: 'Subcategories'});
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
pri.route('/userManagement', {
|
pri.route('/userManagement', {
|
||||||
name: 'UserManagement',
|
name: 'UserManagement',
|
||||||
action: function(params, queryParams) {
|
action: function(params, queryParams) {
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
<template name="Intro">
|
|
||||||
<div id="intro">Intro</div>
|
|
||||||
</template>
|
|
||||||
4
imports/ui/Intro.import.styl
vendored
4
imports/ui/Intro.import.styl
vendored
@@ -1,4 +0,0 @@
|
|||||||
#intro
|
|
||||||
text-align: center
|
|
||||||
font-size: 4em
|
|
||||||
font-family: sans-serif
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
import { Template } from 'meteor/templating';
|
|
||||||
import './Intro.html';
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
<template name="Menu">
|
|
||||||
<div id="menu">
|
|
||||||
<a class="option" href="/sales">
|
|
||||||
<i class="fa fa-usd"></i>
|
|
||||||
<p>Sales</p>
|
|
||||||
</a>
|
|
||||||
<a class="option" href="/prices">
|
|
||||||
<i class="fa fa-usd"></i>
|
|
||||||
<p>Prices</p>
|
|
||||||
</a>
|
|
||||||
<a class="option" href="/items">
|
|
||||||
<i class="fa fa-sitemap"></i>
|
|
||||||
<p>Items</p>
|
|
||||||
</a>
|
|
||||||
<a class="option" href="/configMenu">
|
|
||||||
<i class="fa fa-cog"></i>
|
|
||||||
<p>Settings</p>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
56
imports/ui/Menu.import.styl
vendored
56
imports/ui/Menu.import.styl
vendored
@@ -1,56 +0,0 @@
|
|||||||
#menu {
|
|
||||||
flex: 0 0 100%;
|
|
||||||
display: -webkit-box;
|
|
||||||
display: -moz-box;
|
|
||||||
display: -ms-flexbox;
|
|
||||||
display: -moz-flex;
|
|
||||||
display: -webkit-flex;
|
|
||||||
display: flex;
|
|
||||||
flex-flow: row wrap;
|
|
||||||
justify-content: center; //Spacing between items along the primary axis. (vertical spacing for a column layout)
|
|
||||||
align-items: flex-start; //Align the items within a line along the primary axis. (horizontal alignment for a column layout)
|
|
||||||
align-content: flex-start; //Spacing between lines along the secondary axis. (spacing between columns for a column layout)
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.option {
|
|
||||||
height: 120px;
|
|
||||||
width: 120px;
|
|
||||||
background: grey;
|
|
||||||
margin: 20px;
|
|
||||||
overflow: hidden;
|
|
||||||
color: white;
|
|
||||||
//Flex element options.
|
|
||||||
flex: 0 0 120px; //Grow, Shrink, Basis
|
|
||||||
//Flex container options.
|
|
||||||
flex-flow: column nowrap;
|
|
||||||
justify-content: space-around; //Spacing between items along the primary axis. (vertical spacing for a column layout)
|
|
||||||
align-items: center; //Align the items 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-decoration: none;
|
|
||||||
|
|
||||||
i {
|
|
||||||
flex: 0 0;
|
|
||||||
font-size: 8em;
|
|
||||||
}
|
|
||||||
p {
|
|
||||||
flex: 0 0;
|
|
||||||
font-size: 1.5em;
|
|
||||||
text-align: center;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.option:hover {
|
|
||||||
-moz-box-shadow: inset 0 0 20px #7a5a7a;
|
|
||||||
-webkit-box-shadow: inset 0 0 20px #7a5a7a;
|
|
||||||
box-shadow: inset 0 0 20px #7a5a7a;
|
|
||||||
}
|
|
||||||
.option:active {
|
|
||||||
background: #CCC;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
import { Template } from 'meteor/templating';
|
|
||||||
import './Menu.html';
|
|
||||||
@@ -1,23 +1,7 @@
|
|||||||
<template name="Pricing">
|
<template name="Pricing">
|
||||||
<div id="pricing">
|
<div id="pricing">
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<div class="controlGroup floatRight">
|
<div class="measureGroup" style="vertical-align: bottom">
|
||||||
<label class='controlLabel'>New Price: </label>
|
|
||||||
<input type="number" class="price" name="price" min="0" data-schema-key='currency' value="{{price}}" required>
|
|
||||||
<input type="button" class="btn btn-success applyButton" value="Apply">
|
|
||||||
<!--<span class="toggleUpdateHistory toggleButton clickable">Set Prev</span>-->
|
|
||||||
<div class="controlGroup outline">
|
|
||||||
<span class="controlLabel">Set Previous:</span>
|
|
||||||
<div class="toggleUpdateHistory checkbox checkbox-slider--b-flat">
|
|
||||||
<label>
|
|
||||||
<input type="checkbox" name="setPrevious" checked><span></span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<label class='controlLabel'>Effective: </label>
|
|
||||||
<input type="date" class="form-control" name="date" data-schema-key='date' required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="controlGroup outline floatLeft" style="position: relative; top: 12px">
|
|
||||||
<label class='controlLabel'>Selected Measure: </label>
|
<label class='controlLabel'>Selected Measure: </label>
|
||||||
<select name="measures">
|
<select name="measures">
|
||||||
{{#each measures}}
|
{{#each measures}}
|
||||||
@@ -25,8 +9,31 @@
|
|||||||
{{/each}}
|
{{/each}}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="controlGroup" style="text-align: center">
|
||||||
|
<label class='controlLabel'>New Price: </label>
|
||||||
|
<input type="number" class="price" name="price" min="0" data-schema-key='currency' value="{{price}}" required>
|
||||||
|
<input type="button" class="btn btn-success applyButton" title="Applies the price to selected products." value="Apply">
|
||||||
|
<input type="button" class="btn btn-danger resetButton" title="Resets this form." value="Reset">
|
||||||
|
<br/>
|
||||||
|
<!--<span class="toggleUpdateHistory toggleButton clickable">Set Prev</span>-->
|
||||||
|
<div class="previousSettings outline">
|
||||||
|
<span class="controlLabel">Set Previous:</span>
|
||||||
|
<div class="toggleUpdateHistory checkbox checkbox-slider--b-flat">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" name="setPrevious" checked><span></span>
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<table>
|
<label class='controlLabel' style="margin-left: 10px">Effective: </label>
|
||||||
|
<input type="date" class="form-control" name="date" data-schema-key='date' required>
|
||||||
|
</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 class="tableContainer">
|
||||||
|
<table class="table table-striped table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="name">Name</th>
|
<th class="name">Name</th>
|
||||||
@@ -42,13 +49,14 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template name="PricingForProduct">
|
<template name="PricingForProduct">
|
||||||
<tr class="clickable noselect">
|
<tr class="clickable noselect {{rowClass}}">
|
||||||
<td>{{name}}</td>
|
<td class="tdLarge noselect nonclickable left">{{name}}</td>
|
||||||
<td>{{currentPrice}}</td>
|
<td class="tdLarge noselect nonclickable left">{{currentPrice}}</td>
|
||||||
<td>{{priceChangeDate}}</td>
|
<td class="tdLarge noselect nonclickable left">{{priceChangeDate}}</td>
|
||||||
<td>{{previousPrice}}</td>
|
<td class="tdLarge noselect nonclickable left">{{previousPrice}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
88
imports/ui/Pricing.import.styl
vendored
88
imports/ui/Pricing.import.styl
vendored
@@ -1,11 +1,29 @@
|
|||||||
#pricing
|
#pricing
|
||||||
margin: 10px 20px
|
margin: 20px 20px
|
||||||
height: 100%
|
height: 100%
|
||||||
|
text-align: left
|
||||||
|
|
||||||
.controls
|
.controls
|
||||||
text-align: left
|
text-align: left
|
||||||
|
display: table
|
||||||
|
width: 100%
|
||||||
|
|
||||||
|
.measureGroup
|
||||||
|
padding: 4px 8px
|
||||||
|
margin: 4px 8px
|
||||||
|
display: table-cell
|
||||||
|
width: 240px
|
||||||
|
select
|
||||||
|
width: 100%
|
||||||
.controlGroup
|
.controlGroup
|
||||||
|
padding: 4px 8px
|
||||||
|
margin: 4px 8px
|
||||||
|
display: table-cell
|
||||||
|
.pagination
|
||||||
|
display: table-cell
|
||||||
|
width: 240px
|
||||||
|
vertical-align: bottom
|
||||||
|
.previousSettings
|
||||||
padding: 4px 8px
|
padding: 4px 8px
|
||||||
margin: 4px 8px
|
margin: 4px 8px
|
||||||
display: inline-block
|
display: inline-block
|
||||||
@@ -17,8 +35,9 @@
|
|||||||
.floatRight
|
.floatRight
|
||||||
float: right
|
float: right
|
||||||
.controlLabel
|
.controlLabel
|
||||||
font-size: 1.5em
|
font-size: .9em
|
||||||
font-weight: 700
|
font-weight: 700
|
||||||
|
margin-top: -2px
|
||||||
select[name="measures"]
|
select[name="measures"]
|
||||||
padding: 4px 8px
|
padding: 4px 8px
|
||||||
font-size: 1.5em
|
font-size: 1.5em
|
||||||
@@ -30,66 +49,37 @@
|
|||||||
input[type="button"]
|
input[type="button"]
|
||||||
margin-top: -6px
|
margin-top: -6px
|
||||||
margin-right: 20px
|
margin-right: 20px
|
||||||
//.toggleButton
|
|
||||||
// padding: 6px 8px
|
|
||||||
// border: 1px solid #4cae4c
|
|
||||||
// border-radius: 4px
|
|
||||||
// font-size: 1.5em
|
|
||||||
// color: white
|
|
||||||
// background: #5b5
|
|
||||||
// font-family: inherit
|
|
||||||
//.toggleButton.inactive
|
|
||||||
// background: #FF6F77
|
|
||||||
// color: 888
|
|
||||||
.toggleUpdateHistory
|
.toggleUpdateHistory
|
||||||
margin: 0
|
margin: 0
|
||||||
position: relative
|
position: relative
|
||||||
top: -4px
|
top: -4px
|
||||||
display: inline-block
|
display: inline-block
|
||||||
//.inactive
|
|
||||||
// background: #666
|
|
||||||
input[type="date"]
|
input[type="date"]
|
||||||
width: 180px
|
width: 180px
|
||||||
display: inline-block
|
display: inline-block
|
||||||
table
|
.resetButton
|
||||||
|
margin-left: 20px
|
||||||
|
|
||||||
|
.tableContainer
|
||||||
width: 100%
|
width: 100%
|
||||||
margin-bottom: 20px
|
margin-bottom: 20px
|
||||||
border: 0
|
border: 0
|
||||||
|
font-size: 12.5px
|
||||||
|
table
|
||||||
table-layout: fixed
|
table-layout: fixed
|
||||||
font-size: 1.3em
|
width: 100%
|
||||||
|
> thead
|
||||||
thead
|
> tr
|
||||||
font-weight: 800
|
> th.name
|
||||||
tr > th
|
|
||||||
background: #333
|
|
||||||
color: white
|
|
||||||
|
|
||||||
tr > th.name
|
|
||||||
width: auto
|
width: auto
|
||||||
tr > th.current
|
> th.current
|
||||||
width: 200px
|
width: 200px
|
||||||
tr > th.previous
|
> th.previous
|
||||||
width: 200px
|
width: 200px
|
||||||
tr > th.changeDate
|
> th.changeDate
|
||||||
width: 200px
|
width: 200px
|
||||||
|
> tbody
|
||||||
tbody
|
> tr.deactivated
|
||||||
text-align: left
|
background-color: #fac0d1
|
||||||
|
> tr.deactivated:hover
|
||||||
tr:nth-child(even)
|
background-color: #ffcadb
|
||||||
background: #DDD
|
|
||||||
|
|
||||||
.rowGroupHead
|
|
||||||
color: white
|
|
||||||
background: #333
|
|
||||||
tr.selected
|
|
||||||
//background: yellow
|
|
||||||
background-attachment: fixed
|
|
||||||
background-repeat: no-repeat
|
|
||||||
background-position: 0 0
|
|
||||||
background-image: linear-gradient(to left, #FCF8D1 70%,#f1da36 100%)
|
|
||||||
tr:nth-child(even).selected
|
|
||||||
background-attachment: fixed
|
|
||||||
background-repeat: no-repeat
|
|
||||||
background-position: 0 0
|
|
||||||
background-image: linear-gradient(to left, #E0DCBA 70%,#f1da36 100%)
|
|
||||||
@@ -1,13 +1,26 @@
|
|||||||
|
|
||||||
import './Pricing.html';
|
import './Pricing.html';
|
||||||
|
|
||||||
Tracker.autorun(function() {
|
let QUERY_LIMIT = 20;
|
||||||
|
let PREFIX = "Pricing.";
|
||||||
|
|
||||||
Meteor.subscribe("products");
|
Meteor.subscribe("products");
|
||||||
Meteor.subscribe("measures");
|
let measuresSubscription = Meteor.subscribe("measures");
|
||||||
|
Tracker.autorun(function() {
|
||||||
|
let ready = measuresSubscription.ready();
|
||||||
|
|
||||||
|
if(ready) {
|
||||||
|
console.log("setting selected measure session var");
|
||||||
|
let firstMeasure = Meteor.collections.Measures.findOne({}, {sort: {order: 1}, fields: {_id: 1}});
|
||||||
|
Session.set(PREFIX + "selectedMeasure", firstMeasure._id);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Template.Pricing.onCreated(function() {
|
||||||
|
});
|
||||||
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()
|
||||||
});
|
});
|
||||||
Template.Pricing.helpers({
|
Template.Pricing.helpers({
|
||||||
measures: function() {
|
measures: function() {
|
||||||
@@ -22,23 +35,42 @@ Template.Pricing.helpers({
|
|||||||
return measures;
|
return measures;
|
||||||
},
|
},
|
||||||
product: function() {
|
product: function() {
|
||||||
let measureId = Session.get("selectedMeasure");
|
let skipCount = Session.get(PREFIX + 'skipCount') || 0;
|
||||||
|
let measureId = Session.get(PREFIX + "selectedMeasure");
|
||||||
|
let dbQuery = {measures: {$all: [measureId]}, $or: [{hidden: false}, {hidden: {$exists:false}}]};
|
||||||
|
|
||||||
return Meteor.collections.Products.find({measures: {$all: [measureId]}}, {sort: {name: 1}});
|
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}});
|
||||||
|
},
|
||||||
|
disablePrev: function() {
|
||||||
|
return (Session.get(PREFIX + 'skipCount') || 0) == 0;
|
||||||
|
},
|
||||||
|
disableNext: function() {
|
||||||
|
return Session.get(PREFIX + 'productCount') - (Session.get(PREFIX + 'skipCount') || 0) - QUERY_LIMIT <= 0;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Template.Pricing.events({
|
Template.Pricing.events({
|
||||||
'change select[name="measures"]': function(event, template) {
|
'change select[name="measures"]': function(event, template) {
|
||||||
Session.set("selectedMeasure", $(event.target).val());
|
Session.get(PREFIX + 'skipCount', 0);
|
||||||
|
Session.set(PREFIX + "selectedMeasure", $(event.target).val());
|
||||||
},
|
},
|
||||||
'click .applyButton': function(event, template) {
|
'click .applyButton': function(event, template) {
|
||||||
let measureId = Session.get("selectedMeasure");
|
let measureId = template.$('select[name="measures"]').val();
|
||||||
let $selectedRows = template.$('tr.selected');
|
let $selectedRows = template.$('tr.selected');
|
||||||
// let selectedProducts = $selectedRows.map(function() {return $(this).data('product')});
|
|
||||||
let price = Number(template.$('input[name="price"]').val());
|
let price = Number(template.$('input[name="price"]').val());
|
||||||
let setPrevious = template.$('input[name="setPrevious"]').prop('checked');
|
let setPrevious = template.$('input[name="setPrevious"]').prop('checked');
|
||||||
let date = template.$('input[name="date"]').val();
|
let date = template.$('input[name="date"]').val();
|
||||||
|
let productIds = [];
|
||||||
|
|
||||||
|
for(let i = 0; i < $selectedRows.length; i++) {
|
||||||
|
let product = $($selectedRows[i]).data('product');
|
||||||
|
productIds.push(product._id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!price) {
|
||||||
|
Meteor.call("clearProductPrice", productIds, measureId)
|
||||||
|
}
|
||||||
|
else {
|
||||||
date = moment(date ? date : new Date().toDateInputValue(), "YYYY-MM-DD").toDate();
|
date = moment(date ? date : new Date().toDateInputValue(), "YYYY-MM-DD").toDate();
|
||||||
setPrevious = setPrevious == true || setPrevious == 'on' || setPrevious == "true" || setPrevious == "yes";
|
setPrevious = setPrevious == true || setPrevious == 'on' || setPrevious == "true" || setPrevious == "yes";
|
||||||
|
|
||||||
@@ -50,38 +82,48 @@ Template.Pricing.events({
|
|||||||
sAlert.error("Unexpected input.");
|
sAlert.error("Unexpected input.");
|
||||||
}
|
}
|
||||||
|
|
||||||
for(let i = 0; i < $selectedRows.length; i++) {
|
Meteor.call("setProductPrice", productIds, measureId, price, setPrevious, date);
|
||||||
let product = $($selectedRows[i]).data('product');
|
|
||||||
|
|
||||||
Meteor.call("setProductPrice", product._id, measureId, price, setPrevious, date);
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
'click .resetButton': function(event, template) {
|
||||||
|
template.$('input.price').val(0);
|
||||||
|
template.$('input.date').val(new Date().toDateInputValue());
|
||||||
|
template.$('input[name="setPrevious"]').removeProp('checked');
|
||||||
|
},
|
||||||
|
'click .prevProducts': function(event, template) {
|
||||||
|
if(!$(event.target).hasClass('disabled'))
|
||||||
|
Session.set(PREFIX + 'skipCount', Math.max(0, (Session.get(PREFIX + 'skipCount') || 0) - QUERY_LIMIT));
|
||||||
|
},
|
||||||
|
'click .nextProducts': function(event, template) {
|
||||||
|
if(!$(event.target).hasClass('disabled'))
|
||||||
|
Session.set(PREFIX + 'skipCount', (Session.get(PREFIX + 'skipCount') || 0) + QUERY_LIMIT);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Template.PricingForProduct.onCreated(function() {
|
|
||||||
//
|
|
||||||
// });
|
|
||||||
Template.PricingForProduct.onRendered(function() {
|
Template.PricingForProduct.onRendered(function() {
|
||||||
this.$('tr').data("product", this.data);
|
this.$('tr').data("product", this.data);
|
||||||
});
|
});
|
||||||
Template.PricingForProduct.helpers({
|
Template.PricingForProduct.helpers({
|
||||||
currentPrice: function() {
|
currentPrice: function() {
|
||||||
let measureId = Session.get("selectedMeasure");
|
let measureId = Session.get(PREFIX + "selectedMeasure");
|
||||||
let price = this.prices && measureId && this.prices[measureId] && this.prices[measureId].price ? this.prices[measureId].price : undefined;
|
let price = this.prices && measureId && this.prices[measureId] && this.prices[measureId].price ? this.prices[measureId].price : undefined;
|
||||||
|
|
||||||
return price ? price.toLocaleString("en-US", {style: 'currency', currency: 'USD', minimumFractionDigits: 2}) : "-";
|
return price ? price.toLocaleString("en-US", {style: 'currency', currency: 'USD', minimumFractionDigits: 2}) : "-";
|
||||||
},
|
},
|
||||||
previousPrice: function() {
|
previousPrice: function() {
|
||||||
let measureId = Session.get("selectedMeasure");
|
let measureId = Session.get(PREFIX + "selectedMeasure");
|
||||||
let price = this.prices && measureId && this.prices[measureId] && this.prices[measureId].previousPrice ? this.prices[measureId].previousPrice : undefined;
|
let price = this.prices && measureId && this.prices[measureId] && this.prices[measureId].previousPrice ? this.prices[measureId].previousPrice : undefined;
|
||||||
|
|
||||||
return price ? price.toLocaleString("en-US", {style: 'currency', currency: 'USD', minimumFractionDigits: 2}) : "-";
|
return price ? price.toLocaleString("en-US", {style: 'currency', currency: 'USD', minimumFractionDigits: 2}) : "-";
|
||||||
},
|
},
|
||||||
priceChangeDate: function() {
|
priceChangeDate: function() {
|
||||||
let measureId = Session.get("selectedMeasure");
|
let measureId = Session.get(PREFIX + "selectedMeasure");
|
||||||
let date = this.prices && measureId && this.prices[measureId] && this.prices[measureId].effectiveDate ? this.prices[measureId].effectiveDate : undefined;
|
let date = this.prices && measureId && this.prices[measureId] && this.prices[measureId].effectiveDate ? this.prices[measureId].effectiveDate : undefined;
|
||||||
|
|
||||||
return date ? moment(date).format("MM/DD/YYYY (w)") : "-";
|
return date ? moment(date).format("MM/DD/YYYY (w)") : "-";
|
||||||
|
},
|
||||||
|
rowClass: function() {
|
||||||
|
return this.deactivated ? "deactivated" : "";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Template.PricingForProduct.events({
|
Template.PricingForProduct.events({
|
||||||
|
|||||||
@@ -1,24 +1,42 @@
|
|||||||
<template name="ProductTags">
|
<template name="ProductTags">
|
||||||
<div id="productTags">
|
<div id="productTags">
|
||||||
{{#if Template.subscriptionsReady}}
|
{{#if Template.subscriptionsReady}}
|
||||||
<div class="insert">
|
<div class="tagInfo">
|
||||||
{{>ProductTagInsert}}
|
<div class="floatRight">
|
||||||
|
<label class="switch">
|
||||||
|
<input class="editTagsSwitchCheckbox" type="checkbox">
|
||||||
|
<div class="slider round"></div>
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid">
|
|
||||||
<table class="dataTable table table-striped table-hover">
|
<div class="tagControls">
|
||||||
|
<label class='control-label'>Name</label>
|
||||||
|
<input name="tagName" type="text" class="form-control" required>
|
||||||
|
<input name="addTag" type="button" class="btn btn-success" value="+">
|
||||||
|
</div>
|
||||||
|
<div class="tableTop">
|
||||||
|
<span class="tagDisplay">
|
||||||
|
{{#each productTagsByUse}}
|
||||||
|
{{> ProductTag}}
|
||||||
|
{{/each}}
|
||||||
|
</span>
|
||||||
|
<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="tableContainer">
|
||||||
|
<table class="table table-striped table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="headers">
|
<tr>
|
||||||
<th class="tdLarge noselect nonclickable" style="max-width: 300px">Name</th>
|
<th class="name">Name {{>ProductTag_ProductSearch columnName='name'}}</th>
|
||||||
<th class="tdLarge noselect nonclickable" style="width: 90px">Actions</th>
|
<th class="tags">Tags {{>ProductTag_ProductSearch columnName='tags' collectionQueryColumnName='name' collection='ProductTags' collectionResultColumnName='_id'}}</th>
|
||||||
</tr>
|
|
||||||
<tr class="footers">
|
|
||||||
<th>{{>ProductTagSearch columnName='name'}}</th>
|
|
||||||
<th></th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{{#each productTags}}
|
{{#each products}}
|
||||||
{{> ProductTag}}
|
{{> ProductTag_Product}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@@ -29,38 +47,18 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template name="ProductTag">
|
<template name="ProductTag">
|
||||||
<tr>
|
<span class="productTagExp" style="{{tagcolor}}"><span class="productTagName">{{name}}</span><input class="productTagEditor" style="display: none" type="text" value={{name}}></span>
|
||||||
{{#if editing}}
|
</template>
|
||||||
<td><input name="name" class="form-control" type="text" value="{{name}}" required></td>
|
|
||||||
<td class="center tdLarge"><i class="editorCancel fa fa-times-circle fa-lg noselect clickable" aria-hidden="true"></i> / <i class="editorApply fa fa-check-square-o fa-lg noselect clickable" aria-hidden="true"></i></td>
|
<template name="ProductTag_Product">
|
||||||
{{else}}
|
<tr class="{{rowClass}}">
|
||||||
<td class="tdLarge noselect nonclickable">{{name}}</td>
|
<td class="tdLarge noselect nonclickable left">{{name}}</td>
|
||||||
<td class="center tdLarge"><i class="tagRemove fa fa-times-circle fa-lg noselect clickable" aria-hidden="true"></i> / <i class="tagEdit fa fa-pencil-square-o fa-lg noselect clickable" aria-hidden="true"></i></td>
|
<td class="tdLarge noselect nonclickable left">{{tags}}</td>
|
||||||
{{/if}}
|
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template name="ProductTagSearch">
|
<template name="ProductTag_ProductSearch">
|
||||||
<div class="">
|
<div class="">
|
||||||
<input type="text" class="searchInput" placeholder="Filter..." value="{{searchValue}}"/>
|
<input type="text" class="searchInput" placeholder="Filter..." value="{{searchValue}}"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template name="ProductTagInsert">
|
|
||||||
<form name="insert" autocomplete="off">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-3 col-sm-0"></div>
|
|
||||||
<div class="col-md-6 col-sm-12">
|
|
||||||
<div class="formGroupHeading">New Product Tag</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label class='control-label'>Name</label>
|
|
||||||
<input name="username" type="text" class="form-control" required>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<input type="submit" class="btn btn-success" value="Create">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3 col-sm-0"></div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</template>
|
|
||||||
168
imports/ui/ProductTags.import.styl
vendored
168
imports/ui/ProductTags.import.styl
vendored
@@ -1,67 +1,131 @@
|
|||||||
#productTags
|
#productTags
|
||||||
margin: 20px 20px
|
margin: 20px 20px
|
||||||
height: 100%
|
height: 100%
|
||||||
//Flex container options.
|
|
||||||
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
|
||||||
|
|
||||||
.editor
|
.tagInfo
|
||||||
height: 100%
|
display: block
|
||||||
overflow-y: auto
|
margin-bottom: 20px
|
||||||
|
|
||||||
.insert
|
.tagControls
|
||||||
flex: none
|
display: block
|
||||||
width: 100%
|
width: 100%
|
||||||
|
label
|
||||||
.col-md-6
|
display: inline-block
|
||||||
padding: 10px 30px 0 30px
|
input[name="tagName"]
|
||||||
background: #EFEFEF
|
width: 140px;
|
||||||
border-radius: 1em
|
display: inline-block
|
||||||
|
input[name="addTag"]
|
||||||
.formGroupHeading
|
margin-top: -4px
|
||||||
font-size: 1.6em
|
.floatRight
|
||||||
|
float: right
|
||||||
|
.editTags
|
||||||
|
font-size: 2em
|
||||||
|
border: 1px solid #999
|
||||||
|
background: #f7f3a0
|
||||||
|
border-radius: 4px
|
||||||
|
padding: 2px 3px
|
||||||
|
.switch
|
||||||
|
position: relative
|
||||||
|
display: inline-block
|
||||||
|
width: 60px
|
||||||
|
height: 34px
|
||||||
|
/* Hide default HTML checkbox */
|
||||||
|
input
|
||||||
|
display:none
|
||||||
|
/* The slider */
|
||||||
|
.slider
|
||||||
|
position: absolute
|
||||||
|
cursor: pointer
|
||||||
|
top: 0
|
||||||
|
left: 0
|
||||||
|
right: 0
|
||||||
|
bottom: 0
|
||||||
|
background-color: #ccc
|
||||||
|
-webkit-transition: .4s
|
||||||
|
transition: .4s
|
||||||
|
.slider:before
|
||||||
|
position: absolute
|
||||||
|
font-family: FontAwesome
|
||||||
|
padding-left: 4px
|
||||||
|
font-size: 20px
|
||||||
|
line-height: 26px
|
||||||
|
color: #ffa398
|
||||||
|
content: "\f040"
|
||||||
|
height: 26px
|
||||||
|
width: 26px
|
||||||
|
left: 4px
|
||||||
|
bottom: 4px
|
||||||
|
background-color: white
|
||||||
|
-webkit-transition: .4s
|
||||||
|
transition: .4s
|
||||||
|
input:checked + .slider
|
||||||
|
background-color: #5cb85c
|
||||||
|
input:focus + .slider
|
||||||
|
box-shadow: 0 0 1px #2196F3
|
||||||
|
input:checked + .slider:before
|
||||||
|
-webkit-transform: translateX(26px);
|
||||||
|
-ms-transform: translateX(26px);
|
||||||
|
transform: translateX(26px);
|
||||||
|
/* Rounded sliders */
|
||||||
|
.slider.round
|
||||||
|
border-radius: 34px
|
||||||
|
.slider.round:before
|
||||||
|
border-radius: 50%
|
||||||
|
.tableTop
|
||||||
|
display: table
|
||||||
|
width: 100%
|
||||||
|
margin-top: 10px
|
||||||
|
.tagDisplay
|
||||||
|
display: table-cell
|
||||||
|
width: auto
|
||||||
|
.productTagExp
|
||||||
font-family: "Arial Black", "Arial Bold", Gadget, sans-serif
|
font-family: "Arial Black", "Arial Bold", Gadget, sans-serif
|
||||||
font-style: normal
|
font-size: 14px
|
||||||
font-variant: normal
|
line-height: 34px
|
||||||
font-weight: 500
|
margin: 0
|
||||||
|
padding: 4px 14px
|
||||||
.grid
|
border: 1px solid #999
|
||||||
flex: auto
|
border-radius: 4px
|
||||||
align-self: stretch
|
white-space: nowrap
|
||||||
overflow-y: auto
|
cursor: pointer
|
||||||
overflow-x: auto
|
.hidden
|
||||||
|
display: none;
|
||||||
|
.productTagEditor
|
||||||
|
display: inline-block
|
||||||
|
font-size: 1em
|
||||||
|
height: 20px
|
||||||
|
background: transparent
|
||||||
|
border: 0
|
||||||
|
padding: 0
|
||||||
|
margin: 0
|
||||||
|
.productTagName
|
||||||
|
border: 0
|
||||||
|
padding: 0
|
||||||
|
margin: 0
|
||||||
|
.pagination
|
||||||
|
display: table-cell
|
||||||
|
width: 240px
|
||||||
|
vertical-align: bottom;
|
||||||
|
.tableContainer
|
||||||
|
width: 100%
|
||||||
margin-bottom: 20px
|
margin-bottom: 20px
|
||||||
border: 0
|
border: 0
|
||||||
padding-top: 20px
|
font-size: 12.5px
|
||||||
|
table
|
||||||
.table > thead > tr > th
|
|
||||||
border: 0
|
|
||||||
padding-top: 0
|
|
||||||
padding-bottom: 6px
|
|
||||||
|
|
||||||
.dataTable
|
|
||||||
table-layout: fixed
|
table-layout: fixed
|
||||||
|
width: 100%
|
||||||
|
> thead
|
||||||
|
> tr
|
||||||
|
> th.name
|
||||||
width: auto
|
width: auto
|
||||||
|
> th.tags
|
||||||
.tdLarge
|
width: auto
|
||||||
font-size: 1.5em
|
> tbody
|
||||||
.tagRemove
|
> tr.deactivated
|
||||||
color: red
|
background-color: #fac0d1
|
||||||
.tagEdit
|
> tr.deactivated:hover
|
||||||
color: darkblue
|
background-color: #ffcadb
|
||||||
.editorApply
|
|
||||||
color: green
|
|
||||||
.editorCancel
|
|
||||||
color: red
|
|
||||||
td.roles
|
td.roles
|
||||||
.role
|
.role
|
||||||
padding: 4px 4px
|
padding: 4px 4px
|
||||||
|
|||||||
@@ -1,86 +1,228 @@
|
|||||||
|
|
||||||
import './ProductTags.html';
|
import './ProductTags.html';
|
||||||
|
|
||||||
|
let QUERY_LIMIT = 20;
|
||||||
|
let PREFIX = "ProductTags.";
|
||||||
|
|
||||||
Tracker.autorun(function() {
|
Tracker.autorun(function() {
|
||||||
|
Meteor.subscribe("products");
|
||||||
Meteor.subscribe("productTags");
|
Meteor.subscribe("productTags");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Template.ProductTags.onCreated(function() {
|
||||||
|
Session.set(PREFIX + "editTags", false);
|
||||||
|
});
|
||||||
Template.ProductTags.helpers({
|
Template.ProductTags.helpers({
|
||||||
productTags: function() {
|
productTags: function() {
|
||||||
return Meteor.collections.ProductTags.find(Session.get('searchQuery') || {}, {sort: {name: -1}});
|
return Meteor.collections.ProductTags.find(Session.get(PREFIX + 'searchQuery') || {}, {sort: {name: 1}});
|
||||||
|
},
|
||||||
|
productTagsByUse: function() {
|
||||||
|
let productTags = Meteor.collections.ProductTags.find({}, {sort: {name: 1}}).fetch();
|
||||||
|
let totalCount = Meteor.collections.Products.find({}).count();
|
||||||
|
|
||||||
|
for(let tag of productTags) {
|
||||||
|
tag.useRatio = totalCount > 0 ? Meteor.collections.Products.find({tags: {$all: [tag._id]}}).count() / totalCount : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Turned off sorting by use count since it caused re-ordering problems when applying tags to products.
|
||||||
|
//productTags.sort(function(a, b) {
|
||||||
|
// return b.useRatio - a.useRatio;
|
||||||
|
//});
|
||||||
|
|
||||||
|
return productTags;
|
||||||
|
},
|
||||||
|
products: function() {
|
||||||
|
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'}});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//Don't show hidden products.
|
||||||
|
dbQuery.push({$or: [{hidden: false}, {hidden: {$exists:false}}]});
|
||||||
|
//Join the query pieces together with an $and
|
||||||
|
dbQuery = dbQuery.length > 1 ? {$and: dbQuery} : dbQuery[0];
|
||||||
|
//Collect a count of the products first, and store it in the session.
|
||||||
|
Session.set(PREFIX + 'productCount', Meteor.collections.Products.find(dbQuery).count()); //Always get a full count.
|
||||||
|
|
||||||
|
return Meteor.collections.Products.find(dbQuery, {limit: QUERY_LIMIT, skip: skipCount, sort: {name: 1}});
|
||||||
|
},
|
||||||
|
disablePrev: function() {
|
||||||
|
return (Session.get(PREFIX + 'skipCount') || 0) == 0;
|
||||||
|
},
|
||||||
|
disableNext: function() {
|
||||||
|
return Session.get(PREFIX + 'productCount') - (Session.get(PREFIX + 'skipCount') || 0) - QUERY_LIMIT <= 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Template.ProductTags.events({
|
||||||
|
'change .editTagsSwitchCheckbox': function(event, template) {
|
||||||
|
Session.set(PREFIX + "editTags", $(event.target).is(":checked"));
|
||||||
|
},
|
||||||
|
'click input[name="addTag"]': function(event, template) {
|
||||||
|
let $tagName = template.$('input[name="tagName"]');
|
||||||
|
let name = $tagName.val();
|
||||||
|
|
||||||
|
Meteor.call('insertProductTag', name, function(error) {
|
||||||
|
if(error) sAlert.error(error);
|
||||||
|
else {
|
||||||
|
sAlert.success("Tag Created");
|
||||||
|
$tagName.val("");
|
||||||
|
$tagName.focus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'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);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.ProductTag.onCreated(function() {
|
Template.ProductTag.onCreated(function() {
|
||||||
this.edited = new ReactiveVar();
|
//this.showEditorVar = new ReactiveVar(false);
|
||||||
});
|
|
||||||
Template.ProductTag.events({
|
|
||||||
"click .tagEdit": function(event, template) {
|
|
||||||
template.edited.set(this);
|
|
||||||
},
|
|
||||||
"click .tagRemove": function(event, template) {
|
|
||||||
let _this = this;
|
|
||||||
bootbox.confirm({
|
|
||||||
message: "Delete the product tag?",
|
|
||||||
buttons: {confirm: {label: "Yes", className: 'btn-success'}, cancel: {label: "No", className: "btn-danger"}},
|
|
||||||
callback: function(result) {
|
|
||||||
if(result) {
|
|
||||||
Meteor.call('deleteProductTag', _this._id, function(error, result) {
|
|
||||||
if(error) {
|
|
||||||
sAlert.error(error);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sAlert.success("Product tag removed.");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
"click .editorCancel": function(event, template) {
|
|
||||||
template.edited.set(undefined);
|
|
||||||
},
|
|
||||||
"click .editorApply": function(event, template) {
|
|
||||||
let name = template.$("input[name='name']").val().trim();
|
|
||||||
|
|
||||||
//Basic validation.
|
|
||||||
if(name) {
|
|
||||||
Meteor.call("updateProductTag", {_id: this._id, name: name}, function(error, result) {
|
|
||||||
if(error) {
|
|
||||||
sAlert.error(error);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sAlert.success("Product tag updated.");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
template.edited.set(undefined);
|
|
||||||
},
|
|
||||||
"click .role": function(event, template) {
|
|
||||||
$(event.target).toggleClass("selected");
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
Template.ProductTag.helpers({
|
Template.ProductTag.helpers({
|
||||||
editing: function() {
|
// tagsize: function() {
|
||||||
return Template.instance().edited.get() == this;
|
// return ((2 * this.useRatio) + 1) + "em";
|
||||||
|
// },
|
||||||
|
// showEditor: function() {
|
||||||
|
// return Template.instance().showEditorVar.get();
|
||||||
|
// },
|
||||||
|
tagcolor: function() {
|
||||||
|
let color = "rgba(" + (Math.round(155 * this.useRatio) + 100) + ",80," + (Math.round(155 * (1-this.useRatio)) + 100) + ", 1)";
|
||||||
|
|
||||||
|
return "-webkit-box-shadow: inset 0px 0px 6px 1px " + color + "; -moz-box-shadow: inset 0px 0px 6px 1px " + color + "; box-shadow: inset 0px 0px 6px 1px " + color + ";";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Template.ProductTag.events({
|
||||||
|
'click .productTagExp': function(event, template) {
|
||||||
|
if(Session.get(PREFIX + "editTags")) {
|
||||||
|
let width = template.$('.productTagName').innerWidth();
|
||||||
|
template.$('.productTagEditor').css('width', width + "px");
|
||||||
|
|
||||||
|
template.$('.productTagName').hide();
|
||||||
|
template.$('.productTagEditor').show();
|
||||||
|
template.$('.productTagEditor').focus();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let tagId = this._id;
|
||||||
|
let $selectedRows = template.parentTemplate(1).$('tr.selected');
|
||||||
|
let productIds = [];
|
||||||
|
|
||||||
|
for(let i = 0; i < $selectedRows.length; i++) {
|
||||||
|
let selectedRow = $selectedRows[i];
|
||||||
|
|
||||||
|
productIds.push($(selectedRow).data('product')._id);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Should either tag or un-tag the products (if any products don't have the tag then add it to all, otherwise remove it).
|
||||||
|
Meteor.call("tagProducts", productIds, tagId);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'blur .productTagEditor': function(event, template) {
|
||||||
|
let name = template.$('.productTagEditor').val();
|
||||||
|
|
||||||
|
template.$('.productTagName').show();
|
||||||
|
template.$('.productTagEditor').hide();
|
||||||
|
|
||||||
|
if(name && name.trim().length > 0) {
|
||||||
|
Meteor.call('updateProductTag', {_id: this._id, name: name.trim()}, function(error) {
|
||||||
|
if(error) sAlert.error(error);
|
||||||
|
else sAlert.success("Tag Updated");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Meteor.call('deleteProductTag', this._id, function(error) {
|
||||||
|
if(error) sAlert.error(error);
|
||||||
|
else sAlert.success("Tag Deleted");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'keydown .productTagEditor': function(event, template) {
|
||||||
|
if(event.which === 13) { //Enter
|
||||||
|
let name = template.$('.productTagEditor').val();
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
template.$('.productTagName').show();
|
||||||
|
template.$('.productTagEditor').hide();
|
||||||
|
|
||||||
|
if(name && name.trim().length > 0) {
|
||||||
|
Meteor.call('updateProductTag', {_id: this._id, name: name.trim()}, function(error) {
|
||||||
|
if(error) sAlert.error(error);
|
||||||
|
else sAlert.success("Tag Updated");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Meteor.call('deleteProductTag', this._id, function(error) {
|
||||||
|
if(error) sAlert.error(error);
|
||||||
|
else sAlert.success("Tag Deleted");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(event.which === 27) { //ESC
|
||||||
|
event.preventDefault();
|
||||||
|
template.$('.productTagEditor').val(this.name);
|
||||||
|
template.$('.productTagName').show();
|
||||||
|
template.$('.productTagEditor').hide();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.ProductTagSearch.events({
|
Template.ProductTag_ProductSearch.events({
|
||||||
"keyup .searchInput": _.throttle(function(event, template) {
|
"keyup .searchInput": _.throttle(function(event, template) {
|
||||||
let searchQuery = Session.get('searchQuery') || {};
|
let searchQuery = Session.get(PREFIX + 'searchQuery') || {};
|
||||||
let searchFields = Session.get('searchFields') || {};
|
let searchFields = Session.get(PREFIX + 'searchFields') || {}; //searchFields allows the view to retain the search values in the inputs across page refreshes.
|
||||||
let searchValue = template.$('.searchInput').val();
|
let searchValue = template.$('.searchInput').val();
|
||||||
|
|
||||||
if(searchValue) {
|
if(searchValue) {
|
||||||
if(this.number) searchValue = parseFloat(searchValue);
|
if(this.number) searchValue = parseFloat(searchValue);
|
||||||
|
|
||||||
if(this.collection) {
|
if(this.collection) {
|
||||||
let ids = Meteor.collections[this.collection].find({[this.collectionQueryColumnName]: {$regex: searchValue, $options: 'i'}}, {fields: {[this.collectionResultColumnName]: 1}}).fetch();
|
let ids = [];
|
||||||
|
//Split the search by the spaces. Each word will be a separate search which must being a word in the matches.
|
||||||
|
let searches = searchValue && searchValue.length > 0 ? searchValue.split(/\s+/) : undefined;
|
||||||
|
let regexs = searches ? [] : undefined;
|
||||||
|
|
||||||
|
if(searches) {
|
||||||
|
for(let search of searches) {
|
||||||
|
regexs.push(new RegExp("\\b" + search));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// let results = Meteor.collections[this.collection].find({[this.collectionQueryColumnName]: {$regex: searchValue, $options: 'i'}}, {fields: {[this.collectionResultColumnName]: 1}}).fetch();
|
||||||
|
//
|
||||||
|
// for(let result of results) {
|
||||||
|
// ids.push(result._id);
|
||||||
|
// }
|
||||||
|
|
||||||
|
for(let regex of regexs) {
|
||||||
|
let results = Meteor.collections[this.collection].find({[this.collectionQueryColumnName]: {$regex: searchValue, $options: 'i'}}, {fields: {[this.collectionResultColumnName]: 1}}).fetch();
|
||||||
|
|
||||||
|
for(let result of results) {
|
||||||
|
ids.push(result._id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Convert the ids to an array of ids instead of an array of objects containing an id.
|
//Convert the ids to an array of ids instead of an array of objects containing an id.
|
||||||
for(let i = 0; i < ids.length; i++) {ids[i] = ids[i]._id;}
|
//for(let i = 0; i < ids.length; i++) {ids[i] = ids[i]._id;}
|
||||||
searchQuery[this.columnName] = {$in: ids};
|
searchQuery[this.columnName] = {$in: ids};
|
||||||
searchFields[this.columnName] = searchValue;
|
searchFields[this.columnName] = searchValue;
|
||||||
}
|
}
|
||||||
@@ -94,39 +236,92 @@ Template.ProductTagSearch.events({
|
|||||||
delete searchFields[this.columnName];
|
delete searchFields[this.columnName];
|
||||||
}
|
}
|
||||||
|
|
||||||
Session.set('searchQuery', searchQuery);
|
Session.set(PREFIX + 'searchQuery', searchQuery);
|
||||||
|
Session.set(PREFIX + 'searchFields', searchFields);
|
||||||
}, 500)
|
}, 500)
|
||||||
});
|
});
|
||||||
Template.ProductTagSearch.helpers({
|
Template.ProductTag_ProductSearch.helpers({
|
||||||
searchValue: function() {
|
searchValue: function() {
|
||||||
let searchFields = Session.get('searchFields');
|
let searchFields = Session.get(PREFIX + 'searchFields');
|
||||||
|
|
||||||
return (searchFields && searchFields[this.columnName]) ? searchFields[this.columnName] : '';
|
return (searchFields && searchFields[this.columnName]) ? searchFields[this.columnName] : '';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.ProductTagInsert.onRendered(function() {
|
Template.ProductTag_Product.onRendered(function() {
|
||||||
this.$('form[name="insert"]').validator();
|
this.$('tr').data("product", this.data);
|
||||||
});
|
});
|
||||||
Template.ProductTagInsert.events({
|
Template.ProductTag_Product.helpers({
|
||||||
'click input[type="submit"]': function(event, template) {
|
tags: function() {
|
||||||
event.preventDefault();
|
let result = "";
|
||||||
template.$('form[name="insert"]').data('bs.validator').validate(function(isValid) {
|
|
||||||
if(isValid) {
|
|
||||||
let name = template.$('input[name="name"]').val();
|
|
||||||
|
|
||||||
Meteor.call('insertProductTag', name, function(error, result) {
|
if(this.tags && this.tags.length > 0) {
|
||||||
if(error) {
|
let tagNames = [];
|
||||||
sAlert.error(error);
|
|
||||||
|
for(let i = 0; i < this.tags.length; i++) {
|
||||||
|
let obj = Meteor.collections.ProductTags.findOne(this.tags[i]);
|
||||||
|
|
||||||
|
if(obj && obj.name)
|
||||||
|
tagNames.push(obj.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = tagNames.join(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
name: function() {
|
||||||
|
let result = this.name;
|
||||||
|
|
||||||
|
if(this.aliases && this.aliases.length > 0) {
|
||||||
|
let first = true;
|
||||||
|
|
||||||
|
for(let alias of this.aliases) {
|
||||||
|
if(first) {
|
||||||
|
result += " ['";
|
||||||
|
first = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sAlert.success("Product tag created.");
|
result += "', '";
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
result += alias;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
result += "']";
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
},
|
},
|
||||||
"click .role": function(event, template) {
|
rowClass: function() {
|
||||||
$(event.target).toggleClass("selected");
|
return this.deactivated ? "deactivated" : "";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Template.ProductTag_Product.events({
|
||||||
|
'click tr': function(event, template) {
|
||||||
|
let $row = template.$(event.target).closest("tr");
|
||||||
|
let parentTemplate = template.parentTemplate(1);
|
||||||
|
|
||||||
|
if(event.shiftKey) {
|
||||||
|
let $lastRow = parentTemplate.$lastClickedRow;
|
||||||
|
let $range = ($row.index() > $lastRow.index() ? $lastRow.nextUntil($row) : $row.nextUntil($lastRow)).add($row);
|
||||||
|
|
||||||
|
if(event.ctrlKey) {
|
||||||
|
$range.toggleClass("selected");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$range.addClass("selected");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(event.ctrlKey) {
|
||||||
|
$row.toggleClass("selected");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$row.addClass("selected");
|
||||||
|
$row.siblings().removeClass('selected');
|
||||||
|
}
|
||||||
|
|
||||||
|
//Store the last row clicked on in a non-reactive variable attached to the parent template.
|
||||||
|
parentTemplate.$lastClickedRow = $row;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -1,17 +1,33 @@
|
|||||||
<template name="Products">
|
<template name="Products">
|
||||||
<div id="products">
|
<div id="products">
|
||||||
<div class="grid">
|
<div class="tableControls">
|
||||||
<div class="dataTable">
|
<span class="controlLabel">Show Hidden</span>
|
||||||
|
<div class="toggleShowHidden checkbox checkbox-slider--b-flat">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" name="showHidden"><span></span>
|
||||||
|
</label>
|
||||||
|
</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 class="tableContainer">
|
||||||
<table class="table table-striped table-hover">
|
<table class="table table-striped table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Name {{>ProductSearch columnName='name'}}</th>
|
<th class="name">Name {{>ProductSearch columnName='name'}}</th>
|
||||||
<th>Tags {{>ProductSearch columnName='tags'}}</th>
|
<th class="tags">Tags {{>ProductSearch columnName='tags' collectionQueryColumnName='name' collection='ProductTags' collectionResultColumnName='_id'}}</th>
|
||||||
<th>Aliases {{>ProductSearch columnName='aliases'}}</th>
|
<th class="aliases">Aliases {{>ProductSearch columnName='aliases'}}</th>
|
||||||
<th>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>
|
||||||
</tr>
|
</tr>
|
||||||
|
<!--<button type="button" name="newProductButton"><i class="fa fa-plus-circle" aria-hidden="true"></i></button>-->
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
{{#if displayNewProduct}}
|
||||||
|
{{> ProductEditor isNew=true}}
|
||||||
|
{{/if}}
|
||||||
{{#each products}}
|
{{#each products}}
|
||||||
{{> Product}}
|
{{> Product}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
@@ -19,20 +35,60 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template name="Product">
|
<template name="Product">
|
||||||
<tr>
|
<tr class="{{getRowClass}}">
|
||||||
<td class="tdLarge noselect nonclickable left">{{name}}</td>
|
{{#if editing}}
|
||||||
<td class="tdLarge noselect nonclickable left">{{tags}}</td>
|
{{> ProductEditor}}
|
||||||
<td class="tdLarge noselect nonclickable left">{{aliases}}</td>
|
{{else}}
|
||||||
<td class="tdLarge noselect nonclickable left">{{measures}}</td>
|
<td class="noselect nonclickable left">{{name}}</td>
|
||||||
|
<td class="noselect nonclickable left">{{tags}}</td>
|
||||||
|
<td class="noselect nonclickable left">{{aliases}}</td>
|
||||||
|
<td class="noselect nonclickable left">{{measures}}</td>
|
||||||
|
{{#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>
|
||||||
|
{{else}}
|
||||||
|
{{#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>
|
||||||
|
{{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>
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template name="ProductEditor">
|
||||||
|
<td colspan="4" class="productEditorTd">
|
||||||
|
<div class="editorDiv"><label>Name:</label><input name="name" class="form-control" type="text" value="{{name}}" autocomplete="off" required></div>
|
||||||
|
<div class="editorDiv"><label>Tags:</label>
|
||||||
|
<select class="productTagsEditor" multiple="multiple">
|
||||||
|
{{#each tags}}
|
||||||
|
<option value="{{_id}}" {{tagSelected}}>{{name}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="editorDiv"><label>Aliases:</label>
|
||||||
|
<select class="productAliasesEditor" multiple="multiple">
|
||||||
|
{{#each aliases}}
|
||||||
|
<option value="{{this}}" selected>{{this}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="editorDiv"><label>Measures:</label>
|
||||||
|
<select class="productMeasuresEditor" multiple="multiple">
|
||||||
|
{{#each measures}}
|
||||||
|
<option value="{{_id}}" {{measureSelected}}>{{name}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="center productEditorTd"><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>
|
||||||
|
</template>
|
||||||
|
|
||||||
<template name="ProductSearch">
|
<template name="ProductSearch">
|
||||||
<div class="">
|
<div class="productSearch">
|
||||||
<input type="text" class="searchInput" placeholder="Filter..." value="{{searchValue}}"/>
|
<input type="text" class="searchInput" placeholder="Filter..." value="{{searchValue}}"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
142
imports/ui/Products.import.styl
vendored
142
imports/ui/Products.import.styl
vendored
@@ -1,52 +1,98 @@
|
|||||||
#products
|
#products
|
||||||
height: 100%;
|
margin: 20px 20px
|
||||||
|
height: 100%
|
||||||
|
text-align: left
|
||||||
|
|
||||||
.editor
|
.tableControls
|
||||||
height: 100%;
|
text-align: right
|
||||||
overflow-y: auto;
|
margin-right: 20px
|
||||||
|
.controlLabel
|
||||||
|
font-size: 9px
|
||||||
|
font-weight: 700
|
||||||
|
color: #5a5a5a
|
||||||
|
position: relative
|
||||||
|
top: -2px
|
||||||
|
.toggleShowHidden
|
||||||
|
margin: 0 40px 0 0
|
||||||
|
position: relative
|
||||||
|
top: -4px
|
||||||
|
display: inline-block
|
||||||
|
|
||||||
.grid
|
.tableContainer
|
||||||
height: 100%;
|
width: 100%
|
||||||
//Flex container options.
|
margin-bottom: 20px
|
||||||
flex-flow: column nowrap;
|
border: 0
|
||||||
justify-content: space-around; //Spacing between items along the primary axis. (vertical spacing for a column layout)
|
font-size: 12.5px
|
||||||
align-items: flex-start; //Align the items 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;
|
|
||||||
|
|
||||||
.buttonContainer
|
table
|
||||||
//Flex element options.
|
table-layout: fixed
|
||||||
//flex: 0 0; //Grow, Shrink, Basis
|
width: 100%
|
||||||
flex: none;
|
.productSearch
|
||||||
|
margin: 3px 0 2px 1px
|
||||||
.dataTable
|
.productEditorTd
|
||||||
overflow-y: auto;
|
background: #deeac0
|
||||||
//Flex element options.
|
input[name="name"], .productTagsEditor, .productAliasesEditor, .productMeasuresEditor
|
||||||
flex: auto;
|
width: 100%
|
||||||
align-self: stretch;
|
.editorDiv
|
||||||
height: 10%;
|
margin: 4px 0
|
||||||
max-height: 100%;
|
label
|
||||||
|
font-family: "Arial Black", "Arial Bold", Gadget, sans-serif
|
||||||
.padding
|
font-size: .9em
|
||||||
flex: none;
|
padding-bottom: 4px
|
||||||
height: 1px;
|
select2
|
||||||
width: 100%;
|
font-size: .4em
|
||||||
|
> thead
|
||||||
#DFAliases
|
> tr
|
||||||
width: 100%;
|
> th.name
|
||||||
height: 150px;
|
width: auto
|
||||||
overflow: auto;
|
> th.tags
|
||||||
|
width: 220px
|
||||||
span
|
> th.aliases
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
width: 220px
|
||||||
font-size: 1.5em;
|
> th.measures
|
||||||
cursor: pointer;
|
width: 220px
|
||||||
display: block;
|
> th.actions
|
||||||
|
width: 90px
|
||||||
span.selected
|
text-align: center
|
||||||
background-color: rgba(255, 248, 131, 0.51);
|
.newProductButton
|
||||||
|
margin-top: 4px
|
||||||
|
padding: 0px 12px
|
||||||
|
.fa-plus-circle
|
||||||
|
display: inline-block
|
||||||
|
.fa-times-circle
|
||||||
|
display: none
|
||||||
|
.newProductButton.active
|
||||||
|
background-color: #fb557b
|
||||||
|
color: black
|
||||||
|
.fa-times-circle
|
||||||
|
display: inline-block
|
||||||
|
.fa-plus-circle
|
||||||
|
display: none
|
||||||
|
> tbody
|
||||||
|
> tr
|
||||||
|
.actionRemove
|
||||||
|
color: #F77
|
||||||
|
.actionEdit
|
||||||
|
color: #44F
|
||||||
|
.editorApply
|
||||||
|
color: green
|
||||||
|
.editorCancel
|
||||||
|
color: red
|
||||||
|
> tr.deactivated
|
||||||
|
background-color: #fac0d1
|
||||||
|
.actionActivate
|
||||||
|
color: #158b18
|
||||||
|
.actionHide
|
||||||
|
color: #6a0707
|
||||||
|
.actionEdit
|
||||||
|
color: #0101e4
|
||||||
|
> tr.deactivated:hover
|
||||||
|
background-color: #ffcadb
|
||||||
|
> tr.hidden
|
||||||
|
background-color: #e995ff
|
||||||
|
.actionEdit
|
||||||
|
color: #0101e4
|
||||||
|
.actionShow
|
||||||
|
color: #027905
|
||||||
|
> tr.hidden:hover
|
||||||
|
background-color: #ffb5ff
|
||||||
@@ -1,33 +1,90 @@
|
|||||||
|
|
||||||
import './Products.html';
|
import './Products.html';
|
||||||
|
|
||||||
|
let QUERY_LIMIT = 20;
|
||||||
|
let PREFIX = "Products.";
|
||||||
|
|
||||||
Tracker.autorun(function() {
|
Tracker.autorun(function() {
|
||||||
Meteor.subscribe("products");
|
Meteor.subscribe("products");
|
||||||
Meteor.subscribe("productTags");
|
Meteor.subscribe("productTags");
|
||||||
|
Meteor.subscribe("measures");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Template.Products.onCreated(function() {
|
||||||
|
Session.set(PREFIX + "displayNewProduct", false);
|
||||||
|
Session.set(PREFIX + "showHidden", false);
|
||||||
|
});
|
||||||
Template.Products.helpers({
|
Template.Products.helpers({
|
||||||
|
displayNewProduct: function() {
|
||||||
|
return Session.get(PREFIX + "displayNewProduct");
|
||||||
|
},
|
||||||
products: function() {
|
products: function() {
|
||||||
let query = Session.get('searchQuery');
|
let skipCount = Session.get(PREFIX + 'skipCount') || 0;
|
||||||
let dbQuery = {};
|
let query = Session.get(PREFIX + 'searchQuery');
|
||||||
|
let dbQuery = [];
|
||||||
|
|
||||||
if(query) {
|
if(query) {
|
||||||
_.each(_.keys(query), function(key) {
|
_.each(_.keys(query), function(key) {
|
||||||
if(_.isFunction(query[key])) dbQuery[key] = query[key]();
|
if(_.isFunction(query[key])) dbQuery.push({[key]: query[key]}); //dbQuery[key] = query[key]();
|
||||||
else if(_.isObject(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[key] = query[key];
|
else if(_.isNumber(query[key])) dbQuery.push({[key]: query[key]}); //dbQuery[key] = query[key];
|
||||||
else dbQuery[key] = {$regex: query[key], $options: 'i'};
|
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'}});
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return Meteor.collections.Products.find(dbQuery, {limit: 20, sort: {name: 1}});
|
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 + '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}});
|
||||||
|
},
|
||||||
|
disablePrev: function() {
|
||||||
|
return (Session.get(PREFIX + 'skipCount') || 0) == 0;
|
||||||
|
},
|
||||||
|
disableNext: function() {
|
||||||
|
return Session.get(PREFIX + 'productCount') - (Session.get(PREFIX + 'skipCount') || 0) - QUERY_LIMIT <= 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Template.Products.events({
|
||||||
|
'click .prevProducts': function(event, template) {
|
||||||
|
if(!$(event.target).hasClass('disabled'))
|
||||||
|
Session.set(PREFIX + 'skipCount', Math.max(0, (Session.get(PREFIX + 'skipCount') || 0) - QUERY_LIMIT));
|
||||||
|
},
|
||||||
|
'click .nextProducts': function(event, template) {
|
||||||
|
if(!$(event.target).hasClass('disabled'))
|
||||||
|
Session.set(PREFIX + 'skipCount', (Session.get(PREFIX + 'skipCount') || 0) + QUERY_LIMIT);
|
||||||
|
},
|
||||||
|
'click .newProductButton': function(event, template) {
|
||||||
|
if(template.$('.newProductButton').hasClass('active')) {
|
||||||
|
Session.set(PREFIX + 'displayNewProduct', false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Session.set(PREFIX + 'displayNewProduct', true);
|
||||||
|
Session.set(PREFIX + "editedProduct", undefined); //Clear the edited product so that only one editor is open at a time.
|
||||||
|
}
|
||||||
|
template.$('.newProductButton').toggleClass('active');
|
||||||
|
},
|
||||||
|
'change input[name="showHidden"]': function(event, template) {
|
||||||
|
//console.log("changed " + $(event.target).prop('checked'));
|
||||||
|
Session.set(PREFIX + "showHidden", $(event.target).prop('checked'));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.ProductSearch.events({
|
Template.ProductSearch.events({
|
||||||
"keyup .searchInput": _.throttle(function(event, template) {
|
"keyup .searchInput": _.throttle(function(event, template) {
|
||||||
let searchQuery = Session.get('searchQuery') || {};
|
let searchQuery = Session.get(PREFIX + 'searchQuery') || {};
|
||||||
let searchFields = Session.get('searchFields') || {};
|
let searchFields = Session.get(PREFIX + 'searchFields') || {};
|
||||||
let searchValue = template.$('.searchInput').val();
|
let searchValue = template.$('.searchInput').val();
|
||||||
|
|
||||||
if(searchValue) {
|
if(searchValue) {
|
||||||
@@ -51,13 +108,13 @@ Template.ProductSearch.events({
|
|||||||
delete searchFields[this.columnName];
|
delete searchFields[this.columnName];
|
||||||
}
|
}
|
||||||
|
|
||||||
Session.set('searchQuery', searchQuery);
|
Session.set(PREFIX + 'searchQuery', searchQuery);
|
||||||
|
Session.set(PREFIX + 'searchFields', searchFields);
|
||||||
}, 500)
|
}, 500)
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.ProductSearch.helpers({
|
Template.ProductSearch.helpers({
|
||||||
searchValue: function() {
|
searchValue: function() {
|
||||||
let searchFields = Session.get('searchFields');
|
let searchFields = Session.get(PREFIX + 'searchFields');
|
||||||
|
|
||||||
return (searchFields && searchFields[this.columnName]) ? searchFields[this.columnName] : '';
|
return (searchFields && searchFields[this.columnName]) ? searchFields[this.columnName] : '';
|
||||||
}
|
}
|
||||||
@@ -82,6 +139,9 @@ Template.Product.helpers({
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
aliases: function() {
|
||||||
|
return this.aliases.join(', ');
|
||||||
|
},
|
||||||
tags: function() {
|
tags: function() {
|
||||||
let result = "";
|
let result = "";
|
||||||
|
|
||||||
@@ -99,5 +159,112 @@ Template.Product.helpers({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
},
|
||||||
|
editing: function() {
|
||||||
|
let editedProduct = Session.get(PREFIX + "editedProduct");
|
||||||
|
|
||||||
|
return editedProduct == this._id;
|
||||||
|
},
|
||||||
|
getRowClass: function() {
|
||||||
|
return this.hidden ? "hidden" : this.deactivated ? "deactivated" : "";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Template.Product.events({
|
||||||
|
"click .actionEdit": function(event, template) {
|
||||||
|
Session.set(PREFIX + "editedProduct", this._id);
|
||||||
|
Session.set(PREFIX + 'displayNewProduct', false); //Ensure the new product editor is closed.
|
||||||
|
template.$('.newProductButton').removeClass('active');
|
||||||
|
},
|
||||||
|
"click .actionRemove": function(event, template) {
|
||||||
|
Meteor.call('deactivateProduct', this._id, function(error, result) {
|
||||||
|
if(error) sAlert.error(error);
|
||||||
|
else sAlert.success("Product Deactivated");
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'click .actionActivate': function(event, template) {
|
||||||
|
Meteor.call('reactivateProduct', this._id, function(error, result) {
|
||||||
|
if(error) sAlert.error(error);
|
||||||
|
else sAlert.success("Product Reactivated");
|
||||||
|
});
|
||||||
|
},
|
||||||
|
"click .actionShow": function(event, template) {
|
||||||
|
Meteor.call('showProduct', this._id, function(error, result) {
|
||||||
|
if(error) sAlert.error(error);
|
||||||
|
else sAlert.success("Product Visibility Enabled");
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'click .actionHide': function(event, template) {
|
||||||
|
Meteor.call('hideProduct', this._id, function(error, result) {
|
||||||
|
if(error) sAlert.error(error);
|
||||||
|
else sAlert.success("Product Visibility Disabled");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
Template.ProductEditor.onRendered(function() {
|
||||||
|
this.$(".productTagsEditor").select2();
|
||||||
|
this.$(".productAliasesEditor").select2({tags: true, tokenSeparators: [';', '.']});
|
||||||
|
this.$(".productMeasuresEditor").select2();
|
||||||
|
});
|
||||||
|
Template.ProductEditor.helpers({
|
||||||
|
measures: function() {
|
||||||
|
return Meteor.collections.Measures.find({});
|
||||||
|
},
|
||||||
|
measureSelected: function() {
|
||||||
|
let measure = this;
|
||||||
|
let product = Template.parentData();
|
||||||
|
|
||||||
|
return product.measures && product.measures.includes(measure._id) ? "selected" : "";
|
||||||
|
},
|
||||||
|
aliases: function() {
|
||||||
|
return this.aliases;
|
||||||
|
},
|
||||||
|
tags: function() {
|
||||||
|
return Meteor.collections.ProductTags.find({});
|
||||||
|
},
|
||||||
|
tagSelected: function() {
|
||||||
|
let tag = this;
|
||||||
|
let product = Template.parentData();
|
||||||
|
|
||||||
|
return product.tags && product.tags.includes(tag._id) ? "selected" : "";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Template.ProductEditor.events({
|
||||||
|
"click .editorCancel": function(event, template) {
|
||||||
|
Session.set(PREFIX + "editedProduct", undefined);
|
||||||
|
Session.set(PREFIX + 'displayNewProduct', false);
|
||||||
|
template.$('.newProductButton').removeClass('active');
|
||||||
|
},
|
||||||
|
"click .editorApply": function(event, template) {
|
||||||
|
let name = template.$("input[name='name']").val().trim();
|
||||||
|
let tags = template.$(".productTagsEditor").select2('data');
|
||||||
|
let aliases = template.$(".productAliasesEditor").select2('data');
|
||||||
|
let measures = template.$(".productMeasuresEditor").select2('data');
|
||||||
|
|
||||||
|
tags = tags.map((n)=>n.id);
|
||||||
|
aliases = aliases.map((n)=>n.id);
|
||||||
|
measures = measures.map((n)=>n.id);
|
||||||
|
|
||||||
|
if(Session.get(PREFIX + 'displayNewProduct')) {
|
||||||
|
Meteor.call("createProduct", name, tags, aliases, measures, function(error, result) {
|
||||||
|
if(error) sAlert.error(error);
|
||||||
|
else {
|
||||||
|
sAlert.success("Product created.");
|
||||||
|
Session.set(PREFIX + 'displayNewProduct', false);
|
||||||
|
template.$('.newProductButton').removeClass('active');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Meteor.call("updateProduct", this._id, name, tags, aliases, measures, function(error, result) {
|
||||||
|
if(error) sAlert.error(error);
|
||||||
|
else {
|
||||||
|
sAlert.success("Product updated.");
|
||||||
|
Session.set(PREFIX + "editedProduct", undefined);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -5,16 +5,16 @@
|
|||||||
{{>InsertSale}}
|
{{>InsertSale}}
|
||||||
</div>
|
</div>
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<table class="dataTable table table-striped table-hover">
|
<table class="table table-striped table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="headers">
|
<tr class="headers">
|
||||||
<th class="tdLarge noselect nonclickable" style="width: 80px">Amount</th>
|
<th class="amount noselect nonclickable">Amount</th>
|
||||||
<th class="tdLarge noselect nonclickable">Product</th>
|
<th class="product noselect nonclickable">Product</th>
|
||||||
<th class="tdLarge noselect nonclickable" style="width: 140px">Price</th>
|
<th class="price noselect nonclickable">Price</th>
|
||||||
<th class="tdLarge noselect nonclickable" style="width: 90px">Measure</th>
|
<th class="measure noselect nonclickable">Measure</th>
|
||||||
<th class="tdLarge noselect nonclickable" style="width: 140px">Date (Week)</th>
|
<th class="date noselect nonclickable">Date (Week)</th>
|
||||||
<th class="tdLarge noselect nonclickable" style="width: 120px">Venue</th>
|
<th class="venue noselect nonclickable">Venue</th>
|
||||||
<th class="tdLarge noselect nonclickable" style="width: 90px">Actions</th>
|
<th class="actions noselect nonclickable">Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="footers">
|
<tr class="footers">
|
||||||
<th>{{>SaleSearch columnName='amount' width='90%'}}</th>
|
<th>{{>SaleSearch columnName='amount' width='90%'}}</th>
|
||||||
@@ -33,6 +33,10 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="pagination">
|
||||||
|
<span class="prevButton noselect {{#if disablePrev}}disabled{{/if}}"><i class="fa fa-long-arrow-left" aria-hidden="true"></i> Prev</span>
|
||||||
|
<span class="nextButton noselect {{#if disableNext}}disabled{{/if}}">Next <i class="fa fa-long-arrow-right" aria-hidden="true"></i></span>
|
||||||
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
@@ -40,7 +44,6 @@
|
|||||||
|
|
||||||
<template name="Sale">
|
<template name="Sale">
|
||||||
<tr>
|
<tr>
|
||||||
<!--{{#if editable}}-->
|
|
||||||
<td class="tdLarge noselect nonclickable center">{{amount}}</td>
|
<td class="tdLarge noselect nonclickable center">{{amount}}</td>
|
||||||
<td class="tdLarge noselect nonclickable left">{{productName productId}}</td>
|
<td class="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="tdLarge noselect nonclickable left">{{formatPrice price}}{{#if showTotalPrice amount}} ({{formatTotalPrice price amount}}){{/if}}</td>
|
||||||
@@ -48,30 +51,6 @@
|
|||||||
<td class="tdLarge noselect nonclickable left">{{formatDate date}}</td>
|
<td class="tdLarge noselect nonclickable left">{{formatDate date}}</td>
|
||||||
<td class="tdLarge noselect nonclickable left">{{venueName venueId}}</td>
|
<td class="tdLarge noselect nonclickable left">{{venueName venueId}}</td>
|
||||||
<td class="tdLarge noselect left"><i class="fa fa-times-circle fa-lg saleRemove clickable" aria-hidden="true"></i></td>
|
<td class="tdLarge noselect left"><i class="fa fa-times-circle fa-lg saleRemove clickable" aria-hidden="true"></i></td>
|
||||||
<!--<a class="saleEdit" href="javascript:"><i class="fa fa-pencil-square-o fa-lg" aria-hidden="true"></i></a>/-->
|
|
||||||
<!--{{else}}-->
|
|
||||||
<!--<form class="editSaleForm" autocomplete="off">-->
|
|
||||||
<!--<td><input name="amount" class="form-control" type="number" min="0" data-schema-key='amount' value="{{amount}}" required></td>-->
|
|
||||||
<!--<td><input name="product" class="form-control" type="text" required/></td>-->
|
|
||||||
<!--<td><input name="price" class="form-control" type="number" min="0" data-schema-key='currency' value="{{price}}" required></td>-->
|
|
||||||
<!--<td>-->
|
|
||||||
<!--<select name="measure" class="form-control" required>-->
|
|
||||||
<!--{{#each measures}}-->
|
|
||||||
<!--<option value="{{this._id}}">{{this.name}}</option>-->
|
|
||||||
<!--{{/each}}-->
|
|
||||||
<!--</select>-->
|
|
||||||
<!--</td>-->
|
|
||||||
<!--<td><input type="date" class="form-control" name="date" data-schema-key='date' value="{{date}}" required></td>-->
|
|
||||||
<!--<td>-->
|
|
||||||
<!--<select name="venue" class="form-control" required>-->
|
|
||||||
<!--{{#each venues}}-->
|
|
||||||
<!--<option value="{{this._id}}">{{this.name}}</option>-->
|
|
||||||
<!--{{/each}}-->
|
|
||||||
<!--</select>-->
|
|
||||||
<!--</td>-->
|
|
||||||
<!--<td><a class="editorSave" href="javascript:"><i class="fa fa-check-square-o fa-lg" aria-hidden="true"></i></a>/<a class="editorCancel" href="javascript:"><i class="fa fa-times-circle fa-lg" aria-hidden="true"></i></a></td>-->
|
|
||||||
<!--</form>-->
|
|
||||||
<!--{{/if}}-->
|
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -80,27 +59,27 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template name="InsertSale">
|
<template name="InsertSale">
|
||||||
<form id="insertSale" autocomplete="off">
|
<form class="insertSaleForm" autocomplete="off">
|
||||||
<div class="row">
|
<div class="grid">
|
||||||
<div class="col-md-4 col-sm-6">
|
<div class="col-4-12">
|
||||||
<div class="formGroupHeading">New Sale</div>
|
<div class="formGroupHeading">New Sale</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for='InsertSaleDate' class='control-label'>Date</label>
|
<label class='control-label'>Date</label>
|
||||||
<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 class="form-group">
|
<div class="form-group">
|
||||||
<label for='InsertSaleProduct' class='control-label'>Product</label>
|
<label class='control-label'>Product</label>
|
||||||
<input name="product" class="form-control" type="text" required/>
|
<input name="product" class="form-control" type="text" required/>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for='InsertSaleVenue' class='control-label'>Venue</label>
|
<label class='control-label'>Venue</label>
|
||||||
<input name="venue" class="form-control" type="text" required/>
|
<input name="venue" class="form-control" type="text" required/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{#each productMeasures}}
|
{{#each productMeasures}}
|
||||||
{{>InsertSaleMeasure this}}
|
{{>InsertSaleMeasure this}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
<div class="col-md-12">
|
<div class="col-1-1">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input type="submit" class="btn btn-success" value="Save Sale">
|
<input type="submit" class="btn btn-success" value="Save Sale">
|
||||||
</div>
|
</div>
|
||||||
@@ -110,7 +89,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template name="InsertSaleMeasure">
|
<template name="InsertSaleMeasure">
|
||||||
<div class="col-md-4 col-sm-6 insertSaleMeasure">
|
<div class="col-2-12 insertSaleMeasure">
|
||||||
<div class="formGroupHeading">{{name}}</div>
|
<div class="formGroupHeading">{{name}}</div>
|
||||||
<input type="hidden" class="measureId" value="{{this._id}}">
|
<input type="hidden" class="measureId" value="{{this._id}}">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -123,7 +102,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class='control-label'>Total</label>
|
<label class='control-label'>Total</label>
|
||||||
<input type="number" class="form-control total" name="total" tabindex="-1" data-schema-key='currency' value="{{total}}" readonly>
|
<input type="number" class="form-control total" name="total" data-schema-key='currency' value="{{total}}" tabindex="-1" readonly>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
61
imports/ui/Sales.import.styl
vendored
61
imports/ui/Sales.import.styl
vendored
@@ -1,24 +1,17 @@
|
|||||||
#salesMain
|
#salesMain
|
||||||
margin: 10px 20px
|
margin: 10px 20px
|
||||||
height: 100%
|
height: 100%
|
||||||
//Flex container options.
|
text-align: left
|
||||||
flex-flow: column nowrap
|
|
||||||
justify-content: space-around //Spacing between sales along the primary axis. (vertical spacing for a column layout)
|
.comboList .deactivated
|
||||||
align-items: flex-start //Align the sales within a line along the primary axis. (horizontal alignment for a column layout)
|
color: red
|
||||||
align-content: center //Spacing between lines along the secondary axis. (spacing between columns for a column layout)
|
background: #ffdbd9
|
||||||
display: -webkit-box
|
|
||||||
display: -moz-box
|
|
||||||
display: -ms-flexbox
|
|
||||||
display: -moz-flex
|
|
||||||
display: -webkit-flex
|
|
||||||
display: flex
|
|
||||||
|
|
||||||
.editor
|
.editor
|
||||||
height: 100%
|
height: 100%
|
||||||
overflow-y: auto
|
overflow-y: auto
|
||||||
|
|
||||||
.insertSale
|
.insertSale
|
||||||
flex: none
|
|
||||||
width: 100%
|
width: 100%
|
||||||
|
|
||||||
.form-group, label
|
.form-group, label
|
||||||
@@ -30,29 +23,41 @@
|
|||||||
font-style: normal
|
font-style: normal
|
||||||
font-variant: normal
|
font-variant: normal
|
||||||
font-weight: 500
|
font-weight: 500
|
||||||
|
|
||||||
.grid
|
.grid
|
||||||
flex: auto
|
width: 100%
|
||||||
align-self: stretch
|
|
||||||
overflow-y: auto
|
|
||||||
overflow-x: auto
|
|
||||||
margin-bottom: 20px
|
margin-bottom: 20px
|
||||||
border: 0
|
border: 0
|
||||||
padding-top: 20px
|
font-size: 12.5px
|
||||||
|
label
|
||||||
.table > thead > tr > th
|
font-size: 10px
|
||||||
border: 0
|
font-weight: 800
|
||||||
padding-top: 0
|
table
|
||||||
padding-bottom: 6px
|
|
||||||
|
|
||||||
.dataTable
|
|
||||||
table-layout: fixed
|
table-layout: fixed
|
||||||
|
min-width: 100%
|
||||||
.tdLarge
|
|
||||||
font-size: 1.3em
|
|
||||||
.saleRemove
|
.saleRemove
|
||||||
color: red
|
color: red
|
||||||
margin-left: 8px
|
margin-left: 8px
|
||||||
.saleEdit
|
.saleEdit
|
||||||
color: darkblue
|
color: darkblue
|
||||||
margin-right: 8px
|
margin-right: 8px
|
||||||
|
.editorApply
|
||||||
|
color: green
|
||||||
|
.editorCancel
|
||||||
|
color: red
|
||||||
|
thead
|
||||||
|
> tr
|
||||||
|
> th.amount
|
||||||
|
width: 90px
|
||||||
|
> th.product
|
||||||
|
width: auto
|
||||||
|
min-width: 140px
|
||||||
|
> th.price
|
||||||
|
width: 140px
|
||||||
|
> th.measure
|
||||||
|
width: 90px
|
||||||
|
> th.date
|
||||||
|
width: 140px
|
||||||
|
> th.venue
|
||||||
|
width: 160px
|
||||||
|
> th.actions
|
||||||
|
width: 90px
|
||||||
|
|||||||
@@ -3,79 +3,40 @@ import './Sales.html';
|
|||||||
import '/imports/util/selectize/selectize.js'
|
import '/imports/util/selectize/selectize.js'
|
||||||
import ResizeSensor from '/imports/util/resize/ResizeSensor.js';
|
import ResizeSensor from '/imports/util/resize/ResizeSensor.js';
|
||||||
|
|
||||||
Tracker.autorun(function() {
|
let QUERY_LIMIT = 20;
|
||||||
Meteor.subscribe("products");
|
let PREFIX = "Sales.";
|
||||||
Meteor.subscribe("sales", Session.get('searchQuery'));
|
|
||||||
});
|
|
||||||
|
|
||||||
Template.Sales.onRendered(function() {
|
Meteor.subscribe("products");
|
||||||
// console.log("moving headers");
|
|
||||||
// try {
|
Tracker.autorun(function() {
|
||||||
// //Move the headers into the header table that will maintain its position.
|
Meteor.subscribe("sales", Session.get(PREFIX + 'searchQuery'), QUERY_LIMIT, Session.get(PREFIX + 'skipCount'));
|
||||||
// //Link the column widths to the header widths.
|
Session.set(PREFIX + 'saleCount', Meteor.call('getSalesCount', Session.get(PREFIX + 'searchQuery')));
|
||||||
// let newHeaderRow = this.$('.dataTableHeader thead tr:first');
|
|
||||||
// let newFooterRow = this.$('.dataTableFooter thead tr:first');
|
|
||||||
// let oldHeaders = this.$('.dataTable thead tr.headers th');
|
|
||||||
// let oldFooters = this.$('.dataTable thead tr.footers th');
|
|
||||||
//
|
|
||||||
// console.log("header count " + oldHeaders.length);
|
|
||||||
//
|
|
||||||
// for(let index = 0; index < oldHeaders.length; index++) {
|
|
||||||
// let width = this.$('.dataTable tbody tr:first td:eq(' + index + ')').width();
|
|
||||||
// let oldHeader = oldHeaders.eq(index);
|
|
||||||
// let newHeader = $("<th\>");
|
|
||||||
// oldHeader.replaceWith(newHeader);
|
|
||||||
// newHeader.width(width);
|
|
||||||
// oldHeader.appendTo(newHeaderRow);
|
|
||||||
// //Link the two headers so that the visible header changes size with the hidden one.
|
|
||||||
// //TODO: Turn this off if manually resizing the visible headers - while resizing.
|
|
||||||
// new ResizeSensor(newHeader, function() {
|
|
||||||
// oldHeader.width(newHeader.width());
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// for(let index = 0; index < oldFooters.length; index++) {
|
|
||||||
// let width = this.$('.dataTable tbody tr:first td:eq(' + index + ')').width();
|
|
||||||
// let oldFooter = oldFooters.eq(index);
|
|
||||||
// let newFooter = $("<th\>");
|
|
||||||
// oldFooter.replaceWith(newFooter);
|
|
||||||
// newFooter.width(width);
|
|
||||||
// oldFooter.appendTo(newFooterRow);
|
|
||||||
// //Link the two headers so that the visible header changes size with the hidden one.
|
|
||||||
// //TODO: Turn this off if manually resizing the visible headers - while resizing.
|
|
||||||
// new ResizeSensor(newFooter, function() {
|
|
||||||
// oldFooter.width(newFooter.width());
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// catch(err) {
|
|
||||||
// console.log(err);
|
|
||||||
// }
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.Sales.helpers({
|
Template.Sales.helpers({
|
||||||
sales: function() {
|
sales: function() {
|
||||||
return Meteor.collections.Sales.find({}, {sort: {date: -1}});
|
return Meteor.collections.Sales.find({}, {sort: {date: -1, createdAt: -1}});
|
||||||
|
},
|
||||||
|
disablePrev: function() {
|
||||||
|
return (Session.get(PREFIX + 'skipCount') || 0) == 0;
|
||||||
|
},
|
||||||
|
disableNext: function() {
|
||||||
|
return Session.get(PREFIX + 'saleCount') - (Session.get(PREFIX + 'skipCount') || 0) - QUERY_LIMIT <= 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Template.Sales.events({
|
||||||
|
'click .prevButton': function(event, template) {
|
||||||
|
if(!$(event.target).hasClass('disabled'))
|
||||||
|
Session.set(PREFIX + 'skipCount', Math.max(0, (Session.get(PREFIX + 'skipCount') || 0) - QUERY_LIMIT));
|
||||||
|
},
|
||||||
|
'click .nextButton': function(event, template) {
|
||||||
|
if(!$(event.target).hasClass('disabled'))
|
||||||
|
Session.set(PREFIX + 'skipCount', (Session.get(PREFIX + 'skipCount') || 0) + QUERY_LIMIT);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.Sale.onCreated(function() {
|
Template.Sale.onCreated(function() {
|
||||||
});
|
});
|
||||||
Template.Sale.events({
|
|
||||||
"click .saleRemove": function(event, template) {
|
|
||||||
let _this = this;
|
|
||||||
bootbox.confirm({
|
|
||||||
message: "Delete the sale?",
|
|
||||||
buttons: {confirm: {label: "Yes", className: 'btn-success'}, cancel: {label: "No", className: "btn-danger"}},
|
|
||||||
callback: function(result) {
|
|
||||||
if(result) {
|
|
||||||
// Meteor.collections.Sales.remove(_this._id);
|
|
||||||
Meteor.call('deleteSale', _this._id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Template.Sale.helpers({
|
Template.Sale.helpers({
|
||||||
measureName: function(id) {
|
measureName: function(id) {
|
||||||
return Meteor.collections.Measures.findOne({_id: id}, {fields: {name: 1}}).name;
|
return Meteor.collections.Measures.findOne({_id: id}, {fields: {name: 1}}).name;
|
||||||
@@ -99,11 +60,33 @@ Template.Sale.helpers({
|
|||||||
return amount > 1;
|
return amount > 1;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Template.Sale.events({
|
||||||
|
"click .saleRemove": function(event, template) {
|
||||||
|
let _this = this;
|
||||||
|
bootbox.confirm({
|
||||||
|
message: "Delete the sale?",
|
||||||
|
buttons: {confirm: {label: "Yes", className: 'btn-success'}, cancel: {label: "No", className: "btn-danger"}},
|
||||||
|
callback: function(result) {
|
||||||
|
if(result) {
|
||||||
|
// Meteor.collections.Sales.remove(_this._id);
|
||||||
|
Meteor.call('deleteSale', _this._id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.SaleSearch.helpers({
|
||||||
|
searchValue: function() {
|
||||||
|
let searchFields = Session.get(PREFIX + 'searchFields');
|
||||||
|
|
||||||
|
return (searchFields && searchFields[this.columnName]) ? searchFields[this.columnName] : '';
|
||||||
|
}
|
||||||
|
});
|
||||||
Template.SaleSearch.events({
|
Template.SaleSearch.events({
|
||||||
"keyup .searchInput": _.throttle(function(event, template) {
|
"keyup .searchInput": _.throttle(function(event, template) {
|
||||||
let searchQuery = Session.get('searchQuery') || {};
|
let searchQuery = Session.get(PREFIX + 'searchQuery') || {};
|
||||||
let searchFields = Session.get('searchFields') || {};
|
let searchFields = Session.get(PREFIX + 'searchFields') || {};
|
||||||
let searchValue = template.$('.searchInput').val();
|
let searchValue = template.$('.searchInput').val();
|
||||||
|
|
||||||
if(searchValue) {
|
if(searchValue) {
|
||||||
@@ -127,32 +110,31 @@ Template.SaleSearch.events({
|
|||||||
delete searchFields[this.columnName];
|
delete searchFields[this.columnName];
|
||||||
}
|
}
|
||||||
|
|
||||||
Session.set('searchQuery', searchQuery);
|
Session.set(PREFIX + 'searchQuery', searchQuery);
|
||||||
|
Session.set(PREFIX + 'searchFields', searchFields);
|
||||||
}, 500)
|
}, 500)
|
||||||
});
|
});
|
||||||
Template.SaleSearch.helpers({
|
|
||||||
searchValue: function() {
|
|
||||||
let searchFields = Session.get('searchFields');
|
|
||||||
|
|
||||||
return (searchFields && searchFields[this.columnName]) ? searchFields[this.columnName] : '';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// let SelectedProduct = new ReactiveVar();
|
|
||||||
Template.InsertSale.onCreated(function() {
|
Template.InsertSale.onCreated(function() {
|
||||||
// $('#insertSale').validator();
|
// $('#insertSale').validator();
|
||||||
// $('#insertSale').data('bs.validator');
|
// $('#insertSale').data('bs.validator');
|
||||||
// this.products = new ReactiveVar([]);
|
// this.products = new ReactiveVar([]);
|
||||||
|
this.selectedDate = new ReactiveVar();
|
||||||
this.selectedProduct = new ReactiveVar();
|
this.selectedProduct = new ReactiveVar();
|
||||||
this.selectedVenue = new ReactiveVar();
|
this.selectedVenue = new ReactiveVar();
|
||||||
});
|
});
|
||||||
Template.InsertSale.onRendered(function() {
|
Template.InsertSale.onRendered(function() {
|
||||||
$('#insertSale').validator();
|
this.$('.insertSaleForm').validator();
|
||||||
// this.$('[name="product"]').
|
// this.$('[name="product"]').
|
||||||
// this.autorun(function() {
|
// this.autorun(function() {
|
||||||
// this.$('[name="product"]').buildCombo(Meteor.collections.Products.find({}).fetch(), {textAttr: 'name', listClass: 'comboList'});
|
// this.$('[name="product"]').buildCombo(Meteor.collections.Products.find({}).fetch(), {textAttr: 'name', listClass: 'comboList'});
|
||||||
// });
|
// });
|
||||||
this.$('[name="product"]').buildCombo({cursor: Meteor.collections.Products.find({}), selection: this.selectedProduct, textAttr: 'name', listClass: 'comboList'});
|
|
||||||
|
//TODO: Highlight deactivated products in combo
|
||||||
|
//TODO: Default the price for each size product based on the date.
|
||||||
|
this.$('[name="product"]').buildCombo({cursor: Meteor.collections.Products.find({$or: [{hidden: false}, {hidden: {$exists:false}}]}), selection: this.selectedProduct, textAttr: 'name', listClass: 'comboList', getClasses: function(data) {
|
||||||
|
return (data && data.deactivated) ? "deactivated" : "";
|
||||||
|
}});
|
||||||
this.$('[name="venue"]').buildCombo({cursor: Meteor.collections.Venues.find({}), selection: this.selectedVenue, textAttr: 'name', listClass: 'comboList'});
|
this.$('[name="venue"]').buildCombo({cursor: Meteor.collections.Venues.find({}), selection: this.selectedVenue, textAttr: 'name', listClass: 'comboList'});
|
||||||
|
|
||||||
// this.autorun(function(){
|
// this.autorun(function(){
|
||||||
@@ -160,14 +142,17 @@ Template.InsertSale.onRendered(function() {
|
|||||||
// }.bind(this));
|
// }.bind(this));
|
||||||
});
|
});
|
||||||
Template.InsertSale.events({
|
Template.InsertSale.events({
|
||||||
'change #InsertSaleProduct': function(event, template) {
|
'change input[name="product"]': function(event, template) {
|
||||||
let selectedId = $('#InsertSaleProduct').val();
|
let selectedId = template.$('input[name="product"]').val();
|
||||||
let selected = Meteor.collections.Products.findOne(selectedId);
|
let selected = Meteor.collections.Products.findOne(selectedId);
|
||||||
template.selectedProduct.set(selected);
|
template.selectedProduct.set(selected);
|
||||||
},
|
},
|
||||||
|
'change input[name="date"]': function(event, template) {
|
||||||
|
template.selectedDate.set(moment(event.target.value, "YYYY-MM-DD").toDate());
|
||||||
|
},
|
||||||
'click input[type="submit"]': function(event, template) {
|
'click input[type="submit"]': function(event, template) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
$('#insertSale').data('bs.validator').validate(function(isValid) {
|
template.$('.insertSaleForm').data('bs.validator').validate(function(isValid) {
|
||||||
if(isValid) {
|
if(isValid) {
|
||||||
let sales = [];
|
let sales = [];
|
||||||
let sale = {
|
let sale = {
|
||||||
@@ -192,30 +177,20 @@ Template.InsertSale.events({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// let debug = "Inserting: ";
|
|
||||||
// for(next in sales) {
|
|
||||||
// debug += "\n\t" + next;
|
|
||||||
// }
|
|
||||||
// console.log(debug);
|
|
||||||
for(let index = 0; index < sales.length; index++) {
|
for(let index = 0; index < sales.length; index++) {
|
||||||
let next = sales[index];
|
let next = sales[index];
|
||||||
console.log("Inserting: " + JSON.stringify(next));
|
//console.log("Inserting: " + JSON.stringify(next));
|
||||||
// Meteor.collections.Sales.insert(next, function(err, id) {
|
Meteor.call('insertSale', next, function(error) {
|
||||||
// if(err) console.log(err);
|
if(error) sAlert.error("Failed to insert the sale!\n" + error);
|
||||||
// });
|
else sAlert.success("Sale Created");
|
||||||
Meteor.call('insertSale', next);
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Template.InsertSale.helpers({
|
Template.InsertSale.helpers({
|
||||||
// sales: function() {
|
|
||||||
// return Meteor.collections.Sales;
|
|
||||||
// },
|
|
||||||
products: function() {
|
products: function() {
|
||||||
//return Meteor.collections.Products.find({});
|
|
||||||
//return this.products;
|
|
||||||
return [{label: "Hermies", value: 1}, {label: "Ralfe", value: 2}, {label: "Bob", value: 3}];
|
return [{label: "Hermies", value: 1}, {label: "Ralfe", value: 2}, {label: "Bob", value: 3}];
|
||||||
},
|
},
|
||||||
productMeasures: function() {
|
productMeasures: function() {
|
||||||
@@ -226,8 +201,8 @@ Template.InsertSale.helpers({
|
|||||||
result[i] = Meteor.collections.Measures.findOne(result[i]);
|
result[i] = Meteor.collections.Measures.findOne(result[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(product) console.log("Found " + result.length + " measures for the product " + product.name);
|
// if(product) console.log("Found " + result.length + " measures for the product " + product.name);
|
||||||
else console.log("No product!");
|
// else console.log("No product!");
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
@@ -237,29 +212,45 @@ Template.InsertSale.helpers({
|
|||||||
});
|
});
|
||||||
|
|
||||||
Template.InsertSaleMeasure.onCreated(function() {
|
Template.InsertSaleMeasure.onCreated(function() {
|
||||||
let prices = this.parentTemplate().selectedProduct.get().prices;
|
let _this = this;
|
||||||
|
|
||||||
|
this.price = new ReactiveVar(0);
|
||||||
|
this.amount = new ReactiveVar(0);
|
||||||
|
|
||||||
|
Tracker.autorun(function() {
|
||||||
|
let date = _this.parentTemplate().selectedDate.get();
|
||||||
|
let prices = _this.parentTemplate().selectedProduct.get().prices;
|
||||||
|
let priceData;
|
||||||
let price = 0;
|
let price = 0;
|
||||||
|
|
||||||
if(prices) price = prices[this._id];
|
if(prices) priceData = prices[_this.data._id];
|
||||||
|
|
||||||
this.price = new ReactiveVar(price);
|
//If this product has pricing data for the given measure, then either use the price, or the previousPrice (if there is one and the effectiveDate is after the sale date).
|
||||||
this.amount = new ReactiveVar(0);
|
if(priceData) {
|
||||||
|
if(priceData.effectiveDate && date && moment(priceData.effectiveDate).isAfter(date))
|
||||||
|
price = priceData.previousPrice;
|
||||||
|
else
|
||||||
|
price = priceData.price
|
||||||
|
}
|
||||||
|
|
||||||
|
_this.price.set(price);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
Template.InsertSaleMeasure.events({
|
Template.InsertSaleMeasure.events({
|
||||||
'change .price': function(event, template) {
|
'change .price': function(event, template) {
|
||||||
template.price.set(parseFloat($(event.target).val()).toFixed(2));
|
template.price.set(parseFloat($(event.target).val()));
|
||||||
},
|
},
|
||||||
'change .amount': function(event, template) {
|
'change .amount': function(event, template) {
|
||||||
template.amount.set(parseFloat($(event.target).val()).toFixed(2));
|
template.amount.set(parseFloat($(event.target).val()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Template.InsertSaleMeasure.helpers({
|
Template.InsertSaleMeasure.helpers({
|
||||||
price: function() {
|
price: function() {
|
||||||
return Template.instance().price.get();
|
return Template.instance().price.get().toFixed(2);
|
||||||
},
|
},
|
||||||
total: function() {
|
total: function() {
|
||||||
let template = Template.instance();
|
let template = Template.instance();
|
||||||
return template.price.get() * template.amount.get();
|
return (template.price.get() * template.amount.get()).toFixed(2);
|
||||||
},
|
},
|
||||||
amount: function() {
|
amount: function() {
|
||||||
return Template.instance().amount.get();
|
return Template.instance().amount.get();
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
<template name="Subcategories">
|
|
||||||
<div id="subcategories">
|
|
||||||
<div class="grid">
|
|
||||||
<div class="dataTable">
|
|
||||||
<table class="table table-striped table-hover">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Name {{>SubcategorySearch columnName='name'}}</th>
|
|
||||||
<th>Category {{>SubcategorySearch columnName='categoryId' collectionQueryColumnName='name' collection='Categories' collectionResultColumnName='_id'}}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{{#each subcategories}}
|
|
||||||
{{> Subcategory}}
|
|
||||||
{{/each}}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template name="Subcategory">
|
|
||||||
<tr>
|
|
||||||
<td>{{name}}</td>
|
|
||||||
<td>{{categoryName categoryId}}</td>
|
|
||||||
</tr>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template name="SubcategorySearch">
|
|
||||||
<div class="">
|
|
||||||
<input type="text" class="searchInput" placeholder="Filter..." value="{{searchValue}}"/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
52
imports/ui/Subcategories.import.styl
vendored
52
imports/ui/Subcategories.import.styl
vendored
@@ -1,52 +0,0 @@
|
|||||||
#subcategories
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
.editor
|
|
||||||
height: 100%;
|
|
||||||
overflow-y: auto;
|
|
||||||
|
|
||||||
.grid
|
|
||||||
height: 100%;
|
|
||||||
//Flex container options.
|
|
||||||
flex-flow: column nowrap;
|
|
||||||
justify-content: space-around; //Spacing between items along the primary axis. (vertical spacing for a column layout)
|
|
||||||
align-items: flex-start; //Align the items 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;
|
|
||||||
|
|
||||||
.buttonContainer
|
|
||||||
//Flex element options.
|
|
||||||
//flex: 0 0; //Grow, Shrink, Basis
|
|
||||||
flex: none;
|
|
||||||
|
|
||||||
.dataTable
|
|
||||||
overflow-y: auto;
|
|
||||||
//Flex element options.
|
|
||||||
flex: auto;
|
|
||||||
align-self: stretch;
|
|
||||||
height: 10%;
|
|
||||||
max-height: 100%;
|
|
||||||
|
|
||||||
.padding
|
|
||||||
flex: none;
|
|
||||||
height: 1px;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
#DFAliases
|
|
||||||
width: 100%;
|
|
||||||
height: 150px;
|
|
||||||
overflow: auto;
|
|
||||||
|
|
||||||
span
|
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
|
||||||
font-size: 1.5em;
|
|
||||||
cursor: pointer;
|
|
||||||
display: block;
|
|
||||||
|
|
||||||
span.selected
|
|
||||||
background-color: rgba(255, 248, 131, 0.51);
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
|
|
||||||
import './Subcategories.html';
|
|
||||||
|
|
||||||
// Tracker.autorun(function() {
|
|
||||||
// Meteor.subscribe("subcategories");
|
|
||||||
// });
|
|
||||||
|
|
||||||
Template.Subcategories.helpers({
|
|
||||||
subcategories: function() {
|
|
||||||
let query = Session.get('searchQuery');
|
|
||||||
let dbQuery = {};
|
|
||||||
|
|
||||||
if(query) {
|
|
||||||
_.each(_.keys(query), function(key) {
|
|
||||||
if(_.isFunction(query[key])) dbQuery[key] = query[key]();
|
|
||||||
else if(_.isObject(query[key])) dbQuery[key] = query[key];
|
|
||||||
else if(_.isNumber(query[key])) dbQuery[key] = query[key];
|
|
||||||
else dbQuery[key] = {$regex: query[key], $options: 'i'};
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return Meteor.collections.Subcategories.find(dbQuery, {limit: 20, sort: {updatedAt: -1}});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Template.Subcategories.events({
|
|
||||||
// 'click .trash': function() {
|
|
||||||
// Meteor.call('deleteSubcategory', this._id);
|
|
||||||
// console.log("Got here");
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
Template.Subcategory.helpers({
|
|
||||||
categoryName: function(id) {
|
|
||||||
return Meteor.collections.Categories.findOne({_id: id}, {fields: {name: 1}}).name;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Template.SubcategorySearch.events({
|
|
||||||
"keyup .searchInput": _.throttle(function(event, template) {
|
|
||||||
let searchQuery = Session.get('searchQuery') || {};
|
|
||||||
let searchFields = Session.get('searchFields') || {};
|
|
||||||
let searchValue = template.$('.searchInput').val();
|
|
||||||
|
|
||||||
if(searchValue) {
|
|
||||||
if(this.number) searchValue = parseFloat(searchValue);
|
|
||||||
|
|
||||||
if(this.collection) {
|
|
||||||
let ids = Meteor.collections[this.collection].find({[this.collectionQueryColumnName]: {$regex: searchValue, $options: 'i'}}, {fields: {[this.collectionResultColumnName]: 1}}).fetch();
|
|
||||||
|
|
||||||
//Convert the ids to an array of ids instead of an array of objects containing an id.
|
|
||||||
for(let i = 0; i < ids.length; i++) {ids[i] = ids[i]._id;}
|
|
||||||
searchQuery[this.columnName] = {$in: ids};
|
|
||||||
searchFields[this.columnName] = searchValue;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
searchFields[this.columnName] = searchQuery[this.columnName] = searchValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//Remove columns from the search query whose values are empty so we don't bother the database with them.
|
|
||||||
delete searchQuery[this.columnName];
|
|
||||||
delete searchFields[this.columnName];
|
|
||||||
}
|
|
||||||
|
|
||||||
Session.set('searchQuery', searchQuery);
|
|
||||||
}, 500)
|
|
||||||
});
|
|
||||||
|
|
||||||
Template.SubcategorySearch.helpers({
|
|
||||||
searchValue: function() {
|
|
||||||
let searchFields = Session.get('searchFields');
|
|
||||||
|
|
||||||
return (searchFields && searchFields[this.columnName]) ? searchFields[this.columnName] : '';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -4,18 +4,18 @@
|
|||||||
<div class="insert">
|
<div class="insert">
|
||||||
{{>UserInsert}}
|
{{>UserInsert}}
|
||||||
</div>
|
</div>
|
||||||
<div class="grid">
|
<div class="tableContainer">
|
||||||
<table class="dataTable table table-striped table-hover">
|
<table class="dataTable table table-striped table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="headers">
|
<tr class="headers">
|
||||||
<th>Username</th>
|
<th class="username">Username</th>
|
||||||
<th>Email</th>
|
<th class="email">Email</th>
|
||||||
<th>Roles</th>
|
<th class="roles">Roles</th>
|
||||||
<th>Actions</th>
|
<th class="actions">Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="footers">
|
<tr class="footers">
|
||||||
<th>{{>UserSearch columnName='username' maxWidth='40' minWidth='30'}}</th>
|
<th>{{>UserSearch columnName='username'}}</th>
|
||||||
<th>{{>UserSearch columnName='email' collectionQueryColumnName='name' collection='Items' collectionResultColumnName='_id' maxWidth='150' minWidth='50'}}</th>
|
<th>{{>UserSearch columnName='email' collectionQueryColumnName='name' collection='Items' collectionResultColumnName='_id'}}</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -54,15 +54,15 @@
|
|||||||
|
|
||||||
<template name="UserSearch">
|
<template name="UserSearch">
|
||||||
<div class="">
|
<div class="">
|
||||||
<input type="text" class="searchInput" placeholder="Filter..." value="{{searchValue}}" style="max-width: {{maxWidth}}px; min-width: {{minWidth}}px;"/>
|
<input type="text" class="searchInput" placeholder="Filter..." value="{{searchValue}}" style="width: 90%"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template name="UserInsert">
|
<template name="UserInsert">
|
||||||
<form name="insert" autocomplete="off">
|
<form name="insert" autocomplete="off">
|
||||||
<div class="row">
|
<div class="grid">
|
||||||
<div class="col-md-3 col-sm-0"></div>
|
<div class="col-3-12"></div>
|
||||||
<div class="col-md-6 col-sm-12">
|
<div class="col-6-12">
|
||||||
<div class="formGroupHeading">New User</div>
|
<div class="formGroupHeading">New User</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class='control-label'>User Name</label>
|
<label class='control-label'>User Name</label>
|
||||||
@@ -84,7 +84,7 @@
|
|||||||
<input type="submit" class="btn btn-success" value="Create">
|
<input type="submit" class="btn btn-success" value="Create">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3 col-sm-0"></div>
|
<div class="col-3-12"></div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</template>
|
</template>
|
||||||
34
imports/ui/UserManagement.import.styl
vendored
34
imports/ui/UserManagement.import.styl
vendored
@@ -33,26 +33,26 @@
|
|||||||
font-style: normal
|
font-style: normal
|
||||||
font-variant: normal
|
font-variant: normal
|
||||||
font-weight: 500
|
font-weight: 500
|
||||||
|
.tableContainer
|
||||||
.grid
|
width: 100%
|
||||||
flex: auto
|
height: 100%
|
||||||
align-self: stretch
|
margin-top: 20px
|
||||||
overflow-y: auto
|
|
||||||
overflow-x: auto
|
|
||||||
margin-bottom: 20px
|
margin-bottom: 20px
|
||||||
border: 0
|
border: 0
|
||||||
padding-top: 20px
|
font-size: 12.5px
|
||||||
|
table
|
||||||
.table > thead > tr > th
|
|
||||||
border: 0
|
|
||||||
padding-top: 0
|
|
||||||
padding-bottom: 6px
|
|
||||||
|
|
||||||
.dataTable
|
|
||||||
table-layout: fixed
|
table-layout: fixed
|
||||||
|
width: 100%
|
||||||
.tdLarge
|
thead
|
||||||
font-size: 1.5em
|
> tr
|
||||||
|
> th.username
|
||||||
|
width: auto
|
||||||
|
> th.email
|
||||||
|
width: auto
|
||||||
|
> th.roles
|
||||||
|
width: 260px
|
||||||
|
> th.actions
|
||||||
|
width: 80px
|
||||||
.userRemove
|
.userRemove
|
||||||
color: red
|
color: red
|
||||||
.userEdit
|
.userEdit
|
||||||
|
|||||||
@@ -55,13 +55,13 @@
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
{{> Template.dynamic template=content}}
|
{{> Template.dynamic template=content}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
© Petit Teton LLC 2017
|
© Petit Teton LLC 2017
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!--<template name="Body">-->
|
<!--<template name="Body">-->
|
||||||
|
|||||||
463
imports/util/bootstrap-like-btn.import.styl
vendored
Normal file
463
imports/util/bootstrap-like-btn.import.styl
vendored
Normal file
@@ -0,0 +1,463 @@
|
|||||||
|
.btn
|
||||||
|
display: inline-block
|
||||||
|
padding: 6px 12px
|
||||||
|
margin-bottom: 0
|
||||||
|
font-size: 14px
|
||||||
|
font-weight: normal
|
||||||
|
line-height: 1.42857143
|
||||||
|
text-align: center
|
||||||
|
white-space: nowrap
|
||||||
|
vertical-align: middle
|
||||||
|
-ms-touch-action: manipulation
|
||||||
|
touch-action: manipulation
|
||||||
|
cursor: pointer
|
||||||
|
-webkit-user-select: none
|
||||||
|
-moz-user-select: none
|
||||||
|
-ms-user-select: none
|
||||||
|
user-select: none
|
||||||
|
background-image: none
|
||||||
|
border: 1px solid transparent
|
||||||
|
border-radius: 4px
|
||||||
|
|
||||||
|
.btn:focus,
|
||||||
|
.btn:active:focus,
|
||||||
|
.btn.active:focus,
|
||||||
|
.btn.focus,
|
||||||
|
.btn:active.focus,
|
||||||
|
.btn.active.focus
|
||||||
|
outline: 5px auto -webkit-focus-ring-color
|
||||||
|
outline-offset: -2px
|
||||||
|
|
||||||
|
.btn:hover,
|
||||||
|
.btn:focus,
|
||||||
|
.btn.focus
|
||||||
|
color: #333
|
||||||
|
text-decoration: none
|
||||||
|
|
||||||
|
.btn:active,
|
||||||
|
.btn.active
|
||||||
|
background-image: none
|
||||||
|
outline: 0
|
||||||
|
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125)
|
||||||
|
box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125)
|
||||||
|
.btn.disabled,
|
||||||
|
.btn[disabled],
|
||||||
|
fieldset[disabled] .btn
|
||||||
|
cursor: not-allowed
|
||||||
|
filter: unquote("alpha(opacity=65)")
|
||||||
|
-webkit-box-shadow: none
|
||||||
|
box-shadow: none
|
||||||
|
opacity: .65
|
||||||
|
|
||||||
|
a.btn.disabled,
|
||||||
|
fieldset[disabled] a.btn
|
||||||
|
pointer-events: none
|
||||||
|
|
||||||
|
.btn-default
|
||||||
|
color: #333
|
||||||
|
background-color: #fff
|
||||||
|
border-color: #ccc
|
||||||
|
|
||||||
|
.btn-default:focus,
|
||||||
|
.btn-default.focus
|
||||||
|
color: #333
|
||||||
|
background-color: #e6e6e6
|
||||||
|
border-color: #8c8c8c
|
||||||
|
|
||||||
|
.btn-default:hover
|
||||||
|
color: #333
|
||||||
|
background-color: #e6e6e6
|
||||||
|
border-color: #adadad
|
||||||
|
|
||||||
|
.btn-default:active,
|
||||||
|
.btn-default.active,
|
||||||
|
.open > .dropdown-toggle.btn-default
|
||||||
|
color: #333
|
||||||
|
background-color: #e6e6e6
|
||||||
|
border-color: #adadad
|
||||||
|
|
||||||
|
.btn-default:active:hover,
|
||||||
|
.btn-default.active:hover,
|
||||||
|
.open > .dropdown-toggle.btn-default:hover,
|
||||||
|
.btn-default:active:focus,
|
||||||
|
.btn-default.active:focus,
|
||||||
|
.open > .dropdown-toggle.btn-default:focus,
|
||||||
|
.btn-default:active.focus,
|
||||||
|
.btn-default.active.focus,
|
||||||
|
.open > .dropdown-toggle.btn-default.focus
|
||||||
|
color: #333
|
||||||
|
background-color: #d4d4d4
|
||||||
|
border-color: #8c8c8c
|
||||||
|
|
||||||
|
.btn-default:active,
|
||||||
|
.btn-default.active,
|
||||||
|
.open > .dropdown-toggle.btn-default
|
||||||
|
background-image: none
|
||||||
|
|
||||||
|
.btn-default.disabled:hover,
|
||||||
|
.btn-default[disabled]:hover,
|
||||||
|
fieldset[disabled] .btn-default:hover,
|
||||||
|
.btn-default.disabled:focus,
|
||||||
|
.btn-default[disabled]:focus,
|
||||||
|
fieldset[disabled] .btn-default:focus,
|
||||||
|
.btn-default.disabled.focus,
|
||||||
|
.btn-default[disabled].focus,
|
||||||
|
fieldset[disabled] .btn-default.focus
|
||||||
|
background-color: #fff
|
||||||
|
border-color: #ccc
|
||||||
|
|
||||||
|
.btn-default .badge
|
||||||
|
color: #fff
|
||||||
|
background-color: #333
|
||||||
|
|
||||||
|
.btn-primary
|
||||||
|
color: #fff
|
||||||
|
background-color: #337ab7
|
||||||
|
border-color: #2e6da4
|
||||||
|
|
||||||
|
.btn-primary:focus,
|
||||||
|
.btn-primary.focus
|
||||||
|
color: #fff
|
||||||
|
background-color: #286090
|
||||||
|
border-color: #122b40
|
||||||
|
|
||||||
|
.btn-primary:hover
|
||||||
|
color: #fff
|
||||||
|
background-color: #286090
|
||||||
|
border-color: #204d74
|
||||||
|
|
||||||
|
.btn-primary:active,
|
||||||
|
.btn-primary.active,
|
||||||
|
.open > .dropdown-toggle.btn-primary
|
||||||
|
color: #fff
|
||||||
|
background-color: #286090
|
||||||
|
border-color: #204d74
|
||||||
|
|
||||||
|
.btn-primary:active:hover,
|
||||||
|
.btn-primary.active:hover,
|
||||||
|
.open > .dropdown-toggle.btn-primary:hover,
|
||||||
|
.btn-primary:active:focus,
|
||||||
|
.btn-primary.active:focus,
|
||||||
|
.open > .dropdown-toggle.btn-primary:focus,
|
||||||
|
.btn-primary:active.focus,
|
||||||
|
.btn-primary.active.focus,
|
||||||
|
.open > .dropdown-toggle.btn-primary.focus
|
||||||
|
color: #fff
|
||||||
|
background-color: #204d74
|
||||||
|
border-color: #122b40
|
||||||
|
|
||||||
|
.btn-primary:active,
|
||||||
|
.btn-primary.active,
|
||||||
|
.open > .dropdown-toggle.btn-primary
|
||||||
|
background-image: none
|
||||||
|
|
||||||
|
.btn-primary.disabled:hover,
|
||||||
|
.btn-primary[disabled]:hover,
|
||||||
|
fieldset[disabled] .btn-primary:hover,
|
||||||
|
.btn-primary.disabled:focus,
|
||||||
|
.btn-primary[disabled]:focus,
|
||||||
|
fieldset[disabled] .btn-primary:focus,
|
||||||
|
.btn-primary.disabled.focus,
|
||||||
|
.btn-primary[disabled].focus,
|
||||||
|
fieldset[disabled] .btn-primary.focus
|
||||||
|
background-color: #337ab7
|
||||||
|
border-color: #2e6da4
|
||||||
|
|
||||||
|
.btn-primary .badge
|
||||||
|
color: #337ab7
|
||||||
|
background-color: #fff
|
||||||
|
|
||||||
|
.btn-success
|
||||||
|
color: #fff
|
||||||
|
background-color: #5cb85c
|
||||||
|
border-color: #4cae4c
|
||||||
|
|
||||||
|
.btn-success:focus,
|
||||||
|
.btn-success.focus
|
||||||
|
color: #fff
|
||||||
|
background-color: #449d44
|
||||||
|
border-color: #255625
|
||||||
|
|
||||||
|
.btn-success:hover
|
||||||
|
color: #fff
|
||||||
|
background-color: #449d44
|
||||||
|
border-color: #398439
|
||||||
|
|
||||||
|
.btn-success:active,
|
||||||
|
.btn-success.active,
|
||||||
|
.open > .dropdown-toggle.btn-success
|
||||||
|
color: #fff
|
||||||
|
background-color: #449d44
|
||||||
|
border-color: #398439
|
||||||
|
|
||||||
|
.btn-success:active:hover,
|
||||||
|
.btn-success.active:hover,
|
||||||
|
.open > .dropdown-toggle.btn-success:hover,
|
||||||
|
.btn-success:active:focus,
|
||||||
|
.btn-success.active:focus,
|
||||||
|
.open > .dropdown-toggle.btn-success:focus,
|
||||||
|
.btn-success:active.focus,
|
||||||
|
.btn-success.active.focus,
|
||||||
|
.open > .dropdown-toggle.btn-success.focus
|
||||||
|
color: #fff
|
||||||
|
background-color: #398439
|
||||||
|
border-color: #255625
|
||||||
|
|
||||||
|
.btn-success:active,
|
||||||
|
.btn-success.active,
|
||||||
|
.open > .dropdown-toggle.btn-success
|
||||||
|
background-image: none
|
||||||
|
|
||||||
|
.btn-success.disabled:hover,
|
||||||
|
.btn-success[disabled]:hover,
|
||||||
|
fieldset[disabled] .btn-success:hover,
|
||||||
|
.btn-success.disabled:focus,
|
||||||
|
.btn-success[disabled]:focus,
|
||||||
|
fieldset[disabled] .btn-success:focus,
|
||||||
|
.btn-success.disabled.focus,
|
||||||
|
.btn-success[disabled].focus,
|
||||||
|
fieldset[disabled] .btn-success.focus
|
||||||
|
background-color: #5cb85c
|
||||||
|
border-color: #4cae4c
|
||||||
|
|
||||||
|
.btn-success .badge
|
||||||
|
color: #5cb85c
|
||||||
|
background-color: #fff
|
||||||
|
|
||||||
|
.btn-info
|
||||||
|
color: #fff
|
||||||
|
background-color: #5bc0de
|
||||||
|
border-color: #46b8da
|
||||||
|
|
||||||
|
.btn-info:focus,
|
||||||
|
.btn-info.focus
|
||||||
|
color: #fff
|
||||||
|
background-color: #31b0d5
|
||||||
|
border-color: #1b6d85
|
||||||
|
|
||||||
|
.btn-info:hover
|
||||||
|
color: #fff
|
||||||
|
background-color: #31b0d5
|
||||||
|
border-color: #269abc
|
||||||
|
|
||||||
|
.btn-info:active,
|
||||||
|
.btn-info.active,
|
||||||
|
.open > .dropdown-toggle.btn-info
|
||||||
|
color: #fff
|
||||||
|
background-color: #31b0d5
|
||||||
|
border-color: #269abc
|
||||||
|
|
||||||
|
.btn-info:active:hover,
|
||||||
|
.btn-info.active:hover,
|
||||||
|
.open > .dropdown-toggle.btn-info:hover,
|
||||||
|
.btn-info:active:focus,
|
||||||
|
.btn-info.active:focus,
|
||||||
|
.open > .dropdown-toggle.btn-info:focus,
|
||||||
|
.btn-info:active.focus,
|
||||||
|
.btn-info.active.focus,
|
||||||
|
.open > .dropdown-toggle.btn-info.focus
|
||||||
|
color: #fff
|
||||||
|
background-color: #269abc
|
||||||
|
border-color: #1b6d85
|
||||||
|
|
||||||
|
.btn-info:active,
|
||||||
|
.btn-info.active,
|
||||||
|
.open > .dropdown-toggle.btn-info
|
||||||
|
background-image: none
|
||||||
|
|
||||||
|
.btn-info.disabled:hover,
|
||||||
|
.btn-info[disabled]:hover,
|
||||||
|
fieldset[disabled] .btn-info:hover,
|
||||||
|
.btn-info.disabled:focus,
|
||||||
|
.btn-info[disabled]:focus,
|
||||||
|
fieldset[disabled] .btn-info:focus,
|
||||||
|
.btn-info.disabled.focus,
|
||||||
|
.btn-info[disabled].focus,
|
||||||
|
fieldset[disabled] .btn-info.focus
|
||||||
|
background-color: #5bc0de
|
||||||
|
border-color: #46b8da
|
||||||
|
|
||||||
|
.btn-info .badge
|
||||||
|
color: #5bc0de
|
||||||
|
background-color: #fff
|
||||||
|
|
||||||
|
.btn-warning
|
||||||
|
color: #fff
|
||||||
|
background-color: #f0ad4e
|
||||||
|
border-color: #eea236
|
||||||
|
|
||||||
|
.btn-warning:focus,
|
||||||
|
.btn-warning.focus
|
||||||
|
color: #fff
|
||||||
|
background-color: #ec971f
|
||||||
|
border-color: #985f0d
|
||||||
|
|
||||||
|
.btn-warning:hover
|
||||||
|
color: #fff
|
||||||
|
background-color: #ec971f
|
||||||
|
border-color: #d58512
|
||||||
|
|
||||||
|
.btn-warning:active,
|
||||||
|
.btn-warning.active,
|
||||||
|
.open > .dropdown-toggle.btn-warning
|
||||||
|
color: #fff
|
||||||
|
background-color: #ec971f
|
||||||
|
border-color: #d58512
|
||||||
|
|
||||||
|
.btn-warning:active:hover,
|
||||||
|
.btn-warning.active:hover,
|
||||||
|
.open > .dropdown-toggle.btn-warning:hover,
|
||||||
|
.btn-warning:active:focus,
|
||||||
|
.btn-warning.active:focus,
|
||||||
|
.open > .dropdown-toggle.btn-warning:focus,
|
||||||
|
.btn-warning:active.focus,
|
||||||
|
.btn-warning.active.focus,
|
||||||
|
.open > .dropdown-toggle.btn-warning.focus
|
||||||
|
color: #fff
|
||||||
|
background-color: #d58512
|
||||||
|
border-color: #985f0d
|
||||||
|
|
||||||
|
.btn-warning:active,
|
||||||
|
.btn-warning.active,
|
||||||
|
.open > .dropdown-toggle.btn-warning
|
||||||
|
background-image: none
|
||||||
|
|
||||||
|
.btn-warning.disabled:hover,
|
||||||
|
.btn-warning[disabled]:hover,
|
||||||
|
fieldset[disabled] .btn-warning:hover,
|
||||||
|
.btn-warning.disabled:focus,
|
||||||
|
.btn-warning[disabled]:focus,
|
||||||
|
fieldset[disabled] .btn-warning:focus,
|
||||||
|
.btn-warning.disabled.focus,
|
||||||
|
.btn-warning[disabled].focus,
|
||||||
|
fieldset[disabled] .btn-warning.focus
|
||||||
|
background-color: #f0ad4e
|
||||||
|
border-color: #eea236
|
||||||
|
|
||||||
|
.btn-warning .badge
|
||||||
|
color: #f0ad4e
|
||||||
|
background-color: #fff
|
||||||
|
|
||||||
|
.btn-danger
|
||||||
|
color: #fff
|
||||||
|
background-color: #d9534f
|
||||||
|
border-color: #d43f3a
|
||||||
|
|
||||||
|
.btn-danger:focus,
|
||||||
|
.btn-danger.focus
|
||||||
|
color: #fff
|
||||||
|
background-color: #c9302c
|
||||||
|
border-color: #761c19
|
||||||
|
|
||||||
|
.btn-danger:hover
|
||||||
|
color: #fff
|
||||||
|
background-color: #c9302c
|
||||||
|
border-color: #ac2925
|
||||||
|
|
||||||
|
.btn-danger:active,
|
||||||
|
.btn-danger.active,
|
||||||
|
.open > .dropdown-toggle.btn-danger
|
||||||
|
color: #fff
|
||||||
|
background-color: #c9302c
|
||||||
|
border-color: #ac2925
|
||||||
|
|
||||||
|
.btn-danger:active:hover,
|
||||||
|
.btn-danger.active:hover,
|
||||||
|
.open > .dropdown-toggle.btn-danger:hover,
|
||||||
|
.btn-danger:active:focus,
|
||||||
|
.btn-danger.active:focus,
|
||||||
|
.open > .dropdown-toggle.btn-danger:focus,
|
||||||
|
.btn-danger:active.focus,
|
||||||
|
.btn-danger.active.focus,
|
||||||
|
.open > .dropdown-toggle.btn-danger.focus
|
||||||
|
color: #fff
|
||||||
|
background-color: #ac2925
|
||||||
|
border-color: #761c19
|
||||||
|
|
||||||
|
.btn-danger:active,
|
||||||
|
.btn-danger.active,
|
||||||
|
.open > .dropdown-toggle.btn-danger
|
||||||
|
background-image: none
|
||||||
|
|
||||||
|
.btn-danger.disabled:hover,
|
||||||
|
.btn-danger[disabled]:hover,
|
||||||
|
fieldset[disabled] .btn-danger:hover,
|
||||||
|
.btn-danger.disabled:focus,
|
||||||
|
.btn-danger[disabled]:focus,
|
||||||
|
fieldset[disabled] .btn-danger:focus,
|
||||||
|
.btn-danger.disabled.focus,
|
||||||
|
.btn-danger[disabled].focus,
|
||||||
|
fieldset[disabled] .btn-danger.focus
|
||||||
|
background-color: #d9534f
|
||||||
|
border-color: #d43f3a
|
||||||
|
|
||||||
|
.btn-danger .badge
|
||||||
|
color: #d9534f
|
||||||
|
background-color: #fff
|
||||||
|
|
||||||
|
.btn-link
|
||||||
|
font-weight: normal
|
||||||
|
color: #337ab7
|
||||||
|
border-radius: 0
|
||||||
|
|
||||||
|
.btn-link,
|
||||||
|
.btn-link:active,
|
||||||
|
.btn-link.active,
|
||||||
|
.btn-link[disabled],
|
||||||
|
fieldset[disabled] .btn-link
|
||||||
|
background-color: transparent
|
||||||
|
-webkit-box-shadow: none
|
||||||
|
box-shadow: none
|
||||||
|
|
||||||
|
.btn-link,
|
||||||
|
.btn-link:hover,
|
||||||
|
.btn-link:focus,
|
||||||
|
.btn-link:active
|
||||||
|
border-color: transparent
|
||||||
|
|
||||||
|
.btn-link:hover,
|
||||||
|
.btn-link:focus
|
||||||
|
color: #23527c
|
||||||
|
text-decoration: underline
|
||||||
|
background-color: transparent
|
||||||
|
|
||||||
|
.btn-link[disabled]:hover,
|
||||||
|
fieldset[disabled] .btn-link:hover,
|
||||||
|
.btn-link[disabled]:focus,
|
||||||
|
fieldset[disabled] .btn-link:focus
|
||||||
|
color: #777
|
||||||
|
text-decoration: none
|
||||||
|
|
||||||
|
.btn-lg,
|
||||||
|
.btn-group-lg > .btn
|
||||||
|
padding: 10px 16px
|
||||||
|
font-size: 18px
|
||||||
|
line-height: 1.3333333
|
||||||
|
border-radius: 6px
|
||||||
|
|
||||||
|
.btn-sm,
|
||||||
|
.btn-group-sm > .btn
|
||||||
|
padding: 5px 10px
|
||||||
|
font-size: 12px
|
||||||
|
line-height: 1.5
|
||||||
|
border-radius: 3px
|
||||||
|
|
||||||
|
.btn-xs,
|
||||||
|
.btn-group-xs > .btn
|
||||||
|
padding: 1px 5px
|
||||||
|
font-size: 12px
|
||||||
|
line-height: 1.5
|
||||||
|
border-radius: 3px
|
||||||
|
|
||||||
|
.btn-block
|
||||||
|
display: block
|
||||||
|
width: 100%
|
||||||
|
|
||||||
|
.btn-block + .btn-block
|
||||||
|
margin-top: 5px
|
||||||
|
|
||||||
|
input[type="submit"].btn-block,
|
||||||
|
input[type="reset"].btn-block,
|
||||||
|
input[type="button"].btn-block
|
||||||
|
width: 100%
|
||||||
|
|
||||||
@@ -130,10 +130,11 @@
|
|||||||
// data: The item or array of items to add. This will be the root tree elements if groupFunctions is provided.
|
// data: The item or array of items to add. This will be the root tree elements if groupFunctions is provided.
|
||||||
function add(data) {
|
function add(data) {
|
||||||
let groupFunctions = _this.options.groupFunctions;
|
let groupFunctions = _this.options.groupFunctions;
|
||||||
|
let getClasses = _this.options.getClasses;
|
||||||
|
|
||||||
let addOne = function(data, parent) { //role is optional.
|
let addOne = function(data, parent) { //role is optional.
|
||||||
let text = $.isFunction(_this.options.textAttr) ? _this.options.textAttr(data) : data[_this.options.textAttr];
|
let text = $.isFunction(_this.options.textAttr) ? _this.options.textAttr(data) : data[_this.options.textAttr];
|
||||||
let li = $("<li" + (parent ? " role='leaf'" : "") + ">" + text + "</li>");
|
let li = $("<li" + (parent ? " role='leaf'" : "") + (getClasses ? " class='" + getClasses(data) + "'" : "") + ">" + text + "</li>");
|
||||||
|
|
||||||
li.appendTo(_this.$list);
|
li.appendTo(_this.$list);
|
||||||
li.data('model', data);
|
li.data('model', data);
|
||||||
@@ -214,7 +215,8 @@
|
|||||||
effects: 'fade',
|
effects: 'fade',
|
||||||
duration: '200',
|
duration: '200',
|
||||||
listClass: 'de.combo-list',
|
listClass: 'de.combo-list',
|
||||||
selectionClass: 'selected' //The class to use for the selected element in the dropdown list.
|
selectionClass: 'selected', //The class to use for the selected element in the dropdown list.
|
||||||
|
getClasses: undefined //An optional function that will return a string to use in the list item's class attribute to style the list item for a given model data. The function will be passed the data object for the list item.
|
||||||
};
|
};
|
||||||
|
|
||||||
Combo.prototype.select = function($li) {
|
Combo.prototype.select = function($li) {
|
||||||
|
|||||||
508
imports/util/normalize.css
vendored
Normal file
508
imports/util/normalize.css
vendored
Normal file
@@ -0,0 +1,508 @@
|
|||||||
|
/*! normalize.css 2012-03-11T12:53 UTC - http://github.com/necolas/normalize.css */
|
||||||
|
|
||||||
|
/* =============================================================================
|
||||||
|
HTML5 display definitions
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Corrects block display not defined in IE6/7/8/9 & FF3
|
||||||
|
*/
|
||||||
|
|
||||||
|
article,
|
||||||
|
aside,
|
||||||
|
details,
|
||||||
|
figcaption,
|
||||||
|
figure,
|
||||||
|
footer,
|
||||||
|
header,
|
||||||
|
hgroup,
|
||||||
|
nav,
|
||||||
|
section,
|
||||||
|
summary {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Corrects inline-block display not defined in IE6/7/8/9 & FF3
|
||||||
|
*/
|
||||||
|
|
||||||
|
audio,
|
||||||
|
canvas,
|
||||||
|
video {
|
||||||
|
display: inline-block;
|
||||||
|
*display: inline;
|
||||||
|
*zoom: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prevents modern browsers from displaying 'audio' without controls
|
||||||
|
* Remove excess height in iOS5 devices
|
||||||
|
*/
|
||||||
|
|
||||||
|
audio:not([controls]) {
|
||||||
|
display: none;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Addresses styling for 'hidden' attribute not present in IE7/8/9, FF3, S4
|
||||||
|
* Known issue: no IE6 support
|
||||||
|
*/
|
||||||
|
|
||||||
|
[hidden] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* =============================================================================
|
||||||
|
Base
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 1. Corrects text resizing oddly in IE6/7 when body font-size is set using em units
|
||||||
|
* http://clagnut.com/blog/348/#c790
|
||||||
|
* 2. Prevents iOS text size adjust after orientation change, without disabling user zoom
|
||||||
|
* www.456bereastreet.com/archive/201012/controlling_text_size_in_safari_for_ios_without_disabling_user_zoom/
|
||||||
|
*/
|
||||||
|
|
||||||
|
html {
|
||||||
|
font-size: 100%; /* 1 */
|
||||||
|
-webkit-text-size-adjust: 100%; /* 2 */
|
||||||
|
-ms-text-size-adjust: 100%; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Addresses font-family inconsistency between 'textarea' and other form elements.
|
||||||
|
*/
|
||||||
|
|
||||||
|
html,
|
||||||
|
button,
|
||||||
|
input,
|
||||||
|
select,
|
||||||
|
textarea {
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Addresses margins handled incorrectly in IE6/7
|
||||||
|
*/
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* =============================================================================
|
||||||
|
Links
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Addresses outline displayed oddly in Chrome
|
||||||
|
*/
|
||||||
|
|
||||||
|
a:focus {
|
||||||
|
outline: thin dotted;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Improves readability when focused and also mouse hovered in all browsers
|
||||||
|
* people.opera.com/patrickl/experiments/keyboard/test
|
||||||
|
*/
|
||||||
|
|
||||||
|
a:hover,
|
||||||
|
a:active {
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* =============================================================================
|
||||||
|
Typography
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Addresses font sizes and margins set differently in IE6/7
|
||||||
|
* Addresses font sizes within 'section' and 'article' in FF4+, Chrome, S5
|
||||||
|
*/
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 2em;
|
||||||
|
margin: 0.67em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 1.5em;
|
||||||
|
margin: 0.83em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 1.17em;
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: 1em;
|
||||||
|
margin: 1.33em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h5 {
|
||||||
|
font-size: 0.83em;
|
||||||
|
margin: 1.67em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h6 {
|
||||||
|
font-size: 0.75em;
|
||||||
|
margin: 2.33em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Addresses styling not present in IE7/8/9, S5, Chrome
|
||||||
|
*/
|
||||||
|
|
||||||
|
abbr[title] {
|
||||||
|
border-bottom: 1px dotted;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Addresses style set to 'bolder' in FF3+, S4/5, Chrome
|
||||||
|
*/
|
||||||
|
|
||||||
|
b,
|
||||||
|
strong {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
margin: 1em 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Addresses styling not present in S5, Chrome
|
||||||
|
*/
|
||||||
|
|
||||||
|
dfn {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Addresses styling not present in IE6/7/8/9
|
||||||
|
*/
|
||||||
|
|
||||||
|
mark {
|
||||||
|
background: #ff0;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Addresses margins set differently in IE6/7
|
||||||
|
*/
|
||||||
|
|
||||||
|
p,
|
||||||
|
pre {
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Corrects font family set oddly in IE6, S4/5, Chrome
|
||||||
|
* en.wikipedia.org/wiki/User:Davidgothberg/Test59
|
||||||
|
*/
|
||||||
|
|
||||||
|
pre,
|
||||||
|
code,
|
||||||
|
kbd,
|
||||||
|
samp {
|
||||||
|
font-family: monospace, serif;
|
||||||
|
_font-family: 'courier new', monospace;
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Improves readability of pre-formatted text in all browsers
|
||||||
|
*/
|
||||||
|
|
||||||
|
pre {
|
||||||
|
white-space: pre;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 1. Addresses CSS quotes not supported in IE6/7
|
||||||
|
* 2. Addresses quote property not supported in S4
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* 1 */
|
||||||
|
|
||||||
|
q {
|
||||||
|
quotes: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 2 */
|
||||||
|
|
||||||
|
q:before,
|
||||||
|
q:after {
|
||||||
|
content: '';
|
||||||
|
content: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
small {
|
||||||
|
font-size: 75%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prevents sub and sup affecting line-height in all browsers
|
||||||
|
* gist.github.com/413930
|
||||||
|
*/
|
||||||
|
|
||||||
|
sub,
|
||||||
|
sup {
|
||||||
|
font-size: 75%;
|
||||||
|
line-height: 0;
|
||||||
|
position: relative;
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
sup {
|
||||||
|
top: -0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub {
|
||||||
|
bottom: -0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* =============================================================================
|
||||||
|
Lists
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Addresses margins set differently in IE6/7
|
||||||
|
*/
|
||||||
|
|
||||||
|
dl,
|
||||||
|
menu,
|
||||||
|
ol,
|
||||||
|
ul {
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dd {
|
||||||
|
margin: 0 0 0 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Addresses paddings set differently in IE6/7
|
||||||
|
*/
|
||||||
|
|
||||||
|
menu,
|
||||||
|
ol,
|
||||||
|
ul {
|
||||||
|
padding: 0 0 0 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Corrects list images handled incorrectly in IE7
|
||||||
|
*/
|
||||||
|
|
||||||
|
nav ul,
|
||||||
|
nav ol {
|
||||||
|
list-style: none;
|
||||||
|
list-style-image: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* =============================================================================
|
||||||
|
Embedded content
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 1. Removes border when inside 'a' element in IE6/7/8/9, FF3
|
||||||
|
* 2. Improves image quality when scaled in IE7
|
||||||
|
* code.flickr.com/blog/2008/11/12/on-ui-quality-the-little-things-client-side-image-resizing/
|
||||||
|
*/
|
||||||
|
|
||||||
|
img {
|
||||||
|
border: 0; /* 1 */
|
||||||
|
-ms-interpolation-mode: bicubic; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Corrects overflow displayed oddly in IE9
|
||||||
|
*/
|
||||||
|
|
||||||
|
svg:not(:root) {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* =============================================================================
|
||||||
|
Figures
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Addresses margin not present in IE6/7/8/9, S5, O11
|
||||||
|
*/
|
||||||
|
|
||||||
|
figure {
|
||||||
|
margin: 0;
|
||||||
|
-webkit-margin-before: 0;
|
||||||
|
-webkit-margin-after: 0;
|
||||||
|
-webkit-margin-start: 0;
|
||||||
|
-webkit-margin-end: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* =============================================================================
|
||||||
|
Forms
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Corrects margin displayed oddly in IE6/7
|
||||||
|
*/
|
||||||
|
|
||||||
|
form {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define consistent border, margin, and padding
|
||||||
|
*/
|
||||||
|
|
||||||
|
fieldset {
|
||||||
|
border: 1px solid #c0c0c0;
|
||||||
|
margin: 0 2px;
|
||||||
|
padding: 0.35em 0.625em 0.75em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 1. Corrects color not being inherited in IE6/7/8/9
|
||||||
|
* 2. Corrects text not wrapping in FF3
|
||||||
|
* 3. Corrects alignment displayed oddly in IE6/7
|
||||||
|
*/
|
||||||
|
|
||||||
|
legend {
|
||||||
|
border: 0; /* 1 */
|
||||||
|
padding: 0;
|
||||||
|
white-space: normal; /* 2 */
|
||||||
|
*margin-left: -7px; /* 3 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 1. Corrects font size not being inherited in all browsers
|
||||||
|
* 2. Addresses margins set differently in IE6/7, FF3+, S5, Chrome
|
||||||
|
* 3. Improves appearance and consistency in all browsers
|
||||||
|
*/
|
||||||
|
|
||||||
|
button,
|
||||||
|
input,
|
||||||
|
select,
|
||||||
|
textarea {
|
||||||
|
font-size: 100%; /* 1 */
|
||||||
|
margin: 0; /* 2 */
|
||||||
|
vertical-align: baseline; /* 3 */
|
||||||
|
*vertical-align: middle; /* 3 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Addresses FF3/4 setting line-height on 'input' using !important in the UA stylesheet
|
||||||
|
*/
|
||||||
|
|
||||||
|
button,
|
||||||
|
input {
|
||||||
|
line-height: normal; /* 1 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 1. Improves usability and consistency of cursor style between image-type 'input' and others
|
||||||
|
* 2. Corrects inability to style clickable 'input' types in iOS
|
||||||
|
* 3. Removes inner spacing in IE7 without affecting normal text inputs
|
||||||
|
* Known issue: inner spacing remains in IE6
|
||||||
|
*/
|
||||||
|
|
||||||
|
button,
|
||||||
|
input[type="button"],
|
||||||
|
input[type="reset"],
|
||||||
|
input[type="submit"] {
|
||||||
|
cursor: pointer; /* 1 */
|
||||||
|
-webkit-appearance: button; /* 2 */
|
||||||
|
*overflow: visible; /* 3 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Re-set default cursor for disabled elements
|
||||||
|
*/
|
||||||
|
|
||||||
|
button[disabled],
|
||||||
|
input[disabled] {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 1. Addresses box sizing set to content-box in IE8/9
|
||||||
|
* 2. Removes excess padding in IE8/9
|
||||||
|
* 3. Removes excess padding in IE7
|
||||||
|
Known issue: excess padding remains in IE6
|
||||||
|
*/
|
||||||
|
|
||||||
|
input[type="checkbox"],
|
||||||
|
input[type="radio"] {
|
||||||
|
box-sizing: border-box; /* 1 */
|
||||||
|
padding: 0; /* 2 */
|
||||||
|
*height: 13px; /* 3 */
|
||||||
|
*width: 13px; /* 3 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 1. Addresses appearance set to searchfield in S5, Chrome
|
||||||
|
* 2. Addresses box-sizing set to border-box in S5, Chrome (include -moz to future-proof)
|
||||||
|
*/
|
||||||
|
|
||||||
|
input[type="search"] {
|
||||||
|
-webkit-appearance: textfield; /* 1 */
|
||||||
|
-moz-box-sizing: content-box;
|
||||||
|
-webkit-box-sizing: content-box; /* 2 */
|
||||||
|
box-sizing: content-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Removes inner padding and search cancel button in S5, Chrome on OS X
|
||||||
|
*/
|
||||||
|
|
||||||
|
input[type="search"]::-webkit-search-decoration,
|
||||||
|
input[type="search"]::-webkit-search-cancel-button {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Removes inner padding and border in FF3+
|
||||||
|
* www.sitepen.com/blog/2008/05/14/the-devils-in-the-details-fixing-dojos-toolbar-buttons/
|
||||||
|
*/
|
||||||
|
|
||||||
|
button::-moz-focus-inner,
|
||||||
|
input::-moz-focus-inner {
|
||||||
|
border: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 1. Removes default vertical scrollbar in IE6/7/8/9
|
||||||
|
* 2. Improves readability and alignment in all browsers
|
||||||
|
*/
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
overflow: auto; /* 1 */
|
||||||
|
vertical-align: top; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* =============================================================================
|
||||||
|
Tables
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove most spacing between table cells
|
||||||
|
*/
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-spacing: 0;
|
||||||
|
}
|
||||||
48
imports/util/polyfills/array.js
Normal file
48
imports/util/polyfills/array.js
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
// https://tc39.github.io/ecma262/#sec-array.prototype.includes
|
||||||
|
if (!Array.prototype.includes) {
|
||||||
|
Object.defineProperty(Array.prototype, 'includes', {
|
||||||
|
value: function(searchElement, fromIndex) {
|
||||||
|
|
||||||
|
// 1. Let O be ? ToObject(this value).
|
||||||
|
if (this == null) {
|
||||||
|
throw new TypeError('"this" is null or not defined');
|
||||||
|
}
|
||||||
|
|
||||||
|
var o = Object(this);
|
||||||
|
|
||||||
|
// 2. Let len be ? ToLength(? Get(O, "length")).
|
||||||
|
var len = o.length >>> 0;
|
||||||
|
|
||||||
|
// 3. If len is 0, return false.
|
||||||
|
if (len === 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Let n be ? ToInteger(fromIndex).
|
||||||
|
// (If fromIndex is undefined, this step produces the value 0.)
|
||||||
|
var n = fromIndex | 0;
|
||||||
|
|
||||||
|
// 5. If n ≥ 0, then
|
||||||
|
// a. Let k be n.
|
||||||
|
// 6. Else n < 0,
|
||||||
|
// a. Let k be len + n.
|
||||||
|
// b. If k < 0, let k be 0.
|
||||||
|
var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
|
||||||
|
|
||||||
|
// 7. Repeat, while k < len
|
||||||
|
while (k < len) {
|
||||||
|
// a. Let elementK be the result of ? Get(O, ! ToString(k)).
|
||||||
|
// b. If SameValueZero(searchElement, elementK) is true, return true.
|
||||||
|
// c. Increase k by 1.
|
||||||
|
// NOTE: === provides the correct "SameValueZero" comparison needed here.
|
||||||
|
if (o[k] === searchElement) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 8. Return false
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
484
imports/util/select2/select2.css
vendored
Normal file
484
imports/util/select2/select2.css
vendored
Normal file
@@ -0,0 +1,484 @@
|
|||||||
|
.select2-container {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0;
|
||||||
|
position: relative;
|
||||||
|
vertical-align: middle; }
|
||||||
|
.select2-container .select2-selection--single {
|
||||||
|
box-sizing: border-box;
|
||||||
|
cursor: pointer;
|
||||||
|
display: block;
|
||||||
|
height: 28px;
|
||||||
|
user-select: none;
|
||||||
|
-webkit-user-select: none; }
|
||||||
|
.select2-container .select2-selection--single .select2-selection__rendered {
|
||||||
|
display: block;
|
||||||
|
padding-left: 8px;
|
||||||
|
padding-right: 20px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap; }
|
||||||
|
.select2-container .select2-selection--single .select2-selection__clear {
|
||||||
|
position: relative; }
|
||||||
|
.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered {
|
||||||
|
padding-right: 8px;
|
||||||
|
padding-left: 20px; }
|
||||||
|
.select2-container .select2-selection--multiple {
|
||||||
|
box-sizing: border-box;
|
||||||
|
cursor: pointer;
|
||||||
|
display: block;
|
||||||
|
min-height: 32px;
|
||||||
|
user-select: none;
|
||||||
|
-webkit-user-select: none; }
|
||||||
|
.select2-container .select2-selection--multiple .select2-selection__rendered {
|
||||||
|
display: inline-block;
|
||||||
|
overflow: hidden;
|
||||||
|
padding-left: 8px;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap; }
|
||||||
|
.select2-container .select2-search--inline {
|
||||||
|
float: left; }
|
||||||
|
.select2-container .select2-search--inline .select2-search__field {
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: none;
|
||||||
|
font-size: 100%;
|
||||||
|
margin-top: 5px;
|
||||||
|
padding: 0; }
|
||||||
|
.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button {
|
||||||
|
-webkit-appearance: none; }
|
||||||
|
|
||||||
|
.select2-dropdown {
|
||||||
|
background-color: white;
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
left: -100000px;
|
||||||
|
width: 100%;
|
||||||
|
z-index: 1051; }
|
||||||
|
|
||||||
|
.select2-results {
|
||||||
|
display: block; }
|
||||||
|
|
||||||
|
.select2-results__options {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0; }
|
||||||
|
|
||||||
|
.select2-results__option {
|
||||||
|
padding: 6px;
|
||||||
|
user-select: none;
|
||||||
|
-webkit-user-select: none; }
|
||||||
|
.select2-results__option[aria-selected] {
|
||||||
|
cursor: pointer; }
|
||||||
|
|
||||||
|
.select2-container--open .select2-dropdown {
|
||||||
|
left: 0; }
|
||||||
|
|
||||||
|
.select2-container--open .select2-dropdown--above {
|
||||||
|
border-bottom: none;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
border-bottom-right-radius: 0; }
|
||||||
|
|
||||||
|
.select2-container--open .select2-dropdown--below {
|
||||||
|
border-top: none;
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-top-right-radius: 0; }
|
||||||
|
|
||||||
|
.select2-search--dropdown {
|
||||||
|
display: block;
|
||||||
|
padding: 4px; }
|
||||||
|
.select2-search--dropdown .select2-search__field {
|
||||||
|
padding: 4px;
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box; }
|
||||||
|
.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button {
|
||||||
|
-webkit-appearance: none; }
|
||||||
|
.select2-search--dropdown.select2-search--hide {
|
||||||
|
display: none; }
|
||||||
|
|
||||||
|
.select2-close-mask {
|
||||||
|
border: 0;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
display: block;
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
min-height: 100%;
|
||||||
|
min-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
width: auto;
|
||||||
|
opacity: 0;
|
||||||
|
z-index: 99;
|
||||||
|
background-color: #fff;
|
||||||
|
filter: alpha(opacity=0); }
|
||||||
|
|
||||||
|
.select2-hidden-accessible {
|
||||||
|
border: 0 !important;
|
||||||
|
clip: rect(0 0 0 0) !important;
|
||||||
|
height: 1px !important;
|
||||||
|
margin: -1px !important;
|
||||||
|
overflow: hidden !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
position: absolute !important;
|
||||||
|
width: 1px !important; }
|
||||||
|
|
||||||
|
.select2-container--default .select2-selection--single {
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
border-radius: 4px; }
|
||||||
|
.select2-container--default .select2-selection--single .select2-selection__rendered {
|
||||||
|
color: #444;
|
||||||
|
line-height: 28px; }
|
||||||
|
.select2-container--default .select2-selection--single .select2-selection__clear {
|
||||||
|
cursor: pointer;
|
||||||
|
float: right;
|
||||||
|
font-weight: bold; }
|
||||||
|
.select2-container--default .select2-selection--single .select2-selection__placeholder {
|
||||||
|
color: #999; }
|
||||||
|
.select2-container--default .select2-selection--single .select2-selection__arrow {
|
||||||
|
height: 26px;
|
||||||
|
position: absolute;
|
||||||
|
top: 1px;
|
||||||
|
right: 1px;
|
||||||
|
width: 20px; }
|
||||||
|
.select2-container--default .select2-selection--single .select2-selection__arrow b {
|
||||||
|
border-color: #888 transparent transparent transparent;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 5px 4px 0 4px;
|
||||||
|
height: 0;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -4px;
|
||||||
|
margin-top: -2px;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
width: 0; }
|
||||||
|
|
||||||
|
.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear {
|
||||||
|
float: left; }
|
||||||
|
|
||||||
|
.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow {
|
||||||
|
left: 1px;
|
||||||
|
right: auto; }
|
||||||
|
|
||||||
|
.select2-container--default.select2-container--disabled .select2-selection--single {
|
||||||
|
background-color: #eee;
|
||||||
|
cursor: default; }
|
||||||
|
.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear {
|
||||||
|
display: none; }
|
||||||
|
|
||||||
|
.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b {
|
||||||
|
border-color: transparent transparent #888 transparent;
|
||||||
|
border-width: 0 4px 5px 4px; }
|
||||||
|
|
||||||
|
.select2-container--default .select2-selection--multiple {
|
||||||
|
background-color: white;
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: text; }
|
||||||
|
.select2-container--default .select2-selection--multiple .select2-selection__rendered {
|
||||||
|
box-sizing: border-box;
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 5px;
|
||||||
|
width: 100%; }
|
||||||
|
.select2-container--default .select2-selection--multiple .select2-selection__rendered li {
|
||||||
|
list-style: none; }
|
||||||
|
.select2-container--default .select2-selection--multiple .select2-selection__placeholder {
|
||||||
|
color: #999;
|
||||||
|
margin-top: 5px;
|
||||||
|
float: left; }
|
||||||
|
.select2-container--default .select2-selection--multiple .select2-selection__clear {
|
||||||
|
cursor: pointer;
|
||||||
|
float: right;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-top: 5px;
|
||||||
|
margin-right: 10px; }
|
||||||
|
.select2-container--default .select2-selection--multiple .select2-selection__choice {
|
||||||
|
background-color: #e4e4e4;
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: default;
|
||||||
|
float: left;
|
||||||
|
margin-right: 5px;
|
||||||
|
margin-top: 5px;
|
||||||
|
padding: 0 5px; }
|
||||||
|
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
|
||||||
|
color: #999;
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-right: 2px; }
|
||||||
|
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover {
|
||||||
|
color: #333; }
|
||||||
|
|
||||||
|
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline {
|
||||||
|
float: right; }
|
||||||
|
|
||||||
|
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
|
||||||
|
margin-left: 5px;
|
||||||
|
margin-right: auto; }
|
||||||
|
|
||||||
|
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
|
||||||
|
margin-left: 2px;
|
||||||
|
margin-right: auto; }
|
||||||
|
|
||||||
|
.select2-container--default.select2-container--focus .select2-selection--multiple {
|
||||||
|
border: solid black 1px;
|
||||||
|
outline: 0; }
|
||||||
|
|
||||||
|
.select2-container--default.select2-container--disabled .select2-selection--multiple {
|
||||||
|
background-color: #eee;
|
||||||
|
cursor: default; }
|
||||||
|
|
||||||
|
.select2-container--default.select2-container--disabled .select2-selection__choice__remove {
|
||||||
|
display: none; }
|
||||||
|
|
||||||
|
.select2-container--default.select2-container--open.select2-container--above .select2-selection--single, .select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple {
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-top-right-radius: 0; }
|
||||||
|
|
||||||
|
.select2-container--default.select2-container--open.select2-container--below .select2-selection--single, .select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple {
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
border-bottom-right-radius: 0; }
|
||||||
|
|
||||||
|
.select2-container--default .select2-search--dropdown .select2-search__field {
|
||||||
|
border: 1px solid #aaa; }
|
||||||
|
|
||||||
|
.select2-container--default .select2-search--inline .select2-search__field {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
outline: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
-webkit-appearance: textfield; }
|
||||||
|
|
||||||
|
.select2-container--default .select2-results > .select2-results__options {
|
||||||
|
max-height: 200px;
|
||||||
|
overflow-y: auto; }
|
||||||
|
|
||||||
|
.select2-container--default .select2-results__option[role=group] {
|
||||||
|
padding: 0; }
|
||||||
|
|
||||||
|
.select2-container--default .select2-results__option[aria-disabled=true] {
|
||||||
|
color: #999; }
|
||||||
|
|
||||||
|
.select2-container--default .select2-results__option[aria-selected=true] {
|
||||||
|
background-color: #ddd; }
|
||||||
|
|
||||||
|
.select2-container--default .select2-results__option .select2-results__option {
|
||||||
|
padding-left: 1em; }
|
||||||
|
.select2-container--default .select2-results__option .select2-results__option .select2-results__group {
|
||||||
|
padding-left: 0; }
|
||||||
|
.select2-container--default .select2-results__option .select2-results__option .select2-results__option {
|
||||||
|
margin-left: -1em;
|
||||||
|
padding-left: 2em; }
|
||||||
|
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
|
||||||
|
margin-left: -2em;
|
||||||
|
padding-left: 3em; }
|
||||||
|
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
|
||||||
|
margin-left: -3em;
|
||||||
|
padding-left: 4em; }
|
||||||
|
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
|
||||||
|
margin-left: -4em;
|
||||||
|
padding-left: 5em; }
|
||||||
|
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
|
||||||
|
margin-left: -5em;
|
||||||
|
padding-left: 6em; }
|
||||||
|
|
||||||
|
.select2-container--default .select2-results__option--highlighted[aria-selected] {
|
||||||
|
background-color: #5897fb;
|
||||||
|
color: white; }
|
||||||
|
|
||||||
|
.select2-container--default .select2-results__group {
|
||||||
|
cursor: default;
|
||||||
|
display: block;
|
||||||
|
padding: 6px; }
|
||||||
|
|
||||||
|
.select2-container--classic .select2-selection--single {
|
||||||
|
background-color: #f7f7f7;
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
border-radius: 4px;
|
||||||
|
outline: 0;
|
||||||
|
background-image: -webkit-linear-gradient(top, white 50%, #eeeeee 100%);
|
||||||
|
background-image: -o-linear-gradient(top, white 50%, #eeeeee 100%);
|
||||||
|
background-image: linear-gradient(to bottom, white 50%, #eeeeee 100%);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }
|
||||||
|
.select2-container--classic .select2-selection--single:focus {
|
||||||
|
border: 1px solid #5897fb; }
|
||||||
|
.select2-container--classic .select2-selection--single .select2-selection__rendered {
|
||||||
|
color: #444;
|
||||||
|
line-height: 28px; }
|
||||||
|
.select2-container--classic .select2-selection--single .select2-selection__clear {
|
||||||
|
cursor: pointer;
|
||||||
|
float: right;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-right: 10px; }
|
||||||
|
.select2-container--classic .select2-selection--single .select2-selection__placeholder {
|
||||||
|
color: #999; }
|
||||||
|
.select2-container--classic .select2-selection--single .select2-selection__arrow {
|
||||||
|
background-color: #ddd;
|
||||||
|
border: none;
|
||||||
|
border-left: 1px solid #aaa;
|
||||||
|
border-top-right-radius: 4px;
|
||||||
|
border-bottom-right-radius: 4px;
|
||||||
|
height: 26px;
|
||||||
|
position: absolute;
|
||||||
|
top: 1px;
|
||||||
|
right: 1px;
|
||||||
|
width: 20px;
|
||||||
|
background-image: -webkit-linear-gradient(top, #eeeeee 50%, #cccccc 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #eeeeee 50%, #cccccc 100%);
|
||||||
|
background-image: linear-gradient(to bottom, #eeeeee 50%, #cccccc 100%);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0); }
|
||||||
|
.select2-container--classic .select2-selection--single .select2-selection__arrow b {
|
||||||
|
border-color: #888 transparent transparent transparent;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 5px 4px 0 4px;
|
||||||
|
height: 0;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -4px;
|
||||||
|
margin-top: -2px;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
width: 0; }
|
||||||
|
|
||||||
|
.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear {
|
||||||
|
float: left; }
|
||||||
|
|
||||||
|
.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow {
|
||||||
|
border: none;
|
||||||
|
border-right: 1px solid #aaa;
|
||||||
|
border-radius: 0;
|
||||||
|
border-top-left-radius: 4px;
|
||||||
|
border-bottom-left-radius: 4px;
|
||||||
|
left: 1px;
|
||||||
|
right: auto; }
|
||||||
|
|
||||||
|
.select2-container--classic.select2-container--open .select2-selection--single {
|
||||||
|
border: 1px solid #5897fb; }
|
||||||
|
.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow {
|
||||||
|
background: transparent;
|
||||||
|
border: none; }
|
||||||
|
.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b {
|
||||||
|
border-color: transparent transparent #888 transparent;
|
||||||
|
border-width: 0 4px 5px 4px; }
|
||||||
|
|
||||||
|
.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single {
|
||||||
|
border-top: none;
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
background-image: -webkit-linear-gradient(top, white 0%, #eeeeee 50%);
|
||||||
|
background-image: -o-linear-gradient(top, white 0%, #eeeeee 50%);
|
||||||
|
background-image: linear-gradient(to bottom, white 0%, #eeeeee 50%);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }
|
||||||
|
|
||||||
|
.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single {
|
||||||
|
border-bottom: none;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
background-image: -webkit-linear-gradient(top, #eeeeee 50%, white 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #eeeeee 50%, white 100%);
|
||||||
|
background-image: linear-gradient(to bottom, #eeeeee 50%, white 100%);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0); }
|
||||||
|
|
||||||
|
.select2-container--classic .select2-selection--multiple {
|
||||||
|
background-color: white;
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: text;
|
||||||
|
outline: 0; }
|
||||||
|
.select2-container--classic .select2-selection--multiple:focus {
|
||||||
|
border: 1px solid #5897fb; }
|
||||||
|
.select2-container--classic .select2-selection--multiple .select2-selection__rendered {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 5px; }
|
||||||
|
.select2-container--classic .select2-selection--multiple .select2-selection__clear {
|
||||||
|
display: none; }
|
||||||
|
.select2-container--classic .select2-selection--multiple .select2-selection__choice {
|
||||||
|
background-color: #e4e4e4;
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: default;
|
||||||
|
float: left;
|
||||||
|
margin-right: 5px;
|
||||||
|
margin-top: 5px;
|
||||||
|
padding: 0 5px; }
|
||||||
|
.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove {
|
||||||
|
color: #888;
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-right: 2px; }
|
||||||
|
.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover {
|
||||||
|
color: #555; }
|
||||||
|
|
||||||
|
.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
|
||||||
|
float: right; }
|
||||||
|
|
||||||
|
.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
|
||||||
|
margin-left: 5px;
|
||||||
|
margin-right: auto; }
|
||||||
|
|
||||||
|
.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
|
||||||
|
margin-left: 2px;
|
||||||
|
margin-right: auto; }
|
||||||
|
|
||||||
|
.select2-container--classic.select2-container--open .select2-selection--multiple {
|
||||||
|
border: 1px solid #5897fb; }
|
||||||
|
|
||||||
|
.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple {
|
||||||
|
border-top: none;
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-top-right-radius: 0; }
|
||||||
|
|
||||||
|
.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple {
|
||||||
|
border-bottom: none;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
border-bottom-right-radius: 0; }
|
||||||
|
|
||||||
|
.select2-container--classic .select2-search--dropdown .select2-search__field {
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
outline: 0; }
|
||||||
|
|
||||||
|
.select2-container--classic .select2-search--inline .select2-search__field {
|
||||||
|
outline: 0;
|
||||||
|
box-shadow: none; }
|
||||||
|
|
||||||
|
.select2-container--classic .select2-dropdown {
|
||||||
|
background-color: white;
|
||||||
|
border: 1px solid transparent; }
|
||||||
|
|
||||||
|
.select2-container--classic .select2-dropdown--above {
|
||||||
|
border-bottom: none; }
|
||||||
|
|
||||||
|
.select2-container--classic .select2-dropdown--below {
|
||||||
|
border-top: none; }
|
||||||
|
|
||||||
|
.select2-container--classic .select2-results > .select2-results__options {
|
||||||
|
max-height: 200px;
|
||||||
|
overflow-y: auto; }
|
||||||
|
|
||||||
|
.select2-container--classic .select2-results__option[role=group] {
|
||||||
|
padding: 0; }
|
||||||
|
|
||||||
|
.select2-container--classic .select2-results__option[aria-disabled=true] {
|
||||||
|
color: grey; }
|
||||||
|
|
||||||
|
.select2-container--classic .select2-results__option--highlighted[aria-selected] {
|
||||||
|
background-color: #3875d7;
|
||||||
|
color: white; }
|
||||||
|
|
||||||
|
.select2-container--classic .select2-results__group {
|
||||||
|
cursor: default;
|
||||||
|
display: block;
|
||||||
|
padding: 6px; }
|
||||||
|
|
||||||
|
.select2-container--classic.select2-container--open .select2-dropdown {
|
||||||
|
border-color: #5897fb; }
|
||||||
6436
imports/util/select2/select2.full.js
vendored
Normal file
6436
imports/util/select2/select2.full.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
5725
imports/util/select2/select2.js
vendored
Normal file
5725
imports/util/select2/select2.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
288
imports/util/simplegrid.css
Normal file
288
imports/util/simplegrid.css
Normal file
@@ -0,0 +1,288 @@
|
|||||||
|
/*
|
||||||
|
Simple Grid
|
||||||
|
Project Page - http://thisisdallas.github.com/Simple-Grid/
|
||||||
|
Author - Dallas Bass
|
||||||
|
Site - http://dallasbass.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
[class*='grid'],
|
||||||
|
[class*='col-'],
|
||||||
|
[class*='mobile-'],
|
||||||
|
.grid:after {
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
[class*='col-'] {
|
||||||
|
float: left;
|
||||||
|
min-height: 1px;
|
||||||
|
padding-right: 20px; /* column-space */
|
||||||
|
}
|
||||||
|
|
||||||
|
[class*='col-'] [class*='col-']:last-child {
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 1140px;
|
||||||
|
min-width: 748px; /* when using padded grid on ipad in portrait mode, width should be viewport-width - padding = (768 - 20) = 748. actually, it should be even smaller to allow for padding of grid containing element */
|
||||||
|
margin: 0 auto;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid:after {
|
||||||
|
content: "";
|
||||||
|
display: table;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-pad {
|
||||||
|
padding-top: 20px;
|
||||||
|
padding-left: 20px; /* grid-space to left */
|
||||||
|
padding-right: 0; /* grid-space to right: (grid-space-left - column-space) e.g. 20px-20px=0 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.push-right {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Content Columns */
|
||||||
|
|
||||||
|
.col-1-1 {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.col-2-3, .col-8-12 {
|
||||||
|
width: 66.66%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-1-2, .col-6-12 {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-1-3, .col-4-12 {
|
||||||
|
width: 33.33%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-1-4, .col-3-12 {
|
||||||
|
width: 25%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-1-5 {
|
||||||
|
width: 20%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-1-6, .col-2-12 {
|
||||||
|
width: 16.667%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-1-7 {
|
||||||
|
width: 14.28%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-1-8 {
|
||||||
|
width: 12.5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-1-9 {
|
||||||
|
width: 11.1%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-1-10 {
|
||||||
|
width: 10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-1-11 {
|
||||||
|
width: 9.09%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-1-12 {
|
||||||
|
width: 8.33%
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Layout Columns */
|
||||||
|
|
||||||
|
.col-11-12 {
|
||||||
|
width: 91.66%
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-10-12 {
|
||||||
|
width: 83.333%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-9-12 {
|
||||||
|
width: 75%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-5-12 {
|
||||||
|
width: 41.66%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-7-12 {
|
||||||
|
width: 58.33%
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pushing blocks */
|
||||||
|
|
||||||
|
.push-2-3, .push-8-12 {
|
||||||
|
margin-left: 66.66%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.push-1-2, .push-6-12 {
|
||||||
|
margin-left: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.push-1-3, .push-4-12 {
|
||||||
|
margin-left: 33.33%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.push-1-4, .push-3-12 {
|
||||||
|
margin-left: 25%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.push-1-5 {
|
||||||
|
margin-left: 20%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.push-1-6, .push-2-12 {
|
||||||
|
margin-left: 16.667%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.push-1-7 {
|
||||||
|
margin-left: 14.28%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.push-1-8 {
|
||||||
|
margin-left: 12.5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.push-1-9 {
|
||||||
|
margin-left: 11.1%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.push-1-10 {
|
||||||
|
margin-left: 10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.push-1-11 {
|
||||||
|
margin-left: 9.09%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.push-1-12 {
|
||||||
|
margin-left: 8.33%
|
||||||
|
}
|
||||||
|
|
||||||
|
@media handheld, only screen and (max-width: 767px) {
|
||||||
|
.grid {
|
||||||
|
width: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 0;
|
||||||
|
padding-left: 20px; /* grid-space to left */
|
||||||
|
padding-right: 10px; /* grid-space to right: (grid-space-left - column-space) e.g. 20px-10px=10px */
|
||||||
|
}
|
||||||
|
|
||||||
|
[class*='col-'] {
|
||||||
|
width: auto;
|
||||||
|
float: none;
|
||||||
|
margin: 10px 0;
|
||||||
|
padding-left: 0;
|
||||||
|
padding-right: 10px; /* column-space */
|
||||||
|
}
|
||||||
|
|
||||||
|
[class*='col-'] [class*='col-'] {
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mobile Layout */
|
||||||
|
|
||||||
|
[class*='mobile-col-'] {
|
||||||
|
float: left;
|
||||||
|
margin: 0 0 10px;
|
||||||
|
padding-left: 0;
|
||||||
|
padding-right: 10px; /* column-space */
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-col-1-1 {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.mobile-col-2-3, .mobile-col-8-12 {
|
||||||
|
width: 66.66%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-col-1-2, .mobile-col-6-12 {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-col-1-3, .mobile-col-4-12 {
|
||||||
|
width: 33.33%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-col-1-4, .mobile-col-3-12 {
|
||||||
|
width: 25%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-col-1-5 {
|
||||||
|
width: 20%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-col-1-6, .mobile-col-2-12 {
|
||||||
|
width: 16.667%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-col-1-7 {
|
||||||
|
width: 14.28%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-col-1-8 {
|
||||||
|
width: 12.5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-col-1-9 {
|
||||||
|
width: 11.1%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-col-1-10 {
|
||||||
|
width: 10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-col-1-11 {
|
||||||
|
width: 9.09%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-col-1-12 {
|
||||||
|
width: 8.33%
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Layout Columns */
|
||||||
|
|
||||||
|
.mobile-col-11-12 {
|
||||||
|
width: 91.66%
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-col-10-12 {
|
||||||
|
width: 83.333%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-col-9-12 {
|
||||||
|
width: 75%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-col-5-12 {
|
||||||
|
width: 41.66%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-col-7-12 {
|
||||||
|
width: 58.33%
|
||||||
|
}
|
||||||
|
|
||||||
|
.hide-on-mobile {
|
||||||
|
display: none !important;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"babel-runtime": "^6.18.0",
|
"babel-runtime": "^6.18.0",
|
||||||
"csv-parse": "latest",
|
"csv-parse": "latest",
|
||||||
|
"jquery": "^3.1.1",
|
||||||
"meteor-node-stubs": "^0.2.4",
|
"meteor-node-stubs": "^0.2.4",
|
||||||
"properties-reader": "0.0.15",
|
"properties-reader": "0.0.15",
|
||||||
"simpl-schema": "0.0.3"
|
"simpl-schema": "0.0.3"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import '/imports/util/regex.js';
|
import '/imports/util/polyfills/regex.js';
|
||||||
import '/imports/startup/server';
|
import '/imports/startup/server';
|
||||||
import '/imports/startup/both';
|
import '/imports/startup/both';
|
||||||
import '/imports/api';
|
import '/imports/api';
|
||||||
|
|||||||
Reference in New Issue
Block a user