Initial commit. Modified the Meteor todos app to create the Petit Teton data tracking app. Has working data for sales. Requires a Mongo database.
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
node_modules
|
||||||
|
private
|
||||||
15
.idea/PetitTetonMeteor.iml
generated
Normal file
15
.idea/PetitTetonMeteor.iml
generated
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/.meteor/local" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="library" name="meteor-packages-auto-import-browser" level="project" />
|
||||||
|
<orderEntry type="library" name="meteor-packages-auto-import-npm" level="project" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
9
.idea/codeStyleSettings.xml
generated
Normal file
9
.idea/codeStyleSettings.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectCodeStyleSettingsManager">
|
||||||
|
<option name="PER_PROJECT_SETTINGS">
|
||||||
|
<value />
|
||||||
|
</option>
|
||||||
|
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default (1)" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
11
.idea/dictionaries/Grumpy.xml
generated
Normal file
11
.idea/dictionaries/Grumpy.xml
generated
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<component name="ProjectDictionaryState">
|
||||||
|
<dictionary name="Grumpy">
|
||||||
|
<words>
|
||||||
|
<w>clickable</w>
|
||||||
|
<w>noselect</w>
|
||||||
|
<w>signup</w>
|
||||||
|
<w>styl</w>
|
||||||
|
<w>yorkville</w>
|
||||||
|
</words>
|
||||||
|
</dictionary>
|
||||||
|
</component>
|
||||||
9
.idea/jsLibraryMappings.xml
generated
Normal file
9
.idea/jsLibraryMappings.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="JavaScriptLibraryMappings">
|
||||||
|
<file url="file://$PROJECT_DIR$" libraries="{PetitTetonMeteor/node_modules}" />
|
||||||
|
<file url="PROJECT" libraries="{meteor-packages-auto-import-browser, meteor-packages-auto-import-npm}" />
|
||||||
|
<includedPredefinedLibrary name="ECMAScript 6" />
|
||||||
|
<includedPredefinedLibrary name="Meteor project library" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
827
.idea/libraries/meteor_packages_auto_import_browser.xml
generated
Normal file
827
.idea/libraries/meteor_packages_auto_import_browser.xml
generated
Normal file
@@ -0,0 +1,827 @@
|
|||||||
|
<component name="libraryTable">
|
||||||
|
<library name="meteor-packages-auto-import-browser" type="javaScript">
|
||||||
|
<properties>
|
||||||
|
<sourceFilesUrls>
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_listen/3.0.0/web.browser/client/main.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_listen/3.0.0/web.browser/client/main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_listen/3.0.0/web.browser/config/config.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_listen/3.0.0/web.browser/config/config.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_method/3.0.4/web.browser/lib/main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_method/3.0.4/web.browser/client/main.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_method/3.0.4/web.browser/client/main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_method/3.0.4/web.browser/ToyKit/main.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_method/3.0.4/web.browser/ToyKit/main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_pub/3.0.4/web.browser/lib/main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_pub/3.0.4/web.browser/client/main.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_pub/3.0.4/web.browser/client/main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_pub/3.0.4/web.browser/ToyKit/main.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_pub/3.0.4/web.browser/ToyKit/main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/babel-runtime/1.0.1/web.browser/babel-runtime.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_result/3.0.0/web.browser/client/header.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_result/3.0.0/web.browser/client/main.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_result/3.0.0/web.browser/client/function.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_result/3.0.0/web.browser/client/main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_result/3.0.0/web.browser/config/config.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_result/3.0.0/web.browser/config/config.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/base64/1.0.10/web.browser/base64.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/binary-heap/1.0.10/web.browser/min-max-heap.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/binary-heap/1.0.10/web.browser/min-heap.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/binary-heap/1.0.10/web.browser/max-heap.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_shell/3.0.0/web.browser/client/main.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_shell/3.0.0/web.browser/client/main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_shell/3.0.0/web.browser/config/config.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_shell/3.0.0/web.browser/config/config.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/ddp-client/1.2.9/web.browser/sockjs-0.3.4.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/ddp-client/1.2.9/web.browser/random_stream.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/ddp-client/1.2.9/web.browser/stream_client_common.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/ddp-client/1.2.9/web.browser/livedata_connection.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/ddp-client/1.2.9/web.browser/stream_client_sockjs.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/ddp-client/1.2.9/web.browser/namespace.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_status/3.0.0/web.browser/client/main.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/ddp-client/1.2.9/web.browser/livedata_common.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_status/3.0.0/web.browser/client/main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/ddp-client/1.2.9/web.browser/client_convenience.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_status/3.0.0/web.browser/config/config.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/ddp-client/1.2.9/web.browser/id_map.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_status/3.0.0/web.browser/config/config.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/momentjs_moment/2.17.1/web.browser/moment.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/momentjs_moment/2.17.1/web.browser/export.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/tomwasd_history-polyfill/0.0.1/web.browser/packages/tomwasd_history-polyfill.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/blaze/2.1.9/web.browser/dombackend.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/blaze/2.1.9/web.browser/view.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/blaze/2.1.9/web.browser/materializer.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/blaze/2.1.9/web.browser/template.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/blaze/2.1.9/web.browser/exceptions.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/aldeed_template-extension/4.0.0/web.browser/lib/template-replaces.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/blaze/2.1.9/web.browser/attrs.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/aldeed_template-extension/4.0.0/web.browser/lib/template-instance-get.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/blaze/2.1.9/web.browser/backcompat.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/aldeed_template-extension/4.0.0/web.browser/lib/template-clear-event-maps.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/blaze/2.1.9/web.browser/events.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/aldeed_template-extension/4.0.0/web.browser/lib/template-for-each-instance.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/blaze/2.1.9/web.browser/lookup.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/aldeed_template-extension/4.0.0/web.browser/lib/template-inherits-hooks-from.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/blaze/2.1.9/web.browser/builtins.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/aldeed_template-extension/4.0.0/web.browser/lib/template-for-each.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/blaze/2.1.9/web.browser/preamble.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/aldeed_template-extension/4.0.0/web.browser/lib/template-copy-as.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/blaze/2.1.9/web.browser/domrange.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/aldeed_template-extension/4.0.0/web.browser/lib/template-inherits-helpers-from.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/aldeed_template-extension/4.0.0/web.browser/lib/template-register-helpers.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/aldeed_template-extension/4.0.0/web.browser/lib/template-instance-parent.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/aldeed_template-extension/4.0.0/web.browser/lib/hooks.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/aldeed_template-extension/4.0.0/web.browser/lib/template-parent-data-function.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/blaze-tools/1.0.10/web.browser/tokens.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/aldeed_template-extension/4.0.0/web.browser/lib/template-hooks.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/blaze-tools/1.0.10/web.browser/tojs.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/aldeed_template-extension/4.0.0/web.browser/lib/template-inherits-events-from.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/blaze-tools/1.0.10/web.browser/preamble.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/aldeed_template-extension/4.0.0/web.browser/lib/template-global-hooks.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/ko.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/pt_PT.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/arillo_flow-router-helpers/0.5.2/web.browser/client/helpers.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/caching-compiler/1.1.9/web.browser/multi-file-caching-compiler.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/et.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/caching-compiler/1.1.9/web.browser/caching-compiler.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/no_NB.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/fr.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/es.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/kh.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/sk.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/mizzao_bootboxjs/4.4.0/web.browser/packages/mizzao_bootboxjs.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/sv.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/sl.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/es_ES.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/it.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/uk.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/hu.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/hr.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/id.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/tr.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/ja.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/zh_TW.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/zh_HK.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/he.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/pt.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/vi.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/ar.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/el.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/en.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/zimme_active-route/2.3.2/web.browser/packages/zimme_active-route.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/ru.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/ro.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/fa.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/zh_CN.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/cs.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/caching-html-compiler/1.0.7/web.browser/caching-html-compiler.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/pl.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/de.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/da.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/ddp-common/1.2.8/web.browser/random_stream.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/nl.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/ddp-common/1.2.8/web.browser/method_invocation.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/ca.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/ddp-common/1.2.8/web.browser/namespace.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/ddp-common/1.2.8/web.browser/utils.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/ddp-common/1.2.8/web.browser/heartbeat.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/methods.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/fastclick/1.0.13/web.browser/pre.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/field.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/fastclick/1.0.13/web.browser/post.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/utils.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/fastclick/1.0.13/web.browser/fastclick.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/client.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/core.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/html-tools/1.0.11/web.browser/scanner.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_oauth.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/html-tools/1.0.11/web.browser/templatetag.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_form.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/html-tools/1.0.11/web.browser/tokenize.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_sep.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/html-tools/1.0.11/web.browser/utils.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_message.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/html-tools/1.0.11/web.browser/charref.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/html-tools/1.0.11/web.browser/parse.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_pwd_form.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_nav_button.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_pwd_form_btn.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/htmljs/1.0.11/web.browser/html.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_social.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/aldeed_collection2-core/1.2.0/web.browser/lib/collection2.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/htmljs/1.0.11/web.browser/visitors.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_signin_link.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/htmljs/1.0.11/web.browser/preamble.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_error.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_pwd_link.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/ensure_signed_in.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/aldeed_schema-deny/1.1.0/web.browser/lib/deny.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_result.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_terms_link.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_title.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_reCaptcha.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/aldeed_schema-index/1.1.1/web.browser/lib/indexing.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_input.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_resend_verification_email_link.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_signup_link.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_flow-routing/1.14.2/web.browser/lib/core.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_flow-routing/1.14.2/web.browser/lib/client/client.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_flow-routing/1.14.2/web.browser/lib/client/templates_helpers/at_input.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/observe-sequence/1.0.14/web.browser/observe_sequence.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/reload/1.1.11/web.browser/deprecated.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/reload/1.1.11/web.browser/reload.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/retry/1.0.9/web.browser/retry.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/session/1.1.7/web.browser/session.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/fortawesome_fontawesome/4.7.0/web.browser/upstream/css/font-awesome.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/spacebars/1.0.13/web.browser/spacebars-runtime.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/poorvavyas_es6-shim/0.21.1/web.browser/es6-shim.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/spacebars-compiler/1.0.13/web.browser/react.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/spacebars-compiler/1.0.13/web.browser/compiler.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/spacebars-compiler/1.0.13/web.browser/templatetag.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/spacebars-compiler/1.0.13/web.browser/codegen.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/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/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/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/throw-compile-error.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/templating-tools/1.0.5/web.browser/code-generation.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/url/1.0.11/web.browser/url_common.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/url/1.0.11/web.browser/url_client.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_sub/3.0.0/web.browser/client/main.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_sub/3.0.0/web.browser/client/main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_sub/3.0.0/web.browser/config/config.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_sub/3.0.0/web.browser/config/config.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/webapp-hashing/1.0.9/web.browser/webapp-hashing.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_throttle/3.0.0/web.browser/client/main.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_throttle/3.0.0/web.browser/client/main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_throttle/3.0.0/web.browser/config/config.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_throttle/3.0.0/web.browser/config/config.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/callback-hook/1.0.10/web.browser/hook.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/check/1.2.4/web.browser/match.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/check/1.2.4/web.browser/isPlainObject.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/aldeed_simple-schema/1.5.3/web.browser/simple-schema-utility.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/check/1.2.4/web.browser/match_test.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/aldeed_simple-schema/1.5.3/web.browser/string-humanize.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/aldeed_simple-schema/1.5.3/web.browser/simple-schema-validation-new.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/aldeed_simple-schema/1.5.3/web.browser/simple-schema.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/aldeed_simple-schema/1.5.3/web.browser/simple-schema-validation.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/aldeed_simple-schema/1.5.3/web.browser/string-polyfills.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/aldeed_simple-schema/1.5.3/web.browser/mongo-object.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_toykit/3.0.4/web.browser/lib/collections.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/aldeed_simple-schema/1.5.3/web.browser/simple-schema-context.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_toykit/3.0.4/web.browser/lib/privateAPI.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/mdg_validation-error/0.2.0/web.browser/validation-error.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_toykit/3.0.4/web.browser/style/toykit.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_toykit/3.0.4/web.browser/client/main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/msavin_jetsetter/2.0.0/web.browser/style/JetSetter.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/msavin_jetsetter/2.0.0/web.browser/client/main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/msavin_jetsetter/2.0.0/web.browser/client/functions.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/msavin_jetsetter/2.0.0/web.browser/client/row/main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/msavin_jetsetter/2.0.0/web.browser/client/row_dict/main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/msavin_jetsetter/2.0.0/web.browser/client/_component/component.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/msavin_jetsetter/2.0.0/web.browser/client/row_editor/JetSetter_editor.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/msavin_jetsetter/2.0.0/web.browser/client/row_header/JetSetter_header.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/msavin_jetsetter/2.0.0/web.browser/client/dirtySession/main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/msavin_jetsetter/2.0.0/web.browser/client/dirtySession/create/main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/msavin_jetsetter/2.0.0/web.browser/client/dirtySession/editor/main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/msavin_jetsetter/2.0.0/web.browser/client/dirtySession/session/main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/msavin_mongol/2.0.1/web.browser/lib/common.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/msavin_mongol/2.0.1/web.browser/style/Mongol.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/msavin_mongol/2.0.1/web.browser/client/main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/msavin_mongol/2.0.1/web.browser/client/row_trash/main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/msavin_mongol/2.0.1/web.browser/client/_component/component.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/msavin_mongol/2.0.1/web.browser/client/doc_editor/inline.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/msavin_mongol/2.0.1/web.browser/client/doc_editor/docViewer.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/msavin_mongol/2.0.1/web.browser/client/doc_insert/docInsert.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/msavin_mongol/2.0.1/web.browser/client/row_header/header.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/msavin_mongol/2.0.1/web.browser/client/row_account/account.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/msavin_mongol/2.0.1/web.browser/client/row_account/accountViewer.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/msavin_mongol/2.0.1/web.browser/client/doc_controls/docControls.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/http/1.1.8/web.browser/deprecated.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/http/1.1.8/web.browser/test_responder.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/msavin_mongol/2.0.1/web.browser/client/row_collection/collections.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/http/1.1.8/web.browser/httpcall_tests.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/http/1.1.8/web.browser/httpcall_common.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/http/1.1.8/web.browser/httpcall_server.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/msavin_mongol/2.0.1/web.browser/client/row_subscriptions/main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/http/1.1.8/web.browser/httpcall_client.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/msavin_mongol/2.0.1/web.browser/client/row_collection_notFound/notFound.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/kadira_flow-router/2.12.1/web.browser/lib/router.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/ordered-dict/1.0.9/web.browser/ordered_dict.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/kadira_flow-router/2.12.1/web.browser/client/router.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/kadira_flow-router/2.12.1/web.browser/client/group.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/promise/0.8.8/web.browser/common.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/kadira_flow-router/2.12.1/web.browser/client/_init.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/promise/0.8.8/web.browser/client.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/kadira_flow-router/2.12.1/web.browser/client/triggers.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/promise/0.8.8/web.browser/server.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/kadira_flow-router/2.12.1/web.browser/client/modules.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/promise/0.8.8/web.browser/promise-tests.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/kadira_flow-router/2.12.1/web.browser/client/route.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/kadira_flow-router/2.12.1/web.browser/test/client/_helpers.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/diff-sequence/1.0.7/web.browser/diff.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/kadira_flow-router/2.12.1/web.browser/test/client/triggers.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/kadira_flow-router/2.12.1/web.browser/test/common/fast_render_route.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/ecmascript-runtime/0.3.15/web.browser/runtime-tests.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/ecmascript-runtime/0.3.15/web.browser/runtime.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/accounts-base/1.2.14/web.browser/client_main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/accounts-base/1.2.14/web.browser/server_main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/accounts-base/1.2.14/web.browser/server_tests.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/accounts-base/1.2.14/web.browser/url_client.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/accounts-base/1.2.14/web.browser/client_tests.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/accounts-base/1.2.14/web.browser/localstorage_token.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/accounts-base/1.2.14/web.browser/accounts_common.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/accounts-base/1.2.14/web.browser/url_server.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/accounts-base/1.2.14/web.browser/accounts_reconnect_tests.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/accounts-base/1.2.14/web.browser/accounts_tests.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/accounts-base/1.2.14/web.browser/accounts_url_tests.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/random/1.0.10/web.browser/deprecated.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/accounts-base/1.2.14/web.browser/accounts_client.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/random/1.0.10/web.browser/random_tests.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/accounts-base/1.2.14/web.browser/accounts_rate_limit.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/random/1.0.10/web.browser/random.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/accounts-base/1.2.14/web.browser/accounts_server.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/rate-limit/1.0.6/web.browser/rate-limit.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/accounts-password/1.3.3/web.browser/password_tests_setup.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/accounts-password/1.3.3/web.browser/email_tests.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/accounts-password/1.3.3/web.browser/email_templates.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/reactive-dict/1.1.8/web.browser/reactive-dict-tests.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/accounts-password/1.3.3/web.browser/email_tests_setup.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/reactive-dict/1.1.8/web.browser/reactive-dict.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/accounts-password/1.3.3/web.browser/password_client.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/reactive-dict/1.1.8/web.browser/migration.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/accounts-password/1.3.3/web.browser/password_tests.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/accounts-password/1.3.3/web.browser/password_server.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/juliancwirko_s-alert/3.2.0/web.browser/client/s-alert-collection.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/juliancwirko_s-alert/3.2.0/web.browser/client/s-alert-template.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/juliancwirko_s-alert/3.2.0/web.browser/client/s-alert-default.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/juliancwirko_s-alert/3.2.0/web.browser/client/s-alert.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/reactive-var/1.0.11/web.browser/reactive-var.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/matb33_collection-hooks/0.8.4/web.browser/findone.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/matb33_collection-hooks/0.8.4/web.browser/upsert.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/service-configuration/1.0.11/web.browser/service_configuration_common.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/matb33_collection-hooks/0.8.4/web.browser/users-compat.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/matb33_collection-hooks/0.8.4/web.browser/find.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/matb33_collection-hooks/0.8.4/web.browser/insert.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/matb33_collection-hooks/0.8.4/web.browser/collection-hooks.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/matb33_collection-hooks/0.8.4/web.browser/remove.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/allow-deny/1.0.5/web.browser/allow-deny.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/matb33_collection-hooks/0.8.4/web.browser/update.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/sha/1.0.9/web.browser/sha256.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/allow-deny/1.0.5/web.browser/allow-deny-tests.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/srp/1.0.10/web.browser/srp.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/srp/1.0.10/web.browser/biginteger.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/tracker/1.1.1/web.browser/deprecated.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/tracker/1.1.1/web.browser/tracker.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/underscore/1.0.10/web.browser/underscore.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/underscore/1.0.10/web.browser/pre.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/underscore/1.0.10/web.browser/post.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/webapp/1.3.12/web.browser/webapp_client_tests.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/webapp/1.3.12/web.browser/webapp_tests.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/webapp/1.3.12/web.browser/webapp_cordova.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/webapp/1.3.12/web.browser/webapp_client.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/webapp/1.3.12/web.browser/webapp_server.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/id-map/1.0.9/web.browser/id-map.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/jquery/1.11.10/web.browser/jquery.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/jquery/1.11.10/web.browser/main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/localstorage/1.0.12/web.browser/localstorage.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/logging/1.1.16/web.browser/logging_test.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/logging/1.1.16/web.browser/logging.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/logging/1.1.16/web.browser/logging_cordova.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/zimme_collection-behaviours/1.0.4/web.browser/packages/zimme_collection-behaviours.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/zimme_collection-softremovable/1.0.5/web.browser/softremovable.coffee" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/ejson/1.0.13/web.browser/stringify.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/ejson/1.0.13/web.browser/ejson.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/es5-shim/4.6.15/web.browser/export_globals.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/es5-shim/4.6.15/web.browser/import_globals.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/es5-shim/4.6.15/web.browser/console.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/es5-shim/4.6.15/web.browser/client.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/es5-shim/4.6.15/web.browser/server.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/modules/0.7.7/web.browser/install-packages.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/modules/0.7.7/web.browser/process.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/modules/0.7.7/web.browser/stubs.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/modules/0.7.7/web.browser/client.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/modules/0.7.7/web.browser/css.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/modules/0.7.7/web.browser/buffer.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/modules/0.7.7/web.browser/server.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/geojson-utils/1.0.10/web.browser/geojson-utils.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/geojson-utils/1.0.10/web.browser/main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/kadira_blaze-layout/2.3.0/web.browser/lib/client/namespace.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/kadira_blaze-layout/2.3.0/web.browser/lib/client/layout.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/raix_eventemitter/0.1.3/web.browser/packages/raix_eventemitter.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/modules-runtime/0.7.7/web.browser/modules-runtime.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/modules-runtime/0.7.7/web.browser/.npm/package/node_modules/install/install.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/mongo-id/1.0.6/web.browser/id.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/launch-screen/1.0.12/web.browser/default-behavior.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/launch-screen/1.0.12/web.browser/mobile-launch-screen.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_allthings/3.0.0/web.browser/main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_authenticate/3.0.0/web.browser/client/main.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_authenticate/3.0.0/web.browser/client/main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_authenticate/3.0.0/web.browser/config/config.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_authenticate/3.0.0/web.browser/config/config.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_autopub/3.0.0/web.browser/client/main.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_autopub/3.0.0/web.browser/client/main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_autopub/3.0.0/web.browser/config/config.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_autopub/3.0.0/web.browser/config/config.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_sep.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_bootstrap.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_blueprint/3.0.0/web.browser/client/tree.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_pwd_form.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_pwd_form_btn.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_social.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_blueprint/3.0.0/web.browser/client/header.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_signin_link.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_blueprint/3.0.0/web.browser/client/inspector.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_blueprint/3.0.0/web.browser/client/main.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_result.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_terms_link.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_blueprint/3.0.0/web.browser/client/main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_blueprint/3.0.0/web.browser/client/api.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_blueprint/3.0.0/web.browser/config/config.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_input.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_blueprint/3.0.0/web.browser/config/config.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_resend_verification_email_link.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_oauth.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_form.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_message.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_nav_button.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_error.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_pwd_link.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_title.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_email/3.0.0/web.browser/client/header.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_reCaptcha.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_email/3.0.0/web.browser/client/main.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_email/3.0.0/web.browser/client/main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_signup_link.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_email/3.0.0/web.browser/client/content.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_email/3.0.0/web.browser/config/config.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_email/3.0.0/web.browser/config/config.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/alanning_roles/1.2.15/web.browser/roles_common.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/alanning_roles/1.2.15/web.browser/client/debug.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/alanning_roles/1.2.15/web.browser/client/uiHelpers.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/alanning_roles/1.2.15/web.browser/client/subscriptions.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_hotreload/3.0.0/web.browser/client/main.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_hotreload/3.0.0/web.browser/client/main.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_hotreload/3.0.0/web.browser/config/config.css" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/meteortoys_hotreload/3.0.0/web.browser/config/config.js" />
|
||||||
|
<item url="file://C:/Tools/.meteor/packages/autoupdate/1.2.11/web.browser/autoupdate_client.js" />
|
||||||
|
</sourceFilesUrls>
|
||||||
|
</properties>
|
||||||
|
<CLASSES>
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_listen/3.0.0/web.browser/client/main.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_listen/3.0.0/web.browser/client/main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_listen/3.0.0/web.browser/config/config.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_listen/3.0.0/web.browser/config/config.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_method/3.0.4/web.browser/lib/main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_method/3.0.4/web.browser/client/main.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_method/3.0.4/web.browser/client/main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_method/3.0.4/web.browser/ToyKit/main.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_method/3.0.4/web.browser/ToyKit/main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_pub/3.0.4/web.browser/lib/main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_pub/3.0.4/web.browser/client/main.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_pub/3.0.4/web.browser/client/main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_pub/3.0.4/web.browser/ToyKit/main.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_pub/3.0.4/web.browser/ToyKit/main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/babel-runtime/1.0.1/web.browser/babel-runtime.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_result/3.0.0/web.browser/client/header.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_result/3.0.0/web.browser/client/main.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_result/3.0.0/web.browser/client/function.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_result/3.0.0/web.browser/client/main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_result/3.0.0/web.browser/config/config.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_result/3.0.0/web.browser/config/config.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/base64/1.0.10/web.browser/base64.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/binary-heap/1.0.10/web.browser/min-max-heap.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/binary-heap/1.0.10/web.browser/min-heap.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/binary-heap/1.0.10/web.browser/max-heap.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_shell/3.0.0/web.browser/client/main.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_shell/3.0.0/web.browser/client/main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_shell/3.0.0/web.browser/config/config.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_shell/3.0.0/web.browser/config/config.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/ddp-client/1.2.9/web.browser/sockjs-0.3.4.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/ddp-client/1.2.9/web.browser/random_stream.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/ddp-client/1.2.9/web.browser/stream_client_common.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/ddp-client/1.2.9/web.browser/livedata_connection.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/ddp-client/1.2.9/web.browser/stream_client_sockjs.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/ddp-client/1.2.9/web.browser/namespace.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_status/3.0.0/web.browser/client/main.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/ddp-client/1.2.9/web.browser/livedata_common.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_status/3.0.0/web.browser/client/main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/ddp-client/1.2.9/web.browser/client_convenience.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_status/3.0.0/web.browser/config/config.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/ddp-client/1.2.9/web.browser/id_map.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_status/3.0.0/web.browser/config/config.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/momentjs_moment/2.17.1/web.browser/moment.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/momentjs_moment/2.17.1/web.browser/export.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/tomwasd_history-polyfill/0.0.1/web.browser/packages/tomwasd_history-polyfill.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/blaze/2.1.9/web.browser/dombackend.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/blaze/2.1.9/web.browser/view.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/blaze/2.1.9/web.browser/materializer.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/blaze/2.1.9/web.browser/template.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/blaze/2.1.9/web.browser/exceptions.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/aldeed_template-extension/4.0.0/web.browser/lib/template-replaces.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/blaze/2.1.9/web.browser/attrs.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/aldeed_template-extension/4.0.0/web.browser/lib/template-instance-get.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/blaze/2.1.9/web.browser/backcompat.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/aldeed_template-extension/4.0.0/web.browser/lib/template-clear-event-maps.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/blaze/2.1.9/web.browser/events.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/aldeed_template-extension/4.0.0/web.browser/lib/template-for-each-instance.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/blaze/2.1.9/web.browser/lookup.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/aldeed_template-extension/4.0.0/web.browser/lib/template-inherits-hooks-from.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/blaze/2.1.9/web.browser/builtins.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/aldeed_template-extension/4.0.0/web.browser/lib/template-for-each.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/blaze/2.1.9/web.browser/preamble.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/aldeed_template-extension/4.0.0/web.browser/lib/template-copy-as.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/blaze/2.1.9/web.browser/domrange.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/aldeed_template-extension/4.0.0/web.browser/lib/template-inherits-helpers-from.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/aldeed_template-extension/4.0.0/web.browser/lib/template-register-helpers.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/aldeed_template-extension/4.0.0/web.browser/lib/template-instance-parent.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/aldeed_template-extension/4.0.0/web.browser/lib/hooks.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/aldeed_template-extension/4.0.0/web.browser/lib/template-parent-data-function.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/blaze-tools/1.0.10/web.browser/tokens.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/aldeed_template-extension/4.0.0/web.browser/lib/template-hooks.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/blaze-tools/1.0.10/web.browser/tojs.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/aldeed_template-extension/4.0.0/web.browser/lib/template-inherits-events-from.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/blaze-tools/1.0.10/web.browser/preamble.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/aldeed_template-extension/4.0.0/web.browser/lib/template-global-hooks.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/ko.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/pt_PT.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/arillo_flow-router-helpers/0.5.2/web.browser/client/helpers.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/caching-compiler/1.1.9/web.browser/multi-file-caching-compiler.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/et.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/caching-compiler/1.1.9/web.browser/caching-compiler.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/no_NB.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/fr.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/es.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/kh.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/sk.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/mizzao_bootboxjs/4.4.0/web.browser/packages/mizzao_bootboxjs.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/sv.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/sl.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/es_ES.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/it.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/uk.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/hu.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/hr.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/id.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/tr.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/ja.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/zh_TW.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/zh_HK.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/he.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/pt.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/vi.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/ar.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/el.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/en.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/zimme_active-route/2.3.2/web.browser/packages/zimme_active-route.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/ru.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/ro.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/fa.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/zh_CN.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/cs.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/caching-html-compiler/1.0.7/web.browser/caching-html-compiler.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/pl.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/de.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/da.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/ddp-common/1.2.8/web.browser/random_stream.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/nl.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/ddp-common/1.2.8/web.browser/method_invocation.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/softwarerero_accounts-t9n/1.3.6/web.browser/t9n/ca.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/ddp-common/1.2.8/web.browser/namespace.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/ddp-common/1.2.8/web.browser/utils.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/ddp-common/1.2.8/web.browser/heartbeat.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/methods.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/fastclick/1.0.13/web.browser/pre.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/field.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/fastclick/1.0.13/web.browser/post.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/utils.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/fastclick/1.0.13/web.browser/fastclick.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/client.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/core.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/html-tools/1.0.11/web.browser/scanner.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_oauth.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/html-tools/1.0.11/web.browser/templatetag.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_form.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/html-tools/1.0.11/web.browser/tokenize.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_sep.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/html-tools/1.0.11/web.browser/utils.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_message.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/html-tools/1.0.11/web.browser/charref.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/html-tools/1.0.11/web.browser/parse.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_pwd_form.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_nav_button.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_pwd_form_btn.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/htmljs/1.0.11/web.browser/html.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_social.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/aldeed_collection2-core/1.2.0/web.browser/lib/collection2.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/htmljs/1.0.11/web.browser/visitors.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_signin_link.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/htmljs/1.0.11/web.browser/preamble.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_error.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_pwd_link.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/ensure_signed_in.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/aldeed_schema-deny/1.1.0/web.browser/lib/deny.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_result.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_terms_link.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_title.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_reCaptcha.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/aldeed_schema-index/1.1.1/web.browser/lib/indexing.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_input.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_resend_verification_email_link.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_core/1.14.2/web.browser/lib/templates_helpers/at_signup_link.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_flow-routing/1.14.2/web.browser/lib/core.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_flow-routing/1.14.2/web.browser/lib/client/client.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_flow-routing/1.14.2/web.browser/lib/client/templates_helpers/at_input.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/observe-sequence/1.0.14/web.browser/observe_sequence.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/reload/1.1.11/web.browser/deprecated.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/reload/1.1.11/web.browser/reload.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/retry/1.0.9/web.browser/retry.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/session/1.1.7/web.browser/session.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/fortawesome_fontawesome/4.7.0/web.browser/upstream/css/font-awesome.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/spacebars/1.0.13/web.browser/spacebars-runtime.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/poorvavyas_es6-shim/0.21.1/web.browser/es6-shim.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/spacebars-compiler/1.0.13/web.browser/react.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/spacebars-compiler/1.0.13/web.browser/compiler.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/spacebars-compiler/1.0.13/web.browser/templatetag.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/spacebars-compiler/1.0.13/web.browser/codegen.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/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/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/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/throw-compile-error.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/templating-tools/1.0.5/web.browser/code-generation.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/url/1.0.11/web.browser/url_common.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/url/1.0.11/web.browser/url_client.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_sub/3.0.0/web.browser/client/main.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_sub/3.0.0/web.browser/client/main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_sub/3.0.0/web.browser/config/config.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_sub/3.0.0/web.browser/config/config.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/webapp-hashing/1.0.9/web.browser/webapp-hashing.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_throttle/3.0.0/web.browser/client/main.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_throttle/3.0.0/web.browser/client/main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_throttle/3.0.0/web.browser/config/config.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_throttle/3.0.0/web.browser/config/config.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/callback-hook/1.0.10/web.browser/hook.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/check/1.2.4/web.browser/match.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/check/1.2.4/web.browser/isPlainObject.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/aldeed_simple-schema/1.5.3/web.browser/simple-schema-utility.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/check/1.2.4/web.browser/match_test.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/aldeed_simple-schema/1.5.3/web.browser/string-humanize.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/aldeed_simple-schema/1.5.3/web.browser/simple-schema-validation-new.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/aldeed_simple-schema/1.5.3/web.browser/simple-schema.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/aldeed_simple-schema/1.5.3/web.browser/simple-schema-validation.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/aldeed_simple-schema/1.5.3/web.browser/string-polyfills.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/aldeed_simple-schema/1.5.3/web.browser/mongo-object.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_toykit/3.0.4/web.browser/lib/collections.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/aldeed_simple-schema/1.5.3/web.browser/simple-schema-context.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_toykit/3.0.4/web.browser/lib/privateAPI.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/mdg_validation-error/0.2.0/web.browser/validation-error.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_toykit/3.0.4/web.browser/style/toykit.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_toykit/3.0.4/web.browser/client/main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/msavin_jetsetter/2.0.0/web.browser/style/JetSetter.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/msavin_jetsetter/2.0.0/web.browser/client/main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/msavin_jetsetter/2.0.0/web.browser/client/functions.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/msavin_jetsetter/2.0.0/web.browser/client/row/main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/msavin_jetsetter/2.0.0/web.browser/client/row_dict/main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/msavin_jetsetter/2.0.0/web.browser/client/_component/component.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/msavin_jetsetter/2.0.0/web.browser/client/row_editor/JetSetter_editor.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/msavin_jetsetter/2.0.0/web.browser/client/row_header/JetSetter_header.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/msavin_jetsetter/2.0.0/web.browser/client/dirtySession/main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/msavin_jetsetter/2.0.0/web.browser/client/dirtySession/create/main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/msavin_jetsetter/2.0.0/web.browser/client/dirtySession/editor/main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/msavin_jetsetter/2.0.0/web.browser/client/dirtySession/session/main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/msavin_mongol/2.0.1/web.browser/lib/common.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/msavin_mongol/2.0.1/web.browser/style/Mongol.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/msavin_mongol/2.0.1/web.browser/client/main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/msavin_mongol/2.0.1/web.browser/client/row_trash/main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/msavin_mongol/2.0.1/web.browser/client/_component/component.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/msavin_mongol/2.0.1/web.browser/client/doc_editor/inline.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/msavin_mongol/2.0.1/web.browser/client/doc_editor/docViewer.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/msavin_mongol/2.0.1/web.browser/client/doc_insert/docInsert.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/msavin_mongol/2.0.1/web.browser/client/row_header/header.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/msavin_mongol/2.0.1/web.browser/client/row_account/account.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/msavin_mongol/2.0.1/web.browser/client/row_account/accountViewer.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/msavin_mongol/2.0.1/web.browser/client/doc_controls/docControls.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/http/1.1.8/web.browser/deprecated.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/http/1.1.8/web.browser/test_responder.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/msavin_mongol/2.0.1/web.browser/client/row_collection/collections.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/http/1.1.8/web.browser/httpcall_tests.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/http/1.1.8/web.browser/httpcall_common.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/http/1.1.8/web.browser/httpcall_server.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/msavin_mongol/2.0.1/web.browser/client/row_subscriptions/main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/http/1.1.8/web.browser/httpcall_client.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/msavin_mongol/2.0.1/web.browser/client/row_collection_notFound/notFound.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/kadira_flow-router/2.12.1/web.browser/lib/router.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/ordered-dict/1.0.9/web.browser/ordered_dict.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/kadira_flow-router/2.12.1/web.browser/client/router.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/kadira_flow-router/2.12.1/web.browser/client/group.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/promise/0.8.8/web.browser/common.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/kadira_flow-router/2.12.1/web.browser/client/_init.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/promise/0.8.8/web.browser/client.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/kadira_flow-router/2.12.1/web.browser/client/triggers.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/promise/0.8.8/web.browser/server.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/kadira_flow-router/2.12.1/web.browser/client/modules.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/promise/0.8.8/web.browser/promise-tests.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/kadira_flow-router/2.12.1/web.browser/client/route.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/kadira_flow-router/2.12.1/web.browser/test/client/_helpers.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/diff-sequence/1.0.7/web.browser/diff.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/kadira_flow-router/2.12.1/web.browser/test/client/triggers.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/kadira_flow-router/2.12.1/web.browser/test/common/fast_render_route.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/ecmascript-runtime/0.3.15/web.browser/runtime-tests.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/ecmascript-runtime/0.3.15/web.browser/runtime.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/accounts-base/1.2.14/web.browser/client_main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/accounts-base/1.2.14/web.browser/server_main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/accounts-base/1.2.14/web.browser/server_tests.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/accounts-base/1.2.14/web.browser/url_client.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/accounts-base/1.2.14/web.browser/client_tests.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/accounts-base/1.2.14/web.browser/localstorage_token.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/accounts-base/1.2.14/web.browser/accounts_common.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/accounts-base/1.2.14/web.browser/url_server.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/accounts-base/1.2.14/web.browser/accounts_reconnect_tests.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/accounts-base/1.2.14/web.browser/accounts_tests.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/accounts-base/1.2.14/web.browser/accounts_url_tests.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/random/1.0.10/web.browser/deprecated.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/accounts-base/1.2.14/web.browser/accounts_client.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/random/1.0.10/web.browser/random_tests.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/accounts-base/1.2.14/web.browser/accounts_rate_limit.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/random/1.0.10/web.browser/random.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/accounts-base/1.2.14/web.browser/accounts_server.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/rate-limit/1.0.6/web.browser/rate-limit.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/accounts-password/1.3.3/web.browser/password_tests_setup.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/accounts-password/1.3.3/web.browser/email_tests.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/accounts-password/1.3.3/web.browser/email_templates.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/reactive-dict/1.1.8/web.browser/reactive-dict-tests.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/accounts-password/1.3.3/web.browser/email_tests_setup.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/reactive-dict/1.1.8/web.browser/reactive-dict.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/accounts-password/1.3.3/web.browser/password_client.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/reactive-dict/1.1.8/web.browser/migration.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/accounts-password/1.3.3/web.browser/password_tests.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/accounts-password/1.3.3/web.browser/password_server.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/juliancwirko_s-alert/3.2.0/web.browser/client/s-alert-collection.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/juliancwirko_s-alert/3.2.0/web.browser/client/s-alert-template.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/juliancwirko_s-alert/3.2.0/web.browser/client/s-alert-default.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/juliancwirko_s-alert/3.2.0/web.browser/client/s-alert.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/reactive-var/1.0.11/web.browser/reactive-var.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/matb33_collection-hooks/0.8.4/web.browser/findone.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/matb33_collection-hooks/0.8.4/web.browser/upsert.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/service-configuration/1.0.11/web.browser/service_configuration_common.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/matb33_collection-hooks/0.8.4/web.browser/users-compat.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/matb33_collection-hooks/0.8.4/web.browser/find.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/matb33_collection-hooks/0.8.4/web.browser/insert.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/matb33_collection-hooks/0.8.4/web.browser/collection-hooks.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/matb33_collection-hooks/0.8.4/web.browser/remove.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/allow-deny/1.0.5/web.browser/allow-deny.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/matb33_collection-hooks/0.8.4/web.browser/update.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/sha/1.0.9/web.browser/sha256.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/allow-deny/1.0.5/web.browser/allow-deny-tests.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/srp/1.0.10/web.browser/srp.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/srp/1.0.10/web.browser/biginteger.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/tracker/1.1.1/web.browser/deprecated.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/tracker/1.1.1/web.browser/tracker.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/underscore/1.0.10/web.browser/underscore.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/underscore/1.0.10/web.browser/pre.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/underscore/1.0.10/web.browser/post.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/webapp/1.3.12/web.browser/webapp_client_tests.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/webapp/1.3.12/web.browser/webapp_tests.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/webapp/1.3.12/web.browser/webapp_cordova.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/webapp/1.3.12/web.browser/webapp_client.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/webapp/1.3.12/web.browser/webapp_server.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/id-map/1.0.9/web.browser/id-map.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/jquery/1.11.10/web.browser/jquery.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/jquery/1.11.10/web.browser/main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/localstorage/1.0.12/web.browser/localstorage.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/logging/1.1.16/web.browser/logging_test.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/logging/1.1.16/web.browser/logging.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/logging/1.1.16/web.browser/logging_cordova.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/zimme_collection-behaviours/1.0.4/web.browser/packages/zimme_collection-behaviours.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/zimme_collection-softremovable/1.0.5/web.browser/softremovable.coffee" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/ejson/1.0.13/web.browser/stringify.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/ejson/1.0.13/web.browser/ejson.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/es5-shim/4.6.15/web.browser/export_globals.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/es5-shim/4.6.15/web.browser/import_globals.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/es5-shim/4.6.15/web.browser/console.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/es5-shim/4.6.15/web.browser/client.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/es5-shim/4.6.15/web.browser/server.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/modules/0.7.7/web.browser/install-packages.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/modules/0.7.7/web.browser/process.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/modules/0.7.7/web.browser/stubs.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/modules/0.7.7/web.browser/client.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/modules/0.7.7/web.browser/css.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/modules/0.7.7/web.browser/buffer.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/modules/0.7.7/web.browser/server.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/geojson-utils/1.0.10/web.browser/geojson-utils.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/geojson-utils/1.0.10/web.browser/main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/kadira_blaze-layout/2.3.0/web.browser/lib/client/namespace.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/kadira_blaze-layout/2.3.0/web.browser/lib/client/layout.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/raix_eventemitter/0.1.3/web.browser/packages/raix_eventemitter.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/modules-runtime/0.7.7/web.browser/modules-runtime.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/modules-runtime/0.7.7/web.browser/.npm/package/node_modules/install/install.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/mongo-id/1.0.6/web.browser/id.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/launch-screen/1.0.12/web.browser/default-behavior.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/launch-screen/1.0.12/web.browser/mobile-launch-screen.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_allthings/3.0.0/web.browser/main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_authenticate/3.0.0/web.browser/client/main.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_authenticate/3.0.0/web.browser/client/main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_authenticate/3.0.0/web.browser/config/config.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_authenticate/3.0.0/web.browser/config/config.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_autopub/3.0.0/web.browser/client/main.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_autopub/3.0.0/web.browser/client/main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_autopub/3.0.0/web.browser/config/config.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_autopub/3.0.0/web.browser/config/config.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_sep.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_bootstrap.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_blueprint/3.0.0/web.browser/client/tree.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_pwd_form.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_pwd_form_btn.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_social.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_blueprint/3.0.0/web.browser/client/header.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_signin_link.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_blueprint/3.0.0/web.browser/client/inspector.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_blueprint/3.0.0/web.browser/client/main.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_result.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_terms_link.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_blueprint/3.0.0/web.browser/client/main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_blueprint/3.0.0/web.browser/client/api.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_blueprint/3.0.0/web.browser/config/config.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_input.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_blueprint/3.0.0/web.browser/config/config.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_resend_verification_email_link.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_oauth.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_form.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_message.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_nav_button.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_error.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_pwd_link.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_title.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_email/3.0.0/web.browser/client/header.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_reCaptcha.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_email/3.0.0/web.browser/client/main.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_email/3.0.0/web.browser/client/main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/useraccounts_bootstrap/1.14.2/web.browser/lib/at_signup_link.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_email/3.0.0/web.browser/client/content.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_email/3.0.0/web.browser/config/config.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_email/3.0.0/web.browser/config/config.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/alanning_roles/1.2.15/web.browser/roles_common.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/alanning_roles/1.2.15/web.browser/client/debug.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/alanning_roles/1.2.15/web.browser/client/uiHelpers.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/alanning_roles/1.2.15/web.browser/client/subscriptions.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_hotreload/3.0.0/web.browser/client/main.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_hotreload/3.0.0/web.browser/client/main.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_hotreload/3.0.0/web.browser/config/config.css" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/meteortoys_hotreload/3.0.0/web.browser/config/config.js" />
|
||||||
|
<root url="file://C:/Tools/.meteor/packages/autoupdate/1.2.11/web.browser/autoupdate_client.js" />
|
||||||
|
</CLASSES>
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</component>
|
||||||
15657
.idea/libraries/meteor_packages_auto_import_npm.xml
generated
Normal file
15657
.idea/libraries/meteor_packages_auto_import_npm.xml
generated
Normal file
File diff suppressed because it is too large
Load Diff
68
.idea/markdown-navigator.xml
generated
Normal file
68
.idea/markdown-navigator.xml
generated
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="MarkdownProjectSettings">
|
||||||
|
<PreviewSettings splitEditorLayout="SPLIT" splitEditorPreview="PREVIEW" useGrayscaleRendering="false" zoomFactor="1.0" maxImageWidth="0" showGitHubPageIfSynced="false" allowBrowsingInPreview="false" synchronizePreviewPosition="true" highlightPreviewType="NONE" highlightFadeOut="5" highlightOnTyping="true" synchronizeSourcePosition="true">
|
||||||
|
<PanelProvider>
|
||||||
|
<provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.panel" providerName="Default - Swing" />
|
||||||
|
</PanelProvider>
|
||||||
|
</PreviewSettings>
|
||||||
|
<ParserSettings>
|
||||||
|
<PegdownExtensions>
|
||||||
|
<option name="ABBREVIATIONS" value="false" />
|
||||||
|
<option name="ANCHORLINKS" value="true" />
|
||||||
|
<option name="ATXHEADERSPACE" value="true" />
|
||||||
|
<option name="AUTOLINKS" value="true" />
|
||||||
|
<option name="DEFINITIONS" value="false" />
|
||||||
|
<option name="FENCED_CODE_BLOCKS" value="true" />
|
||||||
|
<option name="FOOTNOTES" value="false" />
|
||||||
|
<option name="HARDWRAPS" value="false" />
|
||||||
|
<option name="INSERTED" value="false" />
|
||||||
|
<option name="QUOTES" value="false" />
|
||||||
|
<option name="RELAXEDHRULES" value="true" />
|
||||||
|
<option name="SMARTS" value="false" />
|
||||||
|
<option name="STRIKETHROUGH" value="true" />
|
||||||
|
<option name="SUBSCRIPT" value="false" />
|
||||||
|
<option name="SUPERSCRIPT" value="false" />
|
||||||
|
<option name="SUPPRESS_HTML_BLOCKS" value="false" />
|
||||||
|
<option name="SUPPRESS_INLINE_HTML" value="false" />
|
||||||
|
<option name="TABLES" value="true" />
|
||||||
|
<option name="TASKLISTITEMS" value="true" />
|
||||||
|
<option name="TOC" value="false" />
|
||||||
|
<option name="WIKILINKS" value="true" />
|
||||||
|
</PegdownExtensions>
|
||||||
|
<ParserOptions>
|
||||||
|
<option name="COMMONMARK_LISTS" value="false" />
|
||||||
|
<option name="DUMMY" value="false" />
|
||||||
|
<option name="EMOJI_SHORTCUTS" value="true" />
|
||||||
|
<option name="FLEXMARK_FRONT_MATTER" value="false" />
|
||||||
|
<option name="GFM_TABLE_RENDERING" value="true" />
|
||||||
|
<option name="GITBOOK_URL_ENCODING" value="false" />
|
||||||
|
<option name="GITHUB_EMOJI_URL" value="false" />
|
||||||
|
<option name="GITHUB_LISTS" value="true" />
|
||||||
|
<option name="GITHUB_WIKI_LINKS" value="true" />
|
||||||
|
<option name="JEKYLL_FRONT_MATTER" value="false" />
|
||||||
|
<option name="SIM_TOC_BLANK_LINE_SPACER" value="true" />
|
||||||
|
</ParserOptions>
|
||||||
|
</ParserSettings>
|
||||||
|
<HtmlSettings headerTopEnabled="false" headerBottomEnabled="false" bodyTopEnabled="false" bodyBottomEnabled="false" embedUrlContent="false" addPageHeader="true">
|
||||||
|
<GeneratorProvider>
|
||||||
|
<provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.generator" providerName="Default Swing HTML Generator" />
|
||||||
|
</GeneratorProvider>
|
||||||
|
<headerTop />
|
||||||
|
<headerBottom />
|
||||||
|
<bodyTop />
|
||||||
|
<bodyBottom />
|
||||||
|
</HtmlSettings>
|
||||||
|
<CssSettings previewScheme="UI_SCHEME" cssUri="" isCssUriEnabled="false" isCssTextEnabled="false" isDynamicPageWidth="true">
|
||||||
|
<StylesheetProvider>
|
||||||
|
<provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.css" providerName="Default Swing Stylesheet" />
|
||||||
|
</StylesheetProvider>
|
||||||
|
<ScriptProviders />
|
||||||
|
<cssText />
|
||||||
|
</CssSettings>
|
||||||
|
<HtmlExportSettings updateOnSave="false" parentDir="$ProjectFileDir$" targetDir="$ProjectFileDir$" cssDir="" scriptDir="" plainHtml="false" imageDir="" copyLinkedImages="false" imageUniquifyType="0" targetExt="" useTargetExt="false" noCssNoScripts="false" linkToExportedHtml="true" exportOnSettingsChange="true" regenerateOnProjectOpen="false" />
|
||||||
|
<LinkMapSettings>
|
||||||
|
<textMaps />
|
||||||
|
</LinkMapSettings>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
3
.idea/markdown-navigator/profiles_settings.xml
generated
Normal file
3
.idea/markdown-navigator/profiles_settings.xml
generated
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<component name="MarkdownNavigator.ProfileManager">
|
||||||
|
<settings default="" />
|
||||||
|
</component>
|
||||||
6
.idea/misc.xml
generated
Normal file
6
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="JavaScriptSettings">
|
||||||
|
<option name="languageLevel" value="ES6" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/PetitTetonMeteor.iml" filepath="$PROJECT_DIR$/.idea/PetitTetonMeteor.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
7
.idea/vagrant.xml
generated
Normal file
7
.idea/vagrant.xml
generated
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VagrantProjectSettings">
|
||||||
|
<option name="instanceFolder" value="" />
|
||||||
|
<option name="provider" value="" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
24
.idea/watcherTasks.xml
generated
Normal file
24
.idea/watcherTasks.xml
generated
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectTasksOptions" suppressed-tasks="Less">
|
||||||
|
<TaskOptions isEnabled="false">
|
||||||
|
<option name="arguments" value="$FileName$" />
|
||||||
|
<option name="checkSyntaxErrors" value="true" />
|
||||||
|
<option name="description" value="Compiles .styl files into .css files" />
|
||||||
|
<option name="exitCodeBehavior" value="ERROR" />
|
||||||
|
<option name="fileExtension" value="styl" />
|
||||||
|
<option name="immediateSync" value="true" />
|
||||||
|
<option name="name" value="Stylus" />
|
||||||
|
<option name="output" value="$FileNameWithoutExtension$.css" />
|
||||||
|
<option name="outputFilters">
|
||||||
|
<array />
|
||||||
|
</option>
|
||||||
|
<option name="outputFromStdout" value="false" />
|
||||||
|
<option name="program" value="$USER_HOME$/AppData/Roaming/npm/stylus.cmd" />
|
||||||
|
<option name="scopeName" value="Project Files" />
|
||||||
|
<option name="trackOnlyRoot" value="true" />
|
||||||
|
<option name="workingDir" value="$FileDir$" />
|
||||||
|
<envs />
|
||||||
|
</TaskOptions>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
1223
.idea/workspace.xml
generated
Normal file
1223
.idea/workspace.xml
generated
Normal file
File diff suppressed because it is too large
Load Diff
15
.meteor/.finished-upgraders
Normal file
15
.meteor/.finished-upgraders
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# This file contains information which helps Meteor properly upgrade your
|
||||||
|
# app when you run 'meteor update'. You should check it into version control
|
||||||
|
# with your project.
|
||||||
|
|
||||||
|
notices-for-0.9.0
|
||||||
|
notices-for-0.9.1
|
||||||
|
0.9.4-platform-file
|
||||||
|
notices-for-facebook-graph-api-2
|
||||||
|
1.2.0-standard-minifiers-package
|
||||||
|
1.2.0-meteor-platform-split
|
||||||
|
1.2.0-cordova-changes
|
||||||
|
1.2.0-breaking-changes
|
||||||
|
1.3.0-split-minifiers-package
|
||||||
|
1.4.0-remove-old-dev-bundle-link
|
||||||
|
1.4.1-add-shell-server-package
|
||||||
1
.meteor/.gitignore
vendored
Normal file
1
.meteor/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
local
|
||||||
7
.meteor/.id
Normal file
7
.meteor/.id
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# This file contains a token that is unique to your project.
|
||||||
|
# Check it into your repository along with the rest of this directory.
|
||||||
|
# It can be used for purposes such as:
|
||||||
|
# - ensuring you don't accidentally deploy one app on top of another
|
||||||
|
# - providing package authors with aggregated statistics
|
||||||
|
|
||||||
|
1v2pn7n1jbklfu1hg4tnm
|
||||||
61
.meteor/packages
Normal file
61
.meteor/packages
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
# Meteor packages used by this project, one per line.
|
||||||
|
# Check this file (and the other files in this directory) into your repository.
|
||||||
|
#
|
||||||
|
# 'meteor add' and 'meteor remove' will edit this file for you,
|
||||||
|
# but you can also edit it by hand.
|
||||||
|
|
||||||
|
meteor-base@1.0.4 # Packages every Meteor app needs to have
|
||||||
|
mobile-experience@1.0.4 # Packages for a great mobile UX
|
||||||
|
mongo@1.1.14 # The database Meteor supports right now
|
||||||
|
blaze-html-templates@1.0.4 # Compile .html files into Meteor Blaze views
|
||||||
|
reactive-var@1.0.11 # Reactive variable for tracker
|
||||||
|
reactive-dict@1.1.8 # ???
|
||||||
|
jquery@1.11.10 # Helpful client-side library
|
||||||
|
tracker@1.1.1 # Meteor's client-side reactive programming library
|
||||||
|
tomwasd:history-polyfill # Adds IE 8/9 support for HTML5 history.
|
||||||
|
email # Adds the Meteor/Email package for sending lost password emails
|
||||||
|
|
||||||
|
standard-minifier-css@1.3.2 # CSS minifier run for production mode
|
||||||
|
standard-minifier-js@1.2.1 # JS minifier run for production mode
|
||||||
|
es5-shim@4.6.15 # ECMAScript 5 compatibility for older browsers.
|
||||||
|
poorvavyas:es6-shim
|
||||||
|
ecmascript # Enable ECMAScript2015+ syntax in app code
|
||||||
|
|
||||||
|
#accounts-ui
|
||||||
|
#accounts-base
|
||||||
|
accounts-password
|
||||||
|
useraccounts:core
|
||||||
|
useraccounts:bootstrap
|
||||||
|
useraccounts:flow-routing # Configures email flows. Used for AccountsTemplates class.
|
||||||
|
alanning:roles # Adds roles to the user mix. https://atmospherejs.com/alanning/roles && https://github.com/alanning/meteor-roles/blob/master/examples/flow-router/
|
||||||
|
|
||||||
|
kadira:flow-router
|
||||||
|
arillo:flow-router-helpers # Provides various template helpers such as {{pathFor 'templateName'}}
|
||||||
|
#tomwasd:flow-router-seo
|
||||||
|
kadira:blaze-layout
|
||||||
|
|
||||||
|
shell-server # ???
|
||||||
|
meteortoys:allthings
|
||||||
|
stylus
|
||||||
|
session
|
||||||
|
##browser-policy # Adds support for specifying browser level security rules related to content and what's allowed to laod on the page.
|
||||||
|
check # Allows for checking the structure and types of arguments passed to Meteor methods and publications.
|
||||||
|
#audit-argument-checks # Used in combination with the Check package for checking the structure and types of arguments passed to Meteor methods and publications. Automatically alerts when a method or publication does not use a check() call.
|
||||||
|
|
||||||
|
aldeed:simple-schema@1.5.3
|
||||||
|
aldeed:collection2@2.10.0
|
||||||
|
matb33:collection-hooks # Allows the collections to register handlers that run before or after database interactions.
|
||||||
|
zimme:collection-softremovable
|
||||||
|
|
||||||
|
#aldeed:autoform@5.8.1
|
||||||
|
#aldeed:collection2-core@2.0.0
|
||||||
|
#aldeed:schema-deny # Addon for Collection2-core to use denyInsert or denyUpdate options.
|
||||||
|
#aldeed:schema-index # Addon for Collection2-core to use index or unique options.
|
||||||
|
#skehoe1989:autoform-relations # Adds relations to autoform
|
||||||
|
|
||||||
|
twbs:bootstrap
|
||||||
|
fortawesome:fontawesome
|
||||||
|
momentjs:moment
|
||||||
|
mizzao:bootboxjs # ???
|
||||||
|
aldeed:template-extension
|
||||||
|
juliancwirko:s-alert # Client error/alert handling
|
||||||
2
.meteor/platforms
Normal file
2
.meteor/platforms
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
server
|
||||||
|
browser
|
||||||
1
.meteor/release
Normal file
1
.meteor/release
Normal file
@@ -0,0 +1 @@
|
|||||||
|
METEOR@1.4.2.3
|
||||||
128
.meteor/versions
Normal file
128
.meteor/versions
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
accounts-base@1.2.14
|
||||||
|
accounts-password@1.3.3
|
||||||
|
alanning:roles@1.2.15
|
||||||
|
aldeed:collection2@2.10.0
|
||||||
|
aldeed:collection2-core@1.2.0
|
||||||
|
aldeed:schema-deny@1.1.0
|
||||||
|
aldeed:schema-index@1.1.1
|
||||||
|
aldeed:simple-schema@1.5.3
|
||||||
|
aldeed:template-extension@4.0.0
|
||||||
|
allow-deny@1.0.5
|
||||||
|
arillo:flow-router-helpers@0.5.2
|
||||||
|
autoupdate@1.2.11
|
||||||
|
babel-compiler@6.13.0
|
||||||
|
babel-runtime@1.0.1
|
||||||
|
base64@1.0.10
|
||||||
|
binary-heap@1.0.10
|
||||||
|
blaze@2.1.9
|
||||||
|
blaze-html-templates@1.0.5
|
||||||
|
blaze-tools@1.0.10
|
||||||
|
boilerplate-generator@1.0.11
|
||||||
|
caching-compiler@1.1.9
|
||||||
|
caching-html-compiler@1.0.7
|
||||||
|
callback-hook@1.0.10
|
||||||
|
check@1.2.4
|
||||||
|
coffeescript@1.0.17
|
||||||
|
ddp@1.2.5
|
||||||
|
ddp-client@1.2.9
|
||||||
|
ddp-common@1.2.8
|
||||||
|
ddp-rate-limiter@1.0.6
|
||||||
|
ddp-server@1.2.10
|
||||||
|
deps@1.0.12
|
||||||
|
diff-sequence@1.0.7
|
||||||
|
ecmascript@0.6.1
|
||||||
|
ecmascript-runtime@0.3.15
|
||||||
|
ejson@1.0.13
|
||||||
|
email@1.1.18
|
||||||
|
es5-shim@4.6.15
|
||||||
|
fastclick@1.0.13
|
||||||
|
fortawesome:fontawesome@4.7.0
|
||||||
|
geojson-utils@1.0.10
|
||||||
|
hot-code-push@1.0.4
|
||||||
|
html-tools@1.0.11
|
||||||
|
htmljs@1.0.11
|
||||||
|
http@1.1.8
|
||||||
|
id-map@1.0.9
|
||||||
|
jquery@1.11.10
|
||||||
|
juliancwirko:s-alert@3.2.0
|
||||||
|
kadira:blaze-layout@2.3.0
|
||||||
|
kadira:flow-router@2.12.1
|
||||||
|
launch-screen@1.0.12
|
||||||
|
livedata@1.0.18
|
||||||
|
localstorage@1.0.12
|
||||||
|
logging@1.1.16
|
||||||
|
matb33:collection-hooks@0.8.4
|
||||||
|
mdg:validation-error@0.2.0
|
||||||
|
meteor@1.6.0
|
||||||
|
meteor-base@1.0.4
|
||||||
|
meteortoys:allthings@3.0.0
|
||||||
|
meteortoys:authenticate@3.0.0
|
||||||
|
meteortoys:autopub@3.0.0
|
||||||
|
meteortoys:blueprint@3.0.0
|
||||||
|
meteortoys:email@3.0.0
|
||||||
|
meteortoys:hotreload@3.0.0
|
||||||
|
meteortoys:listen@3.0.0
|
||||||
|
meteortoys:method@3.0.4
|
||||||
|
meteortoys:pub@3.0.4
|
||||||
|
meteortoys:result@3.0.0
|
||||||
|
meteortoys:shell@3.0.0
|
||||||
|
meteortoys:status@3.0.0
|
||||||
|
meteortoys:sub@3.0.0
|
||||||
|
meteortoys:throttle@3.0.0
|
||||||
|
meteortoys:toykit@3.0.4
|
||||||
|
minifier-css@1.2.15
|
||||||
|
minifier-js@1.2.15
|
||||||
|
minimongo@1.0.19
|
||||||
|
mizzao:bootboxjs@4.4.0
|
||||||
|
mobile-experience@1.0.4
|
||||||
|
mobile-status-bar@1.0.13
|
||||||
|
modules@0.7.7
|
||||||
|
modules-runtime@0.7.7
|
||||||
|
momentjs:moment@2.17.1
|
||||||
|
mongo@1.1.14
|
||||||
|
mongo-id@1.0.6
|
||||||
|
msavin:jetsetter@2.0.0
|
||||||
|
msavin:mongol@2.0.1
|
||||||
|
npm-bcrypt@0.9.2
|
||||||
|
npm-mongo@2.2.11_2
|
||||||
|
observe-sequence@1.0.14
|
||||||
|
ordered-dict@1.0.9
|
||||||
|
poorvavyas:es6-shim@0.21.1
|
||||||
|
promise@0.8.8
|
||||||
|
raix:eventemitter@0.1.3
|
||||||
|
random@1.0.10
|
||||||
|
rate-limit@1.0.6
|
||||||
|
reactive-dict@1.1.8
|
||||||
|
reactive-var@1.0.11
|
||||||
|
reload@1.1.11
|
||||||
|
retry@1.0.9
|
||||||
|
routepolicy@1.0.12
|
||||||
|
service-configuration@1.0.11
|
||||||
|
session@1.1.7
|
||||||
|
sha@1.0.9
|
||||||
|
shell-server@0.2.1
|
||||||
|
softwarerero:accounts-t9n@1.3.6
|
||||||
|
spacebars@1.0.13
|
||||||
|
spacebars-compiler@1.0.13
|
||||||
|
srp@1.0.10
|
||||||
|
standard-minifier-css@1.3.2
|
||||||
|
standard-minifier-js@1.2.1
|
||||||
|
stylus@2.513.8
|
||||||
|
templating@1.2.15
|
||||||
|
templating-compiler@1.2.15
|
||||||
|
templating-runtime@1.2.15
|
||||||
|
templating-tools@1.0.5
|
||||||
|
tomwasd:history-polyfill@0.0.1
|
||||||
|
tracker@1.1.1
|
||||||
|
twbs:bootstrap@3.3.6
|
||||||
|
ui@1.0.12
|
||||||
|
underscore@1.0.10
|
||||||
|
url@1.0.11
|
||||||
|
useraccounts:bootstrap@1.14.2
|
||||||
|
useraccounts:core@1.14.2
|
||||||
|
useraccounts:flow-routing@1.14.2
|
||||||
|
webapp@1.3.12
|
||||||
|
webapp-hashing@1.0.9
|
||||||
|
zimme:active-route@2.3.2
|
||||||
|
zimme:collection-behaviours@1.0.4
|
||||||
|
zimme:collection-softremovable@1.0.5
|
||||||
22
LICENSE
Normal file
22
LICENSE
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
========================================
|
||||||
|
Meteor is licensed under the MIT License
|
||||||
|
========================================
|
||||||
|
|
||||||
|
Copyright (C) 2011--2016 Meteor Development Group
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
19
README IMPORT.md
Normal file
19
README IMPORT.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
To import data, place the data in the /private folder, then write a script in the /server folder (javascript).
|
||||||
|
|
||||||
|
The script file should define Meteor methods:
|
||||||
|
```
|
||||||
|
|
||||||
|
Meteor.methods({
|
||||||
|
"importSomethingOfMine": function() {
|
||||||
|
//Your script here.
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Then run meteor.
|
||||||
|
|
||||||
|
Then at the terminal (in your WebStorm UI, or at a command line (at the project root path), run `meteor shell` to open a server side shell.
|
||||||
|
|
||||||
|
Once in the shell, you can write javascript code that will be executed.
|
||||||
|
|
||||||
|
Type `Meteor.call('importSomethingOfMine')` and hit the enter key and it will execute the method you defined earlier.
|
||||||
89
README.md
Normal file
89
README.md
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
# Petit Teton Data Management Application (PTApp)
|
||||||
|
|
||||||
|
This application is designed to track sales and production data.
|
||||||
|
|
||||||
|
In a development environment, the application will create the database if it doesn't exist, naming it "meteor" and will run the database on localhost:3001. The application's web interface will be accessible on localhost:3000.
|
||||||
|
These can be changed in development mode by setting environment variables.
|
||||||
|
|
||||||
|
At runtime (production environment), the application should be deployed on a linux machine.
|
||||||
|
Package this application by running 'npm run build' from the command line in the project base directory, or double click the npm "build" script in the development environment.
|
||||||
|
|
||||||
|
1. Install MongoDB on the linux machine.
|
||||||
|
1. `sudo apt-get update`
|
||||||
|
1. `sudo apt-get install -y mongodb` (installs 2.6.10 on Ubuntu LTS 16.04 - that is the minimum version of mongo required for Meteor 1.4 - you should install the latest mongo: 3.2 per the meteor install instructions)
|
||||||
|
|
||||||
|
**OR**
|
||||||
|
|
||||||
|
See [instructions](https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/) for installing newer versions of MongoDB (RECOMMENDED)
|
||||||
|
1. Get the version of the mongo command line tool: `sudo mongo --version`
|
||||||
|
1. Get the version of the mongo server: `sudo mongod --version`
|
||||||
|
1. Start/stop/restart the mongo service: `sudo service mongod stop/start/restart`
|
||||||
|
1. View logs: `/var/log/mongodb/mongod.log`
|
||||||
|
1. Edit config: `/etc/mongod.conf` (see [docs](https://docs.mongodb.com/manual/reference/configuration-options/))
|
||||||
|
1. Run tools: (see [descriptions](https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/#packages))
|
||||||
|
- mongod (the mongo database server)
|
||||||
|
- mongo (command line shell for interacting with a running db)
|
||||||
|
- mongoimport (imports data from: Extended JSON, CSV, or TSV formats created by mongoexport or 3rd party tools)
|
||||||
|
- bsondump (converts bson file formats [binary] into human readable formats [JSON] - use with mongodump files)
|
||||||
|
- mongodump (produces binary output for backups - not for use with shared clusters and replica sets)
|
||||||
|
- mongoexport (produces JSON or CSV data)
|
||||||
|
- mongofiles (command line gridfs integration - for manipulating files)
|
||||||
|
- mongooplog (replication & polling - ?)
|
||||||
|
- mongoperf
|
||||||
|
- mongorestore
|
||||||
|
- mongostat
|
||||||
|
- mongotop (stats)
|
||||||
|
1. Install nodejs & npm
|
||||||
|
1. `sudo apt-get install nodejs`
|
||||||
|
1. `sudo apt-get install npm`
|
||||||
|
1. Install n
|
||||||
|
1. `sudo npm install -g n`
|
||||||
|
1. Update nodejs to 4.7.0 (for use with meteor 1.4 - may be another nodejs version for newer meteor versions): `n bin 4.7.0` (may need to first download 4.7.0 - see other docs on linux & nodejs)
|
||||||
|
1. `sudo n 4.7.0`
|
||||||
|
1. `sudo npm install -g npm` (updates npm?)
|
||||||
|
1. Install nginx on the linux machine.
|
||||||
|
1. Install samba on the linux machine. (`sudo nano /etc/samba/smb.conf` & `sudo service smbd restart`)
|
||||||
|
1. Share the /var/www directory using the www-data user.
|
||||||
|
1. Share the /etc/nginx directory using the root user (optional & security risk - makes configuring /etc/nginx/sites-available easier).
|
||||||
|
1. Share the nginx logs directory /var/logs/nginx using a standard user with read only access (maybe www-data?).
|
||||||
|
1. Install passenger which will glue the nginx web server to one or more instances of nodejs/meteor running on the machine. (See passenger site for updated install instructions - these are specific to Ubuntu)
|
||||||
|
1. `sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7`
|
||||||
|
1. `sudo apt-get install -y apt-transport-https ca-certificates`
|
||||||
|
1. `sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger xenial main > /etc/apt/sources.list.d/passenger.list'`
|
||||||
|
1. `sudo apt-get update`
|
||||||
|
1. `sudo apt-get install -y nginx-extras passenger`
|
||||||
|
1. Configure the nginx sites-available file ("PTapp") to link nginx to passenger, and provide passenger the settings to startup meteor. Example: (replace {{xxxx}} with your own content) (NOTE: setting the mail_url fails, I used a release.properties file in the app's private directory instead, with code to use the properties file first in the server.js file in meteor.)
|
||||||
|
```
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
server_name app.petitteton.com;
|
||||||
|
root /var/www/PTApp/bundle/public;
|
||||||
|
# Turn on Passenger
|
||||||
|
passenger_enabled on;
|
||||||
|
# Tell Passenger that your app is a Meteor app
|
||||||
|
passenger_app_type node;
|
||||||
|
passenger_startup_file main.js;
|
||||||
|
# Tell your app where MongoDB is
|
||||||
|
passenger_env_var MONGO_URL {{your mongodb address/port/dbname. Example: mongodb://localhost:27017/PTApp}};
|
||||||
|
# Tell your app what its root URL is
|
||||||
|
passenger_env_var ROOT_URL http://app.petitteton.com;
|
||||||
|
#passenger_env_var MAIL_URL smtp://{{your email. example: administrator%40declarativeengineering.com}}:{{smtp password here - don't use symbols like # or $ etc}}@{{your email server. Example: secure.emailsrvr.com}};
|
||||||
|
passenger_nodejs /usr/local/n/versions/node/4.7.0/bin/node;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
1. Restart nginx: `sudo service nginx restart`
|
||||||
|
1. Get status with `sudo passenger-status`
|
||||||
|
1. Stop passenger & nginx: `sudo service nginx stop` (use start or restart or reload also)
|
||||||
|
1. Create an app folder in /var/www (example: PTApp)
|
||||||
|
1. Unpack the packaged application into this new folder (easily done via the samba share on the windows development machine by drag and dropping the contents of the archive created in step 1).
|
||||||
|
1. Install the app with npm (navigate to /var/www/PTApp/bundle/programs/server): `npm install --production`
|
||||||
|
1. **Restart the passenger app each time the application is updated**: `sudo passenger-config restart-app /var/www/PTApp`
|
||||||
|
1. Use RDP to connect to the GUI for the linux server
|
||||||
|
1. Install Mongo Chef (free version) to connect to the db on localhost:27017
|
||||||
|
1. Download the archive.
|
||||||
|
1. Move the unpacked archive into /opt
|
||||||
|
1. Modify the ~/.bashrc to include: `PATH=$PATH:/opt/mongochef-3.5.0-linux-x86-dist/bin` at the end (not sure if this is necessary).
|
||||||
|
1. Run Mongo Chef from the GUI environment (how? - probably use the start menu -> Run, then pass the path like above + the executable name)
|
||||||
|
|
||||||
|
NOTE: Use MongoBooster on a windows development machine to connect to the dev database (localhost:3001) and to export.
|
||||||
69
client/bootstrap.styl
vendored
Normal file
69
client/bootstrap.styl
vendored
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
textarea:focus,
|
||||||
|
input[type="text"]:focus,
|
||||||
|
input[type="password"]:focus,
|
||||||
|
input[type="datetime"]:focus,
|
||||||
|
input[type="datetime-local"]:focus,
|
||||||
|
input[type="date"]:focus,
|
||||||
|
input[type="month"]:focus,
|
||||||
|
input[type="time"]:focus,
|
||||||
|
input[type="week"]:focus,
|
||||||
|
input[type="number"]:focus,
|
||||||
|
input[type="email"]:focus,
|
||||||
|
input[type="url"]:focus,
|
||||||
|
input[type="search"]:focus,
|
||||||
|
input[type="tel"]:focus,
|
||||||
|
input[type="color"]:focus,
|
||||||
|
.uneditable-input:focus,
|
||||||
|
.list-group:focus {
|
||||||
|
border-color: rgba(82, 168, 236, 0.8);
|
||||||
|
outline: 0;
|
||||||
|
outline: thin dotted \9;
|
||||||
|
/* IE6-9 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
-webkit-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);
|
||||||
|
*/
|
||||||
|
-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;
|
||||||
|
box-shadow: 0px 0px 46px -13px rgba(230,28,230,1) !important;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control, .select2-selection {
|
||||||
|
font-size: 14px;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2 .select2-selection {
|
||||||
|
border-color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container--default.select2-container--focus .select2-selection--multiple {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
.has-error {
|
||||||
|
border-color: #a94442 !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;
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
-webkit-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;
|
||||||
|
*/
|
||||||
|
}
|
||||||
53
client/client.js
Normal file
53
client/client.js
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import {Meteor} from 'meteor/meteor';
|
||||||
|
import '/imports/startup/client'
|
||||||
|
import '/imports/startup/both'
|
||||||
|
import '/imports/api';
|
||||||
|
import '/imports/ui/helpers.js';
|
||||||
|
import '/imports/util/validator.js';
|
||||||
|
import '/imports/util/blaze.js';
|
||||||
|
import '/imports/util/date.js';
|
||||||
|
import '/imports/util/de.combo.js';
|
||||||
|
import '/imports/util/resize/ResizeSensor.js';
|
||||||
|
import '/imports/util/resize/ElementQueries.js';
|
||||||
|
import '/imports/ui/layouts/Body.js';
|
||||||
|
import '/imports/ui/layouts/Full.js';
|
||||||
|
import '/imports/ui/accounts/accounts.js';
|
||||||
|
|
||||||
|
Blaze._allowJavascriptUrls();
|
||||||
|
|
||||||
|
Meteor.subscribe("measures");
|
||||||
|
Meteor.subscribe("venues");
|
||||||
|
Meteor.subscribe("categories");
|
||||||
|
Meteor.subscribe("subcategories");
|
||||||
|
Meteor.subscribe("items");
|
||||||
|
|
||||||
|
Meteor.startup(function () {
|
||||||
|
sAlert.config({
|
||||||
|
effect: '',
|
||||||
|
position: 'bottom-right',
|
||||||
|
timeout: 5000,
|
||||||
|
html: false,
|
||||||
|
onRouteClose: true,
|
||||||
|
stack: true,
|
||||||
|
// or you can pass an object:
|
||||||
|
// stack: {
|
||||||
|
// spacing: 10 // in px
|
||||||
|
// limit: 3 // when fourth alert appears all previous ones are cleared
|
||||||
|
// }
|
||||||
|
offset: 0, // in px - will be added to first alert (bottom or top - depends of the position in config)
|
||||||
|
beep: false,
|
||||||
|
// examples:
|
||||||
|
// beep: '/beep.mp3' // or you can pass an object:
|
||||||
|
// beep: {
|
||||||
|
// info: '/beep-info.mp3',
|
||||||
|
// error: '/beep-error.mp3',
|
||||||
|
// success: '/beep-success.mp3',
|
||||||
|
// warning: '/beep-warning.mp3'
|
||||||
|
// }
|
||||||
|
onClose: _.noop //
|
||||||
|
// examples:
|
||||||
|
// onClose: function() {
|
||||||
|
// /* Code here will be executed once the alert closes. */
|
||||||
|
// }
|
||||||
|
});
|
||||||
|
});
|
||||||
4
client/head.html
Normal file
4
client/head.html
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<head>
|
||||||
|
<title>PT App</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
</head>
|
||||||
74
client/main.styl
Normal file
74
client/main.styl
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
*
|
||||||
|
box-sizing: border-box
|
||||||
|
-webkit-tap-highlight-color: transparent
|
||||||
|
-webkit-font-smoothing: antialiased
|
||||||
|
|
||||||
|
html
|
||||||
|
scrollbar-face-color: #808080
|
||||||
|
scrollbar-highlight-color: #808080
|
||||||
|
scrollbar-3dlight-color: #707070
|
||||||
|
scrollbar-darkshadow-color: #808080
|
||||||
|
scrollbar-shadow-color: #7e7e7e
|
||||||
|
scrollbar-arrow-color: #ffffff
|
||||||
|
scrollbar-track-color: #505050
|
||||||
|
height: 100%
|
||||||
|
|
||||||
|
html, body, #archives ul, #overall-footer, #content ul
|
||||||
|
margin: 0 0 0 0
|
||||||
|
padding: 0 0 0 0
|
||||||
|
|
||||||
|
body
|
||||||
|
font-family: verdana, arial, helvetica, sans-serif
|
||||||
|
font-size: 1.0em
|
||||||
|
height: 100%
|
||||||
|
|
||||||
|
#__blaze-root
|
||||||
|
//max-width: 950px //Use if the width should be limited.
|
||||||
|
//min-width: 250px
|
||||||
|
//margin: 0 auto //Use if the width should be limited.
|
||||||
|
//min-height: 100% //Used with a full height layout.
|
||||||
|
|
||||||
|
//Flex container.
|
||||||
|
//display: flex
|
||||||
|
//flex-direction: row
|
||||||
|
//flex-wrap: nowrap
|
||||||
|
//align-items: stretch
|
||||||
|
//align-content: stretch
|
||||||
|
height: 100%;
|
||||||
|
//width: 100%;
|
||||||
|
//min-height: 100%;
|
||||||
|
//min-width: 100%;
|
||||||
|
|
||||||
|
.noselect
|
||||||
|
-webkit-touch-callout: none; /* iOS Safari */
|
||||||
|
-webkit-user-select: none; /* Chrome/Safari/Opera */
|
||||||
|
-khtml-user-select: none; /* Konqueror */
|
||||||
|
-moz-user-select: none; /* Firefox */
|
||||||
|
-ms-user-select: none; /* Internet Explorer/Edge */
|
||||||
|
user-select: none; /* Non-prefixed version, currently not supported by any browser */
|
||||||
|
.clickable
|
||||||
|
cursor: pointer
|
||||||
|
.nonclickable
|
||||||
|
cursor: default
|
||||||
|
.left
|
||||||
|
text-align: left
|
||||||
|
.center
|
||||||
|
text-align: center
|
||||||
|
|
||||||
|
|
||||||
|
//@import "../imports/util/selectize/selectize.default.import.styl"
|
||||||
|
//@import "../imports/util/selectize/selectize.import.styl"
|
||||||
|
@import "../imports/util/de.combo.import.styl"
|
||||||
|
|
||||||
|
@import "../imports/ui/layouts/Body.import.styl"
|
||||||
|
@import "../imports/ui/layouts/Full.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/Products.import.styl"
|
||||||
|
@import "../imports/ui/ProductTags.import.styl"
|
||||||
|
@import "../imports/ui/Sales.import.styl"
|
||||||
|
@import "../imports/ui/Pricing.import.styl"
|
||||||
|
@import "../imports/ui/Production.import.styl"
|
||||||
1245
client/titatoggle-dist.css
Normal file
1245
client/titatoggle-dist.css
Normal file
File diff suppressed because it is too large
Load Diff
130
imports/api/Measure.js
Normal file
130
imports/api/Measure.js
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
import { Meteor } from 'meteor/meteor';
|
||||||
|
import { Mongo } from 'meteor/mongo';
|
||||||
|
import { check } from 'meteor/check';
|
||||||
|
import {SimpleSchema} from 'meteor/aldeed:simple-schema';
|
||||||
|
|
||||||
|
Measures = new Mongo.Collection('Measures');
|
||||||
|
Measures.attachSchema(new SimpleSchema({
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
label: "Name",
|
||||||
|
optional: false,
|
||||||
|
trim: true,
|
||||||
|
index: 1,
|
||||||
|
unique: true
|
||||||
|
},
|
||||||
|
postfix: {
|
||||||
|
type: String,
|
||||||
|
label: "Postfix",
|
||||||
|
optional: true, //Note: Each does not have a postfix.
|
||||||
|
trim: true
|
||||||
|
},
|
||||||
|
order: {
|
||||||
|
type: SimpleSchema.Integer,
|
||||||
|
label: "Order",
|
||||||
|
optional: false,
|
||||||
|
min: 0
|
||||||
|
},
|
||||||
|
createdAt: { //Force the value to the current date on the server.
|
||||||
|
type: Date,
|
||||||
|
label: "Created On",
|
||||||
|
// autoValue: function() { //The disadvantage of autoValue is that it sets the date after insertion, causing the UI to update twice - once where the item has no date, and then again where the date is set. Sorted lists will cause the item to bounce around.
|
||||||
|
// if(this.isInsert) return new Date();
|
||||||
|
// else if(this.isUpsert) return {$setOnInsert: new Date()};
|
||||||
|
// else this.unset();
|
||||||
|
// },
|
||||||
|
// denyUpdate: true,
|
||||||
|
optional: false
|
||||||
|
},
|
||||||
|
updatedAt: {
|
||||||
|
type: Date,
|
||||||
|
label: "Updated On",
|
||||||
|
// autoValue: function() {
|
||||||
|
// if(this.isUpdate) return new Date();
|
||||||
|
// },
|
||||||
|
// denyInsert: true,
|
||||||
|
optional: true
|
||||||
|
},
|
||||||
|
deletedAt: {
|
||||||
|
type: Date,
|
||||||
|
label: "Deleted On",
|
||||||
|
optional: true
|
||||||
|
},
|
||||||
|
deletedBy: {
|
||||||
|
type: String,
|
||||||
|
label: "Deleted By",
|
||||||
|
optional: true
|
||||||
|
},
|
||||||
|
restoredAt: {
|
||||||
|
type: Date,
|
||||||
|
label: "Restored On",
|
||||||
|
optional: true
|
||||||
|
},
|
||||||
|
restoredBy: {
|
||||||
|
type: String,
|
||||||
|
label: "Restored By",
|
||||||
|
optional: true
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
//https://github.com/zimme/meteor-collection-softremovable
|
||||||
|
Measures.attachBehaviour("softRemovable", {
|
||||||
|
removed: 'deleted',
|
||||||
|
removedAt: 'deletedAt',
|
||||||
|
removedBy: 'removedBy',
|
||||||
|
restoredAt: 'restoredAt',
|
||||||
|
restoredBy: 'restoredBy'
|
||||||
|
});
|
||||||
|
|
||||||
|
if(Meteor.isServer) Meteor.publish('measures', function() {
|
||||||
|
return Measures.find({});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Requires: meteor add matb33:collection-hooks
|
||||||
|
Measures.before.insert(function(userId, doc) {
|
||||||
|
// check(userId, String);
|
||||||
|
doc.createdAt = new Date();
|
||||||
|
});
|
||||||
|
Measures.before.update(function(userId, doc, fieldNames, modifier, options) {
|
||||||
|
modifier.$set = modifier.$set || {}; //Make sure there is an object.
|
||||||
|
modifier.$set.updatedAt = new Date();
|
||||||
|
});
|
||||||
|
|
||||||
|
if(Meteor.isServer) {
|
||||||
|
Meteor.methods({
|
||||||
|
insertMeasure: function(measure) {
|
||||||
|
check(measure, {
|
||||||
|
name: String,
|
||||||
|
order: Number,
|
||||||
|
postfix: String
|
||||||
|
});
|
||||||
|
|
||||||
|
measure.createdAt = new Date();
|
||||||
|
|
||||||
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||||
|
Measures.insert(measure);
|
||||||
|
}
|
||||||
|
else throw new Meteor.Error(403, "Not authorized.");
|
||||||
|
},
|
||||||
|
deleteMeasure: function(id) {
|
||||||
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||||
|
Measures.remove(id);
|
||||||
|
}
|
||||||
|
else throw new Meteor.Error(403, "Not authorized.");
|
||||||
|
},
|
||||||
|
updateMeasure: function(measure) {
|
||||||
|
check(measure, {
|
||||||
|
name: String,
|
||||||
|
order: Number,
|
||||||
|
postfix: String
|
||||||
|
});
|
||||||
|
|
||||||
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||||
|
Products.update(id, {$set: {name: measure.name, order: measure.order, postfix: measure.postfix, updateAt: new Date()}});
|
||||||
|
}
|
||||||
|
else throw new Meteor.Error(403, "Not authorized.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Measures;
|
||||||
268
imports/api/Product.js
Normal file
268
imports/api/Product.js
Normal file
@@ -0,0 +1,268 @@
|
|||||||
|
import { Meteor } from 'meteor/meteor';
|
||||||
|
import { Mongo } from 'meteor/mongo';
|
||||||
|
import { check } from 'meteor/check';
|
||||||
|
import {SimpleSchema} from 'meteor/aldeed:simple-schema';
|
||||||
|
|
||||||
|
Products = new Mongo.Collection('Products');
|
||||||
|
|
||||||
|
const ProductsSchema = new SimpleSchema({
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
label: "Name",
|
||||||
|
optional: false,
|
||||||
|
trim: true,
|
||||||
|
index: 1,
|
||||||
|
unique: true
|
||||||
|
},
|
||||||
|
tags: { //An array of ProductTag names. Note that we are not using the ProductTag ID's because I want a looser connection (if a ProductTag is deleted, it isn't a big deal if it isn't maintained in the Product records).
|
||||||
|
type: [String],
|
||||||
|
label: "Tags",
|
||||||
|
optional: false,
|
||||||
|
defaultValue: []
|
||||||
|
},
|
||||||
|
measures: { //A JSON array of Measure ID's.
|
||||||
|
type: Array,
|
||||||
|
label: "Measures",
|
||||||
|
optional: false,
|
||||||
|
defaultValue: []
|
||||||
|
},
|
||||||
|
'measures.$': {
|
||||||
|
type: String,
|
||||||
|
label: "Measure ID",
|
||||||
|
regEx: SimpleSchema.RegEx.Id
|
||||||
|
},
|
||||||
|
aliases: { //A JSON array of alternate names.
|
||||||
|
type: Array,
|
||||||
|
label: "Aliases",
|
||||||
|
optional: false,
|
||||||
|
defaultValue: []
|
||||||
|
},
|
||||||
|
'aliases.$': {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
prices: { //A JSON object mapping Measure ID's to price data for this item. Price data is an object with price, effectiveDate, previousPrice. Example: prices: {XZ5Z3CM49NDrJNADA: {price: 10.5, effectiveDate: ISODate("2017-01-12T13:14:18.876-08:00"), previousPrice: 9}, ...}
|
||||||
|
type: Object,
|
||||||
|
//blackbox: true,
|
||||||
|
custom: function() {
|
||||||
|
console.log("In custom validation for prices");
|
||||||
|
return true;
|
||||||
|
// if(this.value != undefined) {
|
||||||
|
// console.log(this.value);
|
||||||
|
// //check(this, Object);
|
||||||
|
// if(!_.isObject(this.value)) {
|
||||||
|
// return "expectObject";
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// for(let measureId of _.allKeys(this.value)) {
|
||||||
|
// //check(measureId, String); //Should be a Mongo ID
|
||||||
|
// if(!_.isString(measureId)) {
|
||||||
|
// console.log("Expected a Mongo ID as attribute names of the Product.prices object.");
|
||||||
|
// return "expectString";
|
||||||
|
// }
|
||||||
|
// //check(this.value[measureId], Object);
|
||||||
|
// let measureData = this.value[measureId];
|
||||||
|
// if(!_.isObject(measureData)) {
|
||||||
|
// console.log("Expected an Object containing price, and optionally (previousPrice & effectiveDate).");
|
||||||
|
// return "expectObject";
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if(_.has(measureData, "price")) {
|
||||||
|
// //check(measureData.price, Number);
|
||||||
|
// if(!_.isNumber(measureData.price)) {
|
||||||
|
// console.log("Expected a Number for 'price'.");
|
||||||
|
// return "expectNumber";
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// //If previous price exists then it must be a number, and effective date must exist and be a date.
|
||||||
|
// if(_.has(measureData, "previousPrice")) {
|
||||||
|
// //check(measureData.effectiveDate, Date);
|
||||||
|
// if(!_.isDate(measureData.effectiveDate)) {
|
||||||
|
// console.log("Expected a Date for 'effectiveDate'.");
|
||||||
|
// return "expectDate";
|
||||||
|
// }
|
||||||
|
// //check(measureData.previousPrice, Number);
|
||||||
|
// if(!_.isDate(measureData.previousPrice)) {
|
||||||
|
// console.log("Expected a Number for 'previousPrice'.");
|
||||||
|
// return "expectNumber";
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// //check(measureData.effectiveDate, undefined);
|
||||||
|
// if(_.isSet(measureData.effectiveDate)) {
|
||||||
|
// console.log("Expected 'effectiveDate' to be undefined.");
|
||||||
|
// return "notAllowed";
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// //check(measureData.effectiveDate, undefined);
|
||||||
|
// if(_.isSet(measureData.effectiveDate)) {
|
||||||
|
// console.log("Expected 'effectiveDate' to be undefined.");
|
||||||
|
// return "notAllowed";
|
||||||
|
// }
|
||||||
|
// //check(measureData.previousPrice, undefined);
|
||||||
|
// if(_.isSet(measureData.previousPrice)) {
|
||||||
|
// console.log("Expected 'previousPrice' to be undefined.");
|
||||||
|
// return "notAllowed";
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
createdAt: {
|
||||||
|
type: Date,
|
||||||
|
label: "Created On",
|
||||||
|
optional: false
|
||||||
|
},
|
||||||
|
updatedAt: {
|
||||||
|
type: Date,
|
||||||
|
label: "Updated On",
|
||||||
|
optional: true
|
||||||
|
},
|
||||||
|
deletedAt: {
|
||||||
|
type: Date,
|
||||||
|
label: "Deleted On",
|
||||||
|
optional: true
|
||||||
|
},
|
||||||
|
deletedBy: {
|
||||||
|
type: String,
|
||||||
|
label: "Deleted By",
|
||||||
|
optional: true
|
||||||
|
},
|
||||||
|
restoredAt: {
|
||||||
|
type: Date,
|
||||||
|
label: "Restored On",
|
||||||
|
optional: true
|
||||||
|
},
|
||||||
|
restoredBy: {
|
||||||
|
type: String,
|
||||||
|
label: "Restored By",
|
||||||
|
optional: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Note: Could not figure out how to setup a schema for prices where prices is an object whose keys are id's of measures, and whose values are objects containing price data (see comments above for more details on price data).
|
||||||
|
// 'prices.$': {
|
||||||
|
// type: new SimpleSchema({
|
||||||
|
// measureId: {
|
||||||
|
// type: String,
|
||||||
|
// label: "Measure Id",
|
||||||
|
// trim: false,
|
||||||
|
// regEx: SimpleSchema.RegEx.Id,
|
||||||
|
// optional: false
|
||||||
|
// },
|
||||||
|
// price: {
|
||||||
|
// type: Number,
|
||||||
|
// label: "Price",
|
||||||
|
// min: 0,
|
||||||
|
// exclusiveMin: true,
|
||||||
|
// optional: false
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// },
|
||||||
|
|
||||||
|
//Products.attachSchema(ProductsSchema);
|
||||||
|
|
||||||
|
//https://github.com/zimme/meteor-collection-softremovable
|
||||||
|
Products.attachBehaviour("softRemovable", {
|
||||||
|
removed: 'deleted',
|
||||||
|
removedAt: 'deletedAt',
|
||||||
|
removedBy: 'removedBy',
|
||||||
|
restoredAt: 'restoredAt',
|
||||||
|
restoredBy: 'restoredBy'
|
||||||
|
});
|
||||||
|
|
||||||
|
if(Meteor.isServer) {
|
||||||
|
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}});
|
||||||
|
});
|
||||||
|
|
||||||
|
Meteor.methods({
|
||||||
|
insertProduct: function(product) {
|
||||||
|
check(product, {
|
||||||
|
name: String
|
||||||
|
});
|
||||||
|
|
||||||
|
product.createdAt = new Date();
|
||||||
|
|
||||||
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||||
|
Products.insert(product, function(err, id) {
|
||||||
|
if(err) console.log(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else throw new Meteor.Error(403, "Not authorized.");
|
||||||
|
},
|
||||||
|
deleteProduct: function(id) {
|
||||||
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||||
|
Products.remove(id);
|
||||||
|
}
|
||||||
|
else throw new Meteor.Error(403, "Not authorized.");
|
||||||
|
},
|
||||||
|
updateProduct: function(product) {
|
||||||
|
check(product, {
|
||||||
|
_id: String,
|
||||||
|
name: String
|
||||||
|
});
|
||||||
|
|
||||||
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||||
|
Products.update(id, {$set: {name: product.name, updateAt: new Date()}});
|
||||||
|
}
|
||||||
|
else throw new Meteor.Error(403, "Not authorized.");
|
||||||
|
},
|
||||||
|
setProductPrice: function(productId, measureId, price, setPrevious, effectiveDate) {
|
||||||
|
check(productId, String);
|
||||||
|
check(measureId, String);
|
||||||
|
check(price, Number);
|
||||||
|
check(setPrevious, Boolean);
|
||||||
|
check(effectiveDate, Date);
|
||||||
|
|
||||||
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||||
|
let product = Products.findOne(productId, {fields: {prices: 1}});
|
||||||
|
|
||||||
|
if(product) {
|
||||||
|
console.log("Product: " + JSON.stringify(product));
|
||||||
|
let prices = product.prices ? product.prices : {};
|
||||||
|
let measurePriceData = prices[measureId];
|
||||||
|
|
||||||
|
if(!measurePriceData) {
|
||||||
|
measurePriceData = {};
|
||||||
|
prices[measureId] = measurePriceData;
|
||||||
|
}
|
||||||
|
console.log("Old Price Data: " + JSON.stringify(prices));
|
||||||
|
|
||||||
|
if(setPrevious && measurePriceData.price) {
|
||||||
|
measurePriceData.previousPrice = measurePriceData.price;
|
||||||
|
measurePriceData.effectiveDate = effectiveDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
measurePriceData.price = price;
|
||||||
|
console.log("New Price Data: " + JSON.stringify(prices));
|
||||||
|
//console.log(ProductsSchema.validate(product));
|
||||||
|
//
|
||||||
|
// check(prices, ProductsSchema);
|
||||||
|
if(ProductsSchema.newContext().isValid()) {
|
||||||
|
console.log("Valid schema for product");
|
||||||
|
Products.update(productId, {$set: {prices: prices, updateAt: new Date()}}, {validate: false, bypassCollection2: true});
|
||||||
|
}
|
||||||
|
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.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Products;
|
||||||
74
imports/api/ProductTag.js
Normal file
74
imports/api/ProductTag.js
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
import { Meteor } from 'meteor/meteor';
|
||||||
|
import { Mongo } from 'meteor/mongo';
|
||||||
|
import { check } from 'meteor/check'
|
||||||
|
import {SimpleSchema} from 'meteor/aldeed:simple-schema';
|
||||||
|
|
||||||
|
ProductTags = new Mongo.Collection('ProductTags', {
|
||||||
|
schema: new SimpleSchema({
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
label: "Name",
|
||||||
|
optional: false,
|
||||||
|
trim: true,
|
||||||
|
index: 1,
|
||||||
|
unique: true
|
||||||
|
},
|
||||||
|
createdAt: {
|
||||||
|
type: Date,
|
||||||
|
label: "Created On",
|
||||||
|
optional: false
|
||||||
|
},
|
||||||
|
updatedAt: {
|
||||||
|
type: Date,
|
||||||
|
label: "Updated On",
|
||||||
|
optional: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
//Allows the client to do DB interaction without calling server side methods, while still retaining control over whether the user can make changes.
|
||||||
|
ProductTags.allow({
|
||||||
|
insert: function() {return false;},
|
||||||
|
update: function() {return false;},
|
||||||
|
remove: function() {return false;}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(Meteor.isServer) {
|
||||||
|
Meteor.publish('productTags', function() {
|
||||||
|
return ProductTags.find({});
|
||||||
|
});
|
||||||
|
|
||||||
|
Meteor.methods({
|
||||||
|
insertProductTag: function(productTag) {
|
||||||
|
check(productTag, String);
|
||||||
|
productTag = {name: productTag, createdAt: new Date()};
|
||||||
|
|
||||||
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||||
|
ProductTags.insert(productTag, function(err, id) {
|
||||||
|
if(err) console.log(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else throw new Meteor.Error(403, "Not authorized.");
|
||||||
|
},
|
||||||
|
deleteProductTag: function(id) {
|
||||||
|
check(id, String);
|
||||||
|
|
||||||
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||||
|
ProductTags.remove(id);
|
||||||
|
}
|
||||||
|
else throw new Meteor.Error(403, "Not authorized.");
|
||||||
|
},
|
||||||
|
updateProductTag: function(tag) {
|
||||||
|
check(tag, {
|
||||||
|
_id: String,
|
||||||
|
name: String
|
||||||
|
});
|
||||||
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||||
|
ProductTags.update(tag._id, {$set: {name: tag.name, updateAt: new Date()}});
|
||||||
|
}
|
||||||
|
else throw new Meteor.Error(403, "Not authorized.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ProductTags;
|
||||||
17
imports/api/Roles.js
Normal file
17
imports/api/Roles.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
if(Meteor.isServer) {
|
||||||
|
Meteor.publish('roles', function() {
|
||||||
|
if(Roles.userIsInRole(this.userId, ['manage'])) {
|
||||||
|
return Meteor.roles.find({}, {fields: {name: 1}});
|
||||||
|
}
|
||||||
|
else throw new Meteor.Error(403, "Not authorized to view roles.");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let ROLE_MANAGE = "manage";
|
||||||
|
let ROLE_UPDATE = "update";
|
||||||
|
|
||||||
|
Meteor.UserRoles = {ROLE_MANAGE, ROLE_UPDATE};
|
||||||
|
|
||||||
|
|
||||||
|
export default Meteor.roles;
|
||||||
111
imports/api/Sale.js
Normal file
111
imports/api/Sale.js
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
import { Meteor } from 'meteor/meteor';
|
||||||
|
import { Mongo } from 'meteor/mongo';
|
||||||
|
import { check } from 'meteor/check';
|
||||||
|
import {SimpleSchema} from 'meteor/aldeed:simple-schema';
|
||||||
|
|
||||||
|
Sales = new Mongo.Collection('Sales');
|
||||||
|
let SalesSchema = new SimpleSchema({
|
||||||
|
date: {
|
||||||
|
type: Date,
|
||||||
|
label: "Date",
|
||||||
|
optional: false,
|
||||||
|
index: 1
|
||||||
|
},
|
||||||
|
amount: {
|
||||||
|
type: Number,
|
||||||
|
label: "Amount",
|
||||||
|
optional: false,
|
||||||
|
decimal: true
|
||||||
|
},
|
||||||
|
price: {
|
||||||
|
type: Number,
|
||||||
|
label: "Price",
|
||||||
|
optional: false,
|
||||||
|
min: 0,
|
||||||
|
exclusiveMin: true,
|
||||||
|
decimal: true
|
||||||
|
},
|
||||||
|
measureId: {
|
||||||
|
type: String,
|
||||||
|
label: "Measure Id",
|
||||||
|
trim: false,
|
||||||
|
regEx: SimpleSchema.RegEx.Id,
|
||||||
|
index: 1
|
||||||
|
},
|
||||||
|
productId: {
|
||||||
|
type: String,
|
||||||
|
label: "Product Id",
|
||||||
|
trim: false,
|
||||||
|
regEx: SimpleSchema.RegEx.Id,
|
||||||
|
index: 1
|
||||||
|
},
|
||||||
|
venueId: {
|
||||||
|
type: String,
|
||||||
|
label: "Vendor Id",
|
||||||
|
trim: false,
|
||||||
|
regEx: SimpleSchema.RegEx.Id,
|
||||||
|
index: 1
|
||||||
|
// autoform: {
|
||||||
|
// type: 'relation',
|
||||||
|
// settings: {
|
||||||
|
// collection: 'Venues',
|
||||||
|
// fields: ['name']
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
},
|
||||||
|
createdAt: {
|
||||||
|
type: Date,
|
||||||
|
label: "Created On",
|
||||||
|
optional: false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Sales.attachSchema(SalesSchema);
|
||||||
|
|
||||||
|
if(Meteor.isServer) {
|
||||||
|
Meteor.publish('sales', function(query, limit = 100) {
|
||||||
|
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'};
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!_.isNumber(limit)) limit = 100;
|
||||||
|
|
||||||
|
return Meteor.collections.Sales.find(dbQuery, {limit: limit, sort: {date: -1}});
|
||||||
|
});
|
||||||
|
|
||||||
|
Meteor.methods({
|
||||||
|
insertSale: function(sale) {
|
||||||
|
//TODO: Check the structure of sale. Use: check(sale, {name: String, ...});
|
||||||
|
sale.createdAt = new Date();
|
||||||
|
|
||||||
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||||
|
Sales.insert(sale, function(err, id) {
|
||||||
|
if(err) console.log(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else throw new Meteor.Error(403, "Not authorized.");
|
||||||
|
},
|
||||||
|
deleteSale: function(id) {
|
||||||
|
check(id, String);
|
||||||
|
|
||||||
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||||
|
Sales.remove(id);
|
||||||
|
}
|
||||||
|
else throw new Meteor.Error(403, "Not authorized.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//Allows the client to do DB interaction without calling server side methods, while still retaining control over whether the user can make changes.
|
||||||
|
Sales.allow({
|
||||||
|
insert: function() {return false;},
|
||||||
|
update: function() {return false;},
|
||||||
|
remove: function() {return false;}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default Sales;
|
||||||
69
imports/api/User.js
Normal file
69
imports/api/User.js
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
import {Random} from 'meteor/random';
|
||||||
|
|
||||||
|
if(Meteor.isServer) {
|
||||||
|
Meteor.publish('users', function() {
|
||||||
|
if(Roles.userIsInRole(this.userId, ['manage'])) {
|
||||||
|
return Meteor.users.find({}, {fields: {username: 1, emails: 1, roles: 1}});
|
||||||
|
}
|
||||||
|
else throw new Meteor.Error(403, "Not authorized to view users.");
|
||||||
|
});
|
||||||
|
|
||||||
|
Meteor.methods({
|
||||||
|
"insertUser": function(user, roles) {
|
||||||
|
check(user, {
|
||||||
|
username: String,
|
||||||
|
email: String
|
||||||
|
});
|
||||||
|
check(roles, [String]);
|
||||||
|
|
||||||
|
//Verify the currently logged in user has authority to manage users.
|
||||||
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_MANAGE])) {
|
||||||
|
//Verify the user name isn't already used.
|
||||||
|
if(Meteor.collections.Users.findOne({username: user.username}) == undefined) {
|
||||||
|
let pwd = Random.secret(20);
|
||||||
|
let id = Accounts.createUser({password: pwd, username: user.username, email: user.email});
|
||||||
|
|
||||||
|
//Requires the alanning:roles package.
|
||||||
|
Roles.addUsersToRoles(id, roles);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new Meteor.Error(400, "User already exists.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else throw new Meteor.Error(403, "Not authorized to add users.");
|
||||||
|
},
|
||||||
|
"updateUser": function(user) {
|
||||||
|
check(user, {
|
||||||
|
_id: String,
|
||||||
|
username: String,
|
||||||
|
emails: [{
|
||||||
|
address: String,
|
||||||
|
verified: Boolean
|
||||||
|
}],
|
||||||
|
roles: [String]
|
||||||
|
});
|
||||||
|
|
||||||
|
//Verify the currently logged in user has authority to manage users.
|
||||||
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_MANAGE])) {
|
||||||
|
//Verify the user name isn't already used with a different ID.
|
||||||
|
if(Meteor.collections.Users.findOne({username: user.username, _id: {$ne: user._id}}) == undefined) {
|
||||||
|
//Update the user. Note: I am using direct mongo modification, versus attempting to go through the Accounts and Roles objects. This could cause problems in the future if these packages change their data structures.
|
||||||
|
Meteor.collections.Users.update(user._id, {$set: {username: user.username, emails: user.emails, roles: user.roles}});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new Meteor.Error(400, "User name already exists.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else throw new Meteor.Error(403, "Not authorized to update users.");
|
||||||
|
},
|
||||||
|
"deleteUser": function(id) {
|
||||||
|
check(id, String);
|
||||||
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_MANAGE])) {
|
||||||
|
Meteor.collections.Users.remove(id);
|
||||||
|
}
|
||||||
|
else throw new Meteor.Error(403, "Not authorized to remove users.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Meteor.users;
|
||||||
130
imports/api/Venue.js
Normal file
130
imports/api/Venue.js
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
import { Meteor } from 'meteor/meteor';
|
||||||
|
import { Mongo } from 'meteor/mongo';
|
||||||
|
import { check } from 'meteor/check';
|
||||||
|
import {SimpleSchema} from 'meteor/aldeed:simple-schema';
|
||||||
|
|
||||||
|
Venues = new Mongo.Collection('Venues');
|
||||||
|
let VenuesSchema = new SimpleSchema({
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
label: "Name",
|
||||||
|
optional: false,
|
||||||
|
trim: true,
|
||||||
|
index: 1,
|
||||||
|
unique: true
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
label: "Type",
|
||||||
|
optional: false,
|
||||||
|
trim: true
|
||||||
|
},
|
||||||
|
createdAt: {
|
||||||
|
type: Date,
|
||||||
|
label: "Created On",
|
||||||
|
optional: false
|
||||||
|
},
|
||||||
|
updatedAt: {
|
||||||
|
type: Date,
|
||||||
|
label: "Updated On",
|
||||||
|
optional: true
|
||||||
|
},
|
||||||
|
deletedAt: {
|
||||||
|
type: Date,
|
||||||
|
label: "Deleted On",
|
||||||
|
optional: true
|
||||||
|
},
|
||||||
|
deletedBy: {
|
||||||
|
type: String,
|
||||||
|
label: "Deleted By",
|
||||||
|
optional: true
|
||||||
|
},
|
||||||
|
restoredAt: {
|
||||||
|
type: Date,
|
||||||
|
label: "Restored On",
|
||||||
|
optional: true
|
||||||
|
},
|
||||||
|
restoredBy: {
|
||||||
|
type: String,
|
||||||
|
label: "Restored By",
|
||||||
|
optional: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Venues.attachSchema(VenuesSchema);
|
||||||
|
|
||||||
|
//https://github.com/zimme/meteor-collection-softremovable
|
||||||
|
Venues.attachBehaviour("softRemovable", {
|
||||||
|
removed: 'deleted',
|
||||||
|
removedAt: 'deletedAt',
|
||||||
|
removedBy: 'removedBy',
|
||||||
|
restoredAt: 'restoredAt',
|
||||||
|
restoredBy: 'restoredBy'
|
||||||
|
});
|
||||||
|
|
||||||
|
if(Meteor.isServer) Meteor.publish('venues', function() {
|
||||||
|
return Venues.find({});
|
||||||
|
});
|
||||||
|
|
||||||
|
// //Requires: meteor add matb33:collection-hooks
|
||||||
|
if(Meteor.isServer) {
|
||||||
|
Venues.before.insert(function(userId, doc) {
|
||||||
|
// check(userId, String);
|
||||||
|
doc.createdAt = new Date();
|
||||||
|
});
|
||||||
|
Venues.before.update(function(userId, doc, fieldNames, modifier, options) {
|
||||||
|
modifier.$set = modifier.$set || {}; //Make sure there is an object.
|
||||||
|
modifier.$set.updatedAt = new Date();
|
||||||
|
});
|
||||||
|
|
||||||
|
Meteor.methods({
|
||||||
|
insertVenue: function(venue) {
|
||||||
|
check(venue, {
|
||||||
|
name: String,
|
||||||
|
type: String
|
||||||
|
});
|
||||||
|
|
||||||
|
venue.createdAt = new Date();
|
||||||
|
|
||||||
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||||
|
Venues.insert(venue);
|
||||||
|
}
|
||||||
|
else throw new Meteor.Error(403, "Not authorized.");
|
||||||
|
},
|
||||||
|
deleteVenue: function(id) {
|
||||||
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||||
|
Venues.remove(id);
|
||||||
|
}
|
||||||
|
else throw new Meteor.Error(403, "Not authorized.");
|
||||||
|
},
|
||||||
|
updateVenue: function(venue) {
|
||||||
|
check(venue, {
|
||||||
|
name: String,
|
||||||
|
type: String
|
||||||
|
});
|
||||||
|
|
||||||
|
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||||
|
Venues.update(id, {$set: {name: venue.name, type: venue.type, updateAt: new Date()}});
|
||||||
|
}
|
||||||
|
else throw new Meteor.Error(403, "Not authorized.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//Allows the client to do DB interaction without calling server side methods, while still retaining control over whether the user can make changes.
|
||||||
|
// Meteor.allow({
|
||||||
|
// insert: true,
|
||||||
|
// update: ()->{return true},
|
||||||
|
// remove: checkUser
|
||||||
|
// };
|
||||||
|
// checkUser = function(userId, doc) {
|
||||||
|
// return doc && doc.userId === userId;
|
||||||
|
// };
|
||||||
|
|
||||||
|
//Allows the client to interact with the db through the server via custom methods.
|
||||||
|
// Meteor.methods({
|
||||||
|
// deleteMeasure: function(id) {
|
||||||
|
// Measures.remove(id);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
export default Venues;
|
||||||
26
imports/api/index.js
Normal file
26
imports/api/index.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
//import Categories from "./Category.js";
|
||||||
|
//import Subcategories from "./Subcategory.js";
|
||||||
|
import Measures from "./Measure.js";
|
||||||
|
import Venues from "./Venue.js";
|
||||||
|
import Products from "./Product.js";
|
||||||
|
import ProductTags from "./ProductTag.js";
|
||||||
|
import Sales from "./Sale.js";
|
||||||
|
import Users from "./User.js";
|
||||||
|
import UserRoles from "./Roles.js";
|
||||||
|
|
||||||
|
Meteor.collections = {Measures, Venues, Products, ProductTags, Sales, Users, UserRoles};
|
||||||
|
if(Meteor.isServer) {
|
||||||
|
//Change this to find admin users, create a default admin user if none exists.
|
||||||
|
if(Users.find({}).count() == 0) {
|
||||||
|
try {
|
||||||
|
console.log("Creating a default admin user: admin/admin");
|
||||||
|
|
||||||
|
let id = Accounts.createUser({password: 'admin', username: 'admin'});
|
||||||
|
//Requires the alanning:roles package.
|
||||||
|
Roles.addUsersToRoles(id, [Meteor.UserRoles.ROLE_MANAGE, Meteor.UserRoles.ROLE_UPDATE]);
|
||||||
|
}
|
||||||
|
catch(err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
68
imports/startup/both/accounts.js
Normal file
68
imports/startup/both/accounts.js
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
import { AccountsTemplates } from 'meteor/useraccounts:core';
|
||||||
|
|
||||||
|
AccountsTemplates.configure({
|
||||||
|
forbidClientAccountCreation: true,
|
||||||
|
showForgotPasswordLink: true,
|
||||||
|
defaultTemplate: 'atForm',
|
||||||
|
defaultLayout: 'Full',
|
||||||
|
defaultContentRegion: 'content',
|
||||||
|
defaultLayoutRegions: {}
|
||||||
|
// defaultTemplate: 'Auth_page',
|
||||||
|
// defaultLayout: 'Body',
|
||||||
|
// defaultContentRegion: 'content',
|
||||||
|
// defaultLayoutRegions: {}
|
||||||
|
});
|
||||||
|
|
||||||
|
// This removes the password field but returns it,
|
||||||
|
// so that you can re-add it later, preserving the
|
||||||
|
// desired order of the fields
|
||||||
|
// let pwd = AccountsTemplates.removeField('password');
|
||||||
|
// AccountsTemplates.removeField('email');
|
||||||
|
// AccountsTemplates.addFields([
|
||||||
|
// {
|
||||||
|
// _id: "username",
|
||||||
|
// type: "text",
|
||||||
|
// displayName: "username",
|
||||||
|
// required: true,
|
||||||
|
// minLength: 5,
|
||||||
|
// },
|
||||||
|
// pwd
|
||||||
|
// ]);
|
||||||
|
let pwd = AccountsTemplates.removeField('password');
|
||||||
|
AccountsTemplates.removeField('email');
|
||||||
|
AccountsTemplates.addFields([
|
||||||
|
{
|
||||||
|
_id: "username",
|
||||||
|
type: "text",
|
||||||
|
displayName: "username",
|
||||||
|
required: true,
|
||||||
|
minLength: 5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
_id: 'email',
|
||||||
|
type: 'email',
|
||||||
|
required: true,
|
||||||
|
displayName: "email",
|
||||||
|
re: /.+@(.+){2,}\.(.+){2,}/,
|
||||||
|
errStr: 'Invalid email',
|
||||||
|
},
|
||||||
|
pwd
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
AccountsTemplates.configureRoute('signIn', {
|
||||||
|
name: 'signin',
|
||||||
|
path: '/signin'
|
||||||
|
});
|
||||||
|
|
||||||
|
// AccountsTemplates.configureRoute('signUp', {
|
||||||
|
// name: 'join',
|
||||||
|
// path: '/join'
|
||||||
|
// });
|
||||||
|
|
||||||
|
AccountsTemplates.configureRoute('forgotPwd');
|
||||||
|
|
||||||
|
AccountsTemplates.configureRoute('resetPwd', {
|
||||||
|
name: 'resetPwd',
|
||||||
|
path: '/reset-password',
|
||||||
|
});
|
||||||
1
imports/startup/both/index.js
Normal file
1
imports/startup/both/index.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import './accounts.js';
|
||||||
1
imports/startup/client/index.js
Normal file
1
imports/startup/client/index.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import './routes.js';
|
||||||
80
imports/startup/client/routes.js
Normal file
80
imports/startup/client/routes.js
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
//Look in /libs/startup/both/useraccounts.js for the login/logout/signup routing.
|
||||||
|
|
||||||
|
let pri = FlowRouter.group({
|
||||||
|
triggersEnter: [AccountsTemplates.ensureSignedIn]
|
||||||
|
});
|
||||||
|
|
||||||
|
pri.route('/', {
|
||||||
|
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', {
|
||||||
|
name: 'Measures',
|
||||||
|
action: function(params, queryParams) {
|
||||||
|
require("/imports/ui/Measures.js");
|
||||||
|
BlazeLayout.render('Body', {content: 'Measures'});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
pri.route('/products', {
|
||||||
|
name: 'Products',
|
||||||
|
action: function(params, queryParams) {
|
||||||
|
require("/imports/ui/Products.js");
|
||||||
|
BlazeLayout.render('Body', {content: 'Products'});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
pri.route('/productTags', {
|
||||||
|
name: 'ProductTags',
|
||||||
|
action: function(params, queryParams) {
|
||||||
|
require("/imports/ui/ProductTags.js");
|
||||||
|
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', {
|
||||||
|
name: 'UserManagement',
|
||||||
|
action: function(params, queryParams) {
|
||||||
|
require("/imports/ui/UserManagement.js");
|
||||||
|
BlazeLayout.render('Body', {content: 'UserManagement'});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
pri.route('/sales', {
|
||||||
|
name: 'Sales',
|
||||||
|
action: function(params, queryParams) {
|
||||||
|
require("/imports/ui/Sales.js");
|
||||||
|
BlazeLayout.render('Body', {content: 'Sales'});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
pri.route('/production', {
|
||||||
|
name: 'Production',
|
||||||
|
action: function(params, queryParams) {
|
||||||
|
require("/imports/ui/Production.js");
|
||||||
|
BlazeLayout.render('Body', {content: 'Production'});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
pri.route('/pricing', {
|
||||||
|
name: 'Pricing',
|
||||||
|
action: function(params, queryParams) {
|
||||||
|
require("/imports/ui/Pricing.js");
|
||||||
|
BlazeLayout.render('Body', {content: 'Pricing'});
|
||||||
|
}
|
||||||
|
});
|
||||||
12
imports/startup/server/email.js
Normal file
12
imports/startup/server/email.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
Accounts.emailTemplates.from = "Do Not Reply <administrator@declarativeengineering.com>";
|
||||||
|
Accounts.emailTemplates.siteName = "Petit Teton App";
|
||||||
|
// Accounts.emailTemplates.verifyEmail.subject = function (user) {
|
||||||
|
// return "Welcome to My Site! Please verify your email";
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// Accounts.emailTemplates.verifyEmail.html = function (user, url) {
|
||||||
|
// return "Hi " + user.profile.firstName + " " + user.profile.lastName + ",\n\n" +
|
||||||
|
// " Please verify your email by simply clicking the link below:\n\n" +
|
||||||
|
// url;
|
||||||
|
// };
|
||||||
1
imports/startup/server/index.js
Normal file
1
imports/startup/server/index.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import "./email.js"
|
||||||
33
imports/startup/server/postStartup/version.js
Normal file
33
imports/startup/server/postStartup/version.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
let AppVersion = new Mongo.Collection('AppVersion');
|
||||||
|
let AppVersionSchema = new SimpleSchema({
|
||||||
|
version: {
|
||||||
|
type: Number,
|
||||||
|
optional: false,
|
||||||
|
defaultValue: 0
|
||||||
|
}
|
||||||
|
});
|
||||||
|
AppVersion.attachSchema(AppVersionSchema);
|
||||||
|
|
||||||
|
try {
|
||||||
|
let appVersions = AppVersion.find({}).fetch();
|
||||||
|
let appVersion;
|
||||||
|
|
||||||
|
if(!appVersions || appVersions.length == 0) { //This will happen only when first creating a database.
|
||||||
|
appVersion = {version: 0};
|
||||||
|
appVersion._id = AppVersion.insert(appVersion);
|
||||||
|
}
|
||||||
|
else if(appVersions.length > 1) { //This should never happen. Remove all but the first app version.
|
||||||
|
for(let i = 1; i < appVersions.length; i++) {
|
||||||
|
AppVersion.remove(appVersions[i]._id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
appVersion = appVersions[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
catch(err) {
|
||||||
|
console.log("Caught an error while upgrading the app version: " + err);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
3
imports/ui/Intro.html
Normal file
3
imports/ui/Intro.html
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<template name="Intro">
|
||||||
|
<div id="intro">Intro</div>
|
||||||
|
</template>
|
||||||
4
imports/ui/Intro.import.styl
vendored
Normal file
4
imports/ui/Intro.import.styl
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
#intro
|
||||||
|
text-align: center
|
||||||
|
font-size: 4em
|
||||||
|
font-family: sans-serif
|
||||||
2
imports/ui/Intro.js
Normal file
2
imports/ui/Intro.js
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
import { Template } from 'meteor/templating';
|
||||||
|
import './Intro.html';
|
||||||
18
imports/ui/Measures.html
Normal file
18
imports/ui/Measures.html
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<template name="Measures">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr><td>Name</td></tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{#each measures}}
|
||||||
|
{{> MeasureRow}}
|
||||||
|
{{/each}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="MeasureRow">
|
||||||
|
<tr>
|
||||||
|
<td>{{name}}</td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
0
imports/ui/Measures.import.styl
vendored
Normal file
0
imports/ui/Measures.import.styl
vendored
Normal file
25
imports/ui/Measures.js
Normal file
25
imports/ui/Measures.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
import './Measures.html';
|
||||||
|
|
||||||
|
Template.Measures.helpers({
|
||||||
|
// someFunctionNameCalledByTemplate: function() {
|
||||||
|
// return something;
|
||||||
|
// }
|
||||||
|
measures: function () {
|
||||||
|
return Measures.find({});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.Measures.events({
|
||||||
|
// 'click .something': function() {
|
||||||
|
// Meteor.call('someMethodOnServer', this.something, someotherparam);
|
||||||
|
// Session.set('someValue', Session.get('someOtherValue'));
|
||||||
|
// console.log("Got here");
|
||||||
|
// }
|
||||||
|
|
||||||
|
'click .trash': function() {
|
||||||
|
//Calls deleteMeasure which is in the collection for Measures.
|
||||||
|
Meteor.call('deleteMeasure', this._id);
|
||||||
|
console.log("Got here");
|
||||||
|
}
|
||||||
|
});
|
||||||
20
imports/ui/Menu.html
Normal file
20
imports/ui/Menu.html
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<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
Normal file
56
imports/ui/Menu.import.styl
vendored
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
#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;
|
||||||
|
}
|
||||||
|
}
|
||||||
2
imports/ui/Menu.js
Normal file
2
imports/ui/Menu.js
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
import { Template } from 'meteor/templating';
|
||||||
|
import './Menu.html';
|
||||||
54
imports/ui/Pricing.html
Normal file
54
imports/ui/Pricing.html
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
<template name="Pricing">
|
||||||
|
<div id="pricing">
|
||||||
|
<div class="controls">
|
||||||
|
<div class="controlGroup floatRight">
|
||||||
|
<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>
|
||||||
|
<select name="measures">
|
||||||
|
{{#each measures}}
|
||||||
|
<option value="{{_id}}">{{name}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="name">Name</th>
|
||||||
|
<th class="current">Current</th>
|
||||||
|
<th class="changeDate">Change Date</th>
|
||||||
|
<th class="previous">Previous</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{#each product}}
|
||||||
|
{{> PricingForProduct}}
|
||||||
|
{{/each}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="PricingForProduct">
|
||||||
|
<tr class="clickable noselect">
|
||||||
|
<td>{{name}}</td>
|
||||||
|
<td>{{currentPrice}}</td>
|
||||||
|
<td>{{priceChangeDate}}</td>
|
||||||
|
<td>{{previousPrice}}</td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
95
imports/ui/Pricing.import.styl
vendored
Normal file
95
imports/ui/Pricing.import.styl
vendored
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
#pricing
|
||||||
|
margin: 10px 20px
|
||||||
|
height: 100%
|
||||||
|
|
||||||
|
.controls
|
||||||
|
text-align: left
|
||||||
|
|
||||||
|
.controlGroup
|
||||||
|
padding: 4px 8px
|
||||||
|
margin: 4px 8px
|
||||||
|
display: inline-block
|
||||||
|
.outline
|
||||||
|
border: 2px dotted #32747e
|
||||||
|
border-radius: 10px
|
||||||
|
.floatLeft
|
||||||
|
float: left
|
||||||
|
.floatRight
|
||||||
|
float: right
|
||||||
|
.controlLabel
|
||||||
|
font-size: 1.5em
|
||||||
|
font-weight: 700
|
||||||
|
select[name="measures"]
|
||||||
|
padding: 4px 8px
|
||||||
|
font-size: 1.5em
|
||||||
|
input
|
||||||
|
padding: 4px 8px
|
||||||
|
font-size: 1.5em
|
||||||
|
input[type="number"]
|
||||||
|
width: 80px
|
||||||
|
input[type="button"]
|
||||||
|
margin-top: -6px
|
||||||
|
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
|
||||||
|
margin: 0
|
||||||
|
position: relative
|
||||||
|
top: -4px
|
||||||
|
display: inline-block
|
||||||
|
//.inactive
|
||||||
|
// background: #666
|
||||||
|
input[type="date"]
|
||||||
|
width: 180px
|
||||||
|
display: inline-block
|
||||||
|
table
|
||||||
|
width: 100%
|
||||||
|
margin-bottom: 20px
|
||||||
|
border: 0
|
||||||
|
table-layout: fixed
|
||||||
|
font-size: 1.3em
|
||||||
|
|
||||||
|
thead
|
||||||
|
font-weight: 800
|
||||||
|
tr > th
|
||||||
|
background: #333
|
||||||
|
color: white
|
||||||
|
|
||||||
|
tr > th.name
|
||||||
|
width: auto
|
||||||
|
tr > th.current
|
||||||
|
width: 200px
|
||||||
|
tr > th.previous
|
||||||
|
width: 200px
|
||||||
|
tr > th.changeDate
|
||||||
|
width: 200px
|
||||||
|
|
||||||
|
tbody
|
||||||
|
text-align: left
|
||||||
|
|
||||||
|
tr:nth-child(even)
|
||||||
|
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%)
|
||||||
114
imports/ui/Pricing.js
Normal file
114
imports/ui/Pricing.js
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
|
||||||
|
import './Pricing.html';
|
||||||
|
|
||||||
|
Tracker.autorun(function() {
|
||||||
|
Meteor.subscribe("products");
|
||||||
|
Meteor.subscribe("measures");
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.Pricing.onRendered(function() {
|
||||||
|
this.$('input[name="date"]').val(new Date().toDateInputValue());
|
||||||
|
});
|
||||||
|
Template.Pricing.helpers({
|
||||||
|
measures: function() {
|
||||||
|
//return Meteor.collections.Measures.find({}, {sort: {order: 1}});
|
||||||
|
let measures = Meteor.collections.Measures.find({}, {sort: {order: 1}}).fetch();
|
||||||
|
|
||||||
|
for(let i = 0; i < measures; i++) {
|
||||||
|
if(Meteor.collections.Products.find({measures: {$all: [measures[i]._id]}}, {sort: {name: 1}}).count() == 0)
|
||||||
|
measures.splice(i, 1); //Remove the measure from the list.
|
||||||
|
}
|
||||||
|
|
||||||
|
return measures;
|
||||||
|
},
|
||||||
|
product: function() {
|
||||||
|
let measureId = Session.get("selectedMeasure");
|
||||||
|
|
||||||
|
return Meteor.collections.Products.find({measures: {$all: [measureId]}}, {sort: {name: 1}});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Template.Pricing.events({
|
||||||
|
'change select[name="measures"]': function(event, template) {
|
||||||
|
Session.set("selectedMeasure", $(event.target).val());
|
||||||
|
},
|
||||||
|
'click .applyButton': function(event, template) {
|
||||||
|
let measureId = Session.get("selectedMeasure");
|
||||||
|
let $selectedRows = template.$('tr.selected');
|
||||||
|
// let selectedProducts = $selectedRows.map(function() {return $(this).data('product')});
|
||||||
|
let price = Number(template.$('input[name="price"]').val());
|
||||||
|
let setPrevious = template.$('input[name="setPrevious"]').prop('checked');
|
||||||
|
let date = template.$('input[name="date"]').val();
|
||||||
|
|
||||||
|
date = moment(date ? date : new Date().toDateInputValue(), "YYYY-MM-DD").toDate();
|
||||||
|
setPrevious = setPrevious == true || setPrevious == 'on' || setPrevious == "true" || setPrevious == "yes";
|
||||||
|
|
||||||
|
if(setPrevious == true && !date) {
|
||||||
|
sAlert.error("Unexpected input.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!price || isNaN(price) || price < 0) {
|
||||||
|
sAlert.error("Unexpected input.");
|
||||||
|
}
|
||||||
|
|
||||||
|
for(let i = 0; i < $selectedRows.length; i++) {
|
||||||
|
let product = $($selectedRows[i]).data('product');
|
||||||
|
|
||||||
|
Meteor.call("setProductPrice", product._id, measureId, price, setPrevious, date);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Template.PricingForProduct.onCreated(function() {
|
||||||
|
//
|
||||||
|
// });
|
||||||
|
Template.PricingForProduct.onRendered(function() {
|
||||||
|
this.$('tr').data("product", this.data);
|
||||||
|
});
|
||||||
|
Template.PricingForProduct.helpers({
|
||||||
|
currentPrice: function() {
|
||||||
|
let measureId = Session.get("selectedMeasure");
|
||||||
|
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}) : "-";
|
||||||
|
},
|
||||||
|
previousPrice: function() {
|
||||||
|
let measureId = Session.get("selectedMeasure");
|
||||||
|
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}) : "-";
|
||||||
|
},
|
||||||
|
priceChangeDate: function() {
|
||||||
|
let measureId = Session.get("selectedMeasure");
|
||||||
|
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)") : "-";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Template.PricingForProduct.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;
|
||||||
|
}
|
||||||
|
});
|
||||||
66
imports/ui/ProductTags.html
Normal file
66
imports/ui/ProductTags.html
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
<template name="ProductTags">
|
||||||
|
<div id="productTags">
|
||||||
|
{{#if Template.subscriptionsReady}}
|
||||||
|
<div class="insert">
|
||||||
|
{{>ProductTagInsert}}
|
||||||
|
</div>
|
||||||
|
<div class="grid">
|
||||||
|
<table class="dataTable table table-striped table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr class="headers">
|
||||||
|
<th class="tdLarge noselect nonclickable" style="max-width: 300px">Name</th>
|
||||||
|
<th class="tdLarge noselect nonclickable" style="width: 90px">Actions</th>
|
||||||
|
</tr>
|
||||||
|
<tr class="footers">
|
||||||
|
<th>{{>ProductTagSearch columnName='name'}}</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{#each productTags}}
|
||||||
|
{{> ProductTag}}
|
||||||
|
{{/each}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="ProductTag">
|
||||||
|
<tr>
|
||||||
|
{{#if editing}}
|
||||||
|
<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>
|
||||||
|
{{else}}
|
||||||
|
<td class="tdLarge noselect nonclickable">{{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>
|
||||||
|
{{/if}}
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="ProductTagSearch">
|
||||||
|
<div class="">
|
||||||
|
<input type="text" class="searchInput" placeholder="Filter..." value="{{searchValue}}"/>
|
||||||
|
</div>
|
||||||
|
</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>
|
||||||
88
imports/ui/ProductTags.import.styl
vendored
Normal file
88
imports/ui/ProductTags.import.styl
vendored
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
#productTags
|
||||||
|
margin: 20px 20px
|
||||||
|
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
|
||||||
|
|
||||||
|
.editor
|
||||||
|
height: 100%
|
||||||
|
overflow-y: auto
|
||||||
|
|
||||||
|
.insert
|
||||||
|
flex: none
|
||||||
|
width: 100%
|
||||||
|
|
||||||
|
.col-md-6
|
||||||
|
padding: 10px 30px 0 30px
|
||||||
|
background: #EFEFEF
|
||||||
|
border-radius: 1em
|
||||||
|
|
||||||
|
.formGroupHeading
|
||||||
|
font-size: 1.6em
|
||||||
|
font-family: "Arial Black", "Arial Bold", Gadget, sans-serif
|
||||||
|
font-style: normal
|
||||||
|
font-variant: normal
|
||||||
|
font-weight: 500
|
||||||
|
|
||||||
|
.grid
|
||||||
|
flex: auto
|
||||||
|
align-self: stretch
|
||||||
|
overflow-y: auto
|
||||||
|
overflow-x: auto
|
||||||
|
margin-bottom: 20px
|
||||||
|
border: 0
|
||||||
|
padding-top: 20px
|
||||||
|
|
||||||
|
.table > thead > tr > th
|
||||||
|
border: 0
|
||||||
|
padding-top: 0
|
||||||
|
padding-bottom: 6px
|
||||||
|
|
||||||
|
.dataTable
|
||||||
|
table-layout: fixed
|
||||||
|
width: auto
|
||||||
|
|
||||||
|
.tdLarge
|
||||||
|
font-size: 1.5em
|
||||||
|
.tagRemove
|
||||||
|
color: red
|
||||||
|
.tagEdit
|
||||||
|
color: darkblue
|
||||||
|
.editorApply
|
||||||
|
color: green
|
||||||
|
.editorCancel
|
||||||
|
color: red
|
||||||
|
td.roles
|
||||||
|
.role
|
||||||
|
padding: 4px 4px
|
||||||
|
border: 1px solid #555
|
||||||
|
border-radius: .25em
|
||||||
|
background: white
|
||||||
|
color: #999
|
||||||
|
cursor: pointer
|
||||||
|
.selected
|
||||||
|
color: black
|
||||||
|
|
||||||
|
div.roles
|
||||||
|
padding: 4px 0
|
||||||
|
.role
|
||||||
|
padding: 4px 4px
|
||||||
|
border: 1px solid #555
|
||||||
|
border-radius: .25em
|
||||||
|
background: white
|
||||||
|
color: #999
|
||||||
|
cursor: pointer
|
||||||
|
.selected
|
||||||
|
color: black
|
||||||
|
.center
|
||||||
|
vertical-align: middle !important
|
||||||
132
imports/ui/ProductTags.js
Normal file
132
imports/ui/ProductTags.js
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
|
||||||
|
import './ProductTags.html';
|
||||||
|
|
||||||
|
Tracker.autorun(function() {
|
||||||
|
Meteor.subscribe("productTags");
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.ProductTags.helpers({
|
||||||
|
productTags: function() {
|
||||||
|
return Meteor.collections.ProductTags.find(Session.get('searchQuery') || {}, {sort: {name: -1}});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.ProductTag.onCreated(function() {
|
||||||
|
this.edited = new ReactiveVar();
|
||||||
|
});
|
||||||
|
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({
|
||||||
|
editing: function() {
|
||||||
|
return Template.instance().edited.get() == this;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.ProductTagSearch.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.ProductTagSearch.helpers({
|
||||||
|
searchValue: function() {
|
||||||
|
let searchFields = Session.get('searchFields');
|
||||||
|
|
||||||
|
return (searchFields && searchFields[this.columnName]) ? searchFields[this.columnName] : '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.ProductTagInsert.onRendered(function() {
|
||||||
|
this.$('form[name="insert"]').validator();
|
||||||
|
});
|
||||||
|
Template.ProductTagInsert.events({
|
||||||
|
'click input[type="submit"]': function(event, template) {
|
||||||
|
event.preventDefault();
|
||||||
|
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(error) {
|
||||||
|
sAlert.error(error);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sAlert.success("Product tag created.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
"click .role": function(event, template) {
|
||||||
|
$(event.target).toggleClass("selected");
|
||||||
|
}
|
||||||
|
});
|
||||||
5
imports/ui/Production.html
Normal file
5
imports/ui/Production.html
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<template name="Production">
|
||||||
|
<div id="production">
|
||||||
|
todo
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
60
imports/ui/Production.import.styl
vendored
Normal file
60
imports/ui/Production.import.styl
vendored
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
#production
|
||||||
|
margin: 10px 20px
|
||||||
|
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
|
||||||
|
|
||||||
|
.editor
|
||||||
|
height: 100%
|
||||||
|
overflow-y: auto
|
||||||
|
|
||||||
|
.insertSale
|
||||||
|
flex: none
|
||||||
|
width: 100%
|
||||||
|
|
||||||
|
.formGroupHeading
|
||||||
|
font-size: 1.6em
|
||||||
|
font-family: "Arial Black", "Arial Bold", Gadget, sans-serif
|
||||||
|
font-style: normal
|
||||||
|
font-variant: normal
|
||||||
|
font-weight: 500
|
||||||
|
|
||||||
|
.grid
|
||||||
|
flex: auto
|
||||||
|
align-self: stretch
|
||||||
|
overflow-y: auto
|
||||||
|
overflow-x: auto
|
||||||
|
margin-bottom: 20px
|
||||||
|
border: 0
|
||||||
|
padding-top: 20px
|
||||||
|
|
||||||
|
.table > thead > tr > th
|
||||||
|
border: 0
|
||||||
|
padding-top: 0
|
||||||
|
padding-bottom: 6px
|
||||||
|
|
||||||
|
.left
|
||||||
|
text-align: left
|
||||||
|
.center
|
||||||
|
text-align: center
|
||||||
|
|
||||||
|
.dataTable
|
||||||
|
table-layout: fixed
|
||||||
|
|
||||||
|
.tdLarge
|
||||||
|
font-size: 1.3em
|
||||||
|
.saleRemove
|
||||||
|
color: red
|
||||||
|
margin-left: 8px
|
||||||
|
.saleEdit
|
||||||
|
color: darkblue
|
||||||
|
margin-right: 8px
|
||||||
2
imports/ui/Production.js
Normal file
2
imports/ui/Production.js
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
import './Production.html';
|
||||||
38
imports/ui/Products.html
Normal file
38
imports/ui/Products.html
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<template name="Products">
|
||||||
|
<div id="products">
|
||||||
|
<div class="grid">
|
||||||
|
<div class="dataTable">
|
||||||
|
<table class="table table-striped table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name {{>ProductSearch columnName='name'}}</th>
|
||||||
|
<th>Tags {{>ProductSearch columnName='tags'}}</th>
|
||||||
|
<th>Aliases {{>ProductSearch columnName='aliases'}}</th>
|
||||||
|
<th>Measures {{>ProductSearch columnName='measures' collectionQueryColumnName='name' collection='Measures' collectionResultColumnName='_id'}}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{#each products}}
|
||||||
|
{{> Product}}
|
||||||
|
{{/each}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="Product">
|
||||||
|
<tr>
|
||||||
|
<td class="tdLarge noselect nonclickable left">{{name}}</td>
|
||||||
|
<td class="tdLarge noselect nonclickable left">{{tags}}</td>
|
||||||
|
<td class="tdLarge noselect nonclickable left">{{aliases}}</td>
|
||||||
|
<td class="tdLarge noselect nonclickable left">{{measures}}</td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="ProductSearch">
|
||||||
|
<div class="">
|
||||||
|
<input type="text" class="searchInput" placeholder="Filter..." value="{{searchValue}}"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
52
imports/ui/Products.import.styl
vendored
Normal file
52
imports/ui/Products.import.styl
vendored
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
#products
|
||||||
|
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);
|
||||||
103
imports/ui/Products.js
Normal file
103
imports/ui/Products.js
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
|
||||||
|
import './Products.html';
|
||||||
|
|
||||||
|
Tracker.autorun(function() {
|
||||||
|
Meteor.subscribe("products");
|
||||||
|
Meteor.subscribe("productTags");
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.Products.helpers({
|
||||||
|
products: 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.Products.find(dbQuery, {limit: 20, sort: {name: 1}});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.ProductSearch.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.ProductSearch.helpers({
|
||||||
|
searchValue: function() {
|
||||||
|
let searchFields = Session.get('searchFields');
|
||||||
|
|
||||||
|
return (searchFields && searchFields[this.columnName]) ? searchFields[this.columnName] : '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.Product.helpers({
|
||||||
|
measures: function() {
|
||||||
|
let result = "";
|
||||||
|
|
||||||
|
if(this.measures && this.measures.length > 0) {
|
||||||
|
let measureNames = [];
|
||||||
|
|
||||||
|
for(let i = 0; i < this.measures.length; i++) {
|
||||||
|
let measureObject = Meteor.collections.Measures.findOne(this.measures[i]);
|
||||||
|
|
||||||
|
if(measureObject && measureObject.name)
|
||||||
|
measureNames.push(measureObject.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = measureNames.join(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
tags: function() {
|
||||||
|
let result = "";
|
||||||
|
|
||||||
|
if(this.tags && this.tags.length > 0) {
|
||||||
|
let tagNames = [];
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
});
|
||||||
129
imports/ui/Sales.html
Normal file
129
imports/ui/Sales.html
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
<template name="Sales">
|
||||||
|
<div id="salesMain">
|
||||||
|
{{#if Template.subscriptionsReady}}
|
||||||
|
<div class="insertSale">
|
||||||
|
{{>InsertSale}}
|
||||||
|
</div>
|
||||||
|
<div class="grid">
|
||||||
|
<table class="dataTable table table-striped table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr class="headers">
|
||||||
|
<th class="tdLarge noselect nonclickable" style="width: 80px">Amount</th>
|
||||||
|
<th class="tdLarge noselect nonclickable">Product</th>
|
||||||
|
<th class="tdLarge noselect nonclickable" style="width: 140px">Price</th>
|
||||||
|
<th class="tdLarge noselect nonclickable" style="width: 90px">Measure</th>
|
||||||
|
<th class="tdLarge noselect nonclickable" style="width: 140px">Date (Week)</th>
|
||||||
|
<th class="tdLarge noselect nonclickable" style="width: 120px">Venue</th>
|
||||||
|
<th class="tdLarge noselect nonclickable" style="width: 90px">Actions</th>
|
||||||
|
</tr>
|
||||||
|
<tr class="footers">
|
||||||
|
<th>{{>SaleSearch columnName='amount' width='90%'}}</th>
|
||||||
|
<th>{{>SaleSearch columnName='productId' collectionQueryColumnName='name' collection='Products' collectionResultColumnName='_id' width='90%'}}</th>
|
||||||
|
<th>{{>SaleSearch columnName='price' width='90%'}}</th>
|
||||||
|
<th>{{>SaleSearch columnName='measureId' collectionQueryColumnName='name' collection='Measures' collectionResultColumnName='_id' width='90%'}}</th>
|
||||||
|
<th></th>
|
||||||
|
<th>{{>SaleSearch columnName='venueId' collectionQueryColumnName='name' collection='Venues' collectionResultColumnName='_id' width='90%'}}</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{#each sales}}
|
||||||
|
{{> Sale}}
|
||||||
|
{{/each}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="Sale">
|
||||||
|
<tr>
|
||||||
|
<!--{{#if editable}}-->
|
||||||
|
<td class="tdLarge noselect nonclickable center">{{amount}}</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">{{measureName measureId}}</td>
|
||||||
|
<td class="tdLarge noselect nonclickable left">{{formatDate date}}</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>
|
||||||
|
<!--<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>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="SaleSearch">
|
||||||
|
<input type="text" class="searchInput" placeholder="Filter..." value="{{searchValue}}" style="padding-right: 10px; width: {{width}}"/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="InsertSale">
|
||||||
|
<form id="insertSale" autocomplete="off">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4 col-sm-6">
|
||||||
|
<div class="formGroupHeading">New Sale</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for='InsertSaleDate' class='control-label'>Date</label>
|
||||||
|
<input type="date" class="form-control" name="date" data-schema-key='date' required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for='InsertSaleProduct' class='control-label'>Product</label>
|
||||||
|
<input name="product" class="form-control" type="text" required/>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for='InsertSaleVenue' class='control-label'>Venue</label>
|
||||||
|
<input name="venue" class="form-control" type="text" required/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{#each productMeasures}}
|
||||||
|
{{>InsertSaleMeasure this}}
|
||||||
|
{{/each}}
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="submit" class="btn btn-success" value="Save Sale">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="InsertSaleMeasure">
|
||||||
|
<div class="col-md-4 col-sm-6 insertSaleMeasure">
|
||||||
|
<div class="formGroupHeading">{{name}}</div>
|
||||||
|
<input type="hidden" class="measureId" value="{{this._id}}">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class='control-label'>Amount</label>
|
||||||
|
<input type="number" class="form-control amount" name="amount" min="0" data-schema-key='amount' value="{{amount}}" required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class='control-label'>Price</label>
|
||||||
|
<input type="number" class="form-control price" name="price" min="0" data-schema-key='currency' value="{{price}}" required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class='control-label'>Total</label>
|
||||||
|
<input type="number" class="form-control total" name="total" tabindex="-1" data-schema-key='currency' value="{{total}}" readonly>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
58
imports/ui/Sales.import.styl
vendored
Normal file
58
imports/ui/Sales.import.styl
vendored
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#salesMain
|
||||||
|
margin: 10px 20px
|
||||||
|
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
|
||||||
|
|
||||||
|
.editor
|
||||||
|
height: 100%
|
||||||
|
overflow-y: auto
|
||||||
|
|
||||||
|
.insertSale
|
||||||
|
flex: none
|
||||||
|
width: 100%
|
||||||
|
|
||||||
|
.form-group, label
|
||||||
|
text-align: left
|
||||||
|
|
||||||
|
.formGroupHeading
|
||||||
|
font-size: 1.6em
|
||||||
|
font-family: "Arial Black", "Arial Bold", Gadget, sans-serif
|
||||||
|
font-style: normal
|
||||||
|
font-variant: normal
|
||||||
|
font-weight: 500
|
||||||
|
|
||||||
|
.grid
|
||||||
|
flex: auto
|
||||||
|
align-self: stretch
|
||||||
|
overflow-y: auto
|
||||||
|
overflow-x: auto
|
||||||
|
margin-bottom: 20px
|
||||||
|
border: 0
|
||||||
|
padding-top: 20px
|
||||||
|
|
||||||
|
.table > thead > tr > th
|
||||||
|
border: 0
|
||||||
|
padding-top: 0
|
||||||
|
padding-bottom: 6px
|
||||||
|
|
||||||
|
.dataTable
|
||||||
|
table-layout: fixed
|
||||||
|
|
||||||
|
.tdLarge
|
||||||
|
font-size: 1.3em
|
||||||
|
.saleRemove
|
||||||
|
color: red
|
||||||
|
margin-left: 8px
|
||||||
|
.saleEdit
|
||||||
|
color: darkblue
|
||||||
|
margin-right: 8px
|
||||||
267
imports/ui/Sales.js
Normal file
267
imports/ui/Sales.js
Normal file
@@ -0,0 +1,267 @@
|
|||||||
|
|
||||||
|
import './Sales.html';
|
||||||
|
import '/imports/util/selectize/selectize.js'
|
||||||
|
import ResizeSensor from '/imports/util/resize/ResizeSensor.js';
|
||||||
|
|
||||||
|
Tracker.autorun(function() {
|
||||||
|
Meteor.subscribe("products");
|
||||||
|
Meteor.subscribe("sales", Session.get('searchQuery'));
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.Sales.onRendered(function() {
|
||||||
|
// console.log("moving headers");
|
||||||
|
// try {
|
||||||
|
// //Move the headers into the header table that will maintain its position.
|
||||||
|
// //Link the column widths to the header widths.
|
||||||
|
// 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({
|
||||||
|
sales: function() {
|
||||||
|
return Meteor.collections.Sales.find({}, {sort: {date: -1}});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
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({
|
||||||
|
measureName: function(id) {
|
||||||
|
return Meteor.collections.Measures.findOne({_id: id}, {fields: {name: 1}}).name;
|
||||||
|
},
|
||||||
|
venueName: function(id) {
|
||||||
|
return Meteor.collections.Venues.findOne({_id: id}, {fields: {name: 1}}).name;
|
||||||
|
},
|
||||||
|
productName: function(id) {
|
||||||
|
return Meteor.collections.Products.findOne({_id: id}, {fields: {name: 1}}).name;
|
||||||
|
},
|
||||||
|
formatDate: function(date) {
|
||||||
|
return moment(date).format("MM/DD/YYYY (w)");
|
||||||
|
},
|
||||||
|
formatPrice: function(price) {
|
||||||
|
return price.toLocaleString("en-US", {style: 'currency', currency: 'USD', minimumFractionDigits: 2});
|
||||||
|
},
|
||||||
|
formatTotalPrice: function(price, amount) {
|
||||||
|
return (price * amount).toLocaleString("en-US", {style: 'currency', currency: 'USD', minimumFractionDigits: 2});
|
||||||
|
},
|
||||||
|
showTotalPrice: function(amount) {
|
||||||
|
return amount > 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.SaleSearch.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.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() {
|
||||||
|
// $('#insertSale').validator();
|
||||||
|
// $('#insertSale').data('bs.validator');
|
||||||
|
// this.products = new ReactiveVar([]);
|
||||||
|
this.selectedProduct = new ReactiveVar();
|
||||||
|
this.selectedVenue = new ReactiveVar();
|
||||||
|
});
|
||||||
|
Template.InsertSale.onRendered(function() {
|
||||||
|
$('#insertSale').validator();
|
||||||
|
// this.$('[name="product"]').
|
||||||
|
// this.autorun(function() {
|
||||||
|
// 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'});
|
||||||
|
this.$('[name="venue"]').buildCombo({cursor: Meteor.collections.Venues.find({}), selection: this.selectedVenue, textAttr: 'name', listClass: 'comboList'});
|
||||||
|
|
||||||
|
// this.autorun(function(){
|
||||||
|
// this.products.set(Meteor.collections.Products.find({}));
|
||||||
|
// }.bind(this));
|
||||||
|
});
|
||||||
|
Template.InsertSale.events({
|
||||||
|
'change #InsertSaleProduct': function(event, template) {
|
||||||
|
let selectedId = $('#InsertSaleProduct').val();
|
||||||
|
let selected = Meteor.collections.Products.findOne(selectedId);
|
||||||
|
template.selectedProduct.set(selected);
|
||||||
|
},
|
||||||
|
'click input[type="submit"]': function(event, template) {
|
||||||
|
event.preventDefault();
|
||||||
|
$('#insertSale').data('bs.validator').validate(function(isValid) {
|
||||||
|
if(isValid) {
|
||||||
|
let sales = [];
|
||||||
|
let sale = {
|
||||||
|
date: moment(template.find("[name='date']").value, "YYYY-MM-DD").toDate(),
|
||||||
|
productId: template.selectedProduct.get()._id,
|
||||||
|
venueId: template.selectedVenue.get()._id
|
||||||
|
};
|
||||||
|
let insertSaleMeasures = template.$(".insertSaleMeasure");
|
||||||
|
for(let next = 0; next < insertSaleMeasures.length; next++) {
|
||||||
|
let nextMeasure = $(insertSaleMeasures[next]);
|
||||||
|
let measureId = nextMeasure.find(".measureId").val();
|
||||||
|
let price = parseFloat(nextMeasure.find(".price").val()).toFixed(2);
|
||||||
|
let amount = parseFloat(nextMeasure.find(".amount").val()).toFixed(2);
|
||||||
|
|
||||||
|
if(amount > 0) {
|
||||||
|
let nextSale = _.clone(sale);
|
||||||
|
|
||||||
|
nextSale.measureId = measureId;
|
||||||
|
nextSale.price = price;
|
||||||
|
nextSale.amount = amount;
|
||||||
|
sales.push(nextSale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// let debug = "Inserting: ";
|
||||||
|
// for(next in sales) {
|
||||||
|
// debug += "\n\t" + next;
|
||||||
|
// }
|
||||||
|
// console.log(debug);
|
||||||
|
for(let index = 0; index < sales.length; index++) {
|
||||||
|
let next = sales[index];
|
||||||
|
console.log("Inserting: " + JSON.stringify(next));
|
||||||
|
// Meteor.collections.Sales.insert(next, function(err, id) {
|
||||||
|
// if(err) console.log(err);
|
||||||
|
// });
|
||||||
|
Meteor.call('insertSale', next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Template.InsertSale.helpers({
|
||||||
|
// sales: function() {
|
||||||
|
// return Meteor.collections.Sales;
|
||||||
|
// },
|
||||||
|
products: function() {
|
||||||
|
//return Meteor.collections.Products.find({});
|
||||||
|
//return this.products;
|
||||||
|
return [{label: "Hermies", value: 1}, {label: "Ralfe", value: 2}, {label: "Bob", value: 3}];
|
||||||
|
},
|
||||||
|
productMeasures: function() {
|
||||||
|
let product = Template.instance().selectedProduct.get();
|
||||||
|
let result = product ? product.measures : [];
|
||||||
|
|
||||||
|
for(let i = 0; i < result.length; i++) {
|
||||||
|
result[i] = Meteor.collections.Measures.findOne(result[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(product) console.log("Found " + result.length + " measures for the product " + product.name);
|
||||||
|
else console.log("No product!");
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
venues: function() {
|
||||||
|
return Meteor.collections.Venues.find({});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.InsertSaleMeasure.onCreated(function() {
|
||||||
|
let prices = this.parentTemplate().selectedProduct.get().prices;
|
||||||
|
let price = 0;
|
||||||
|
|
||||||
|
if(prices) price = prices[this._id];
|
||||||
|
|
||||||
|
this.price = new ReactiveVar(price);
|
||||||
|
this.amount = new ReactiveVar(0);
|
||||||
|
});
|
||||||
|
Template.InsertSaleMeasure.events({
|
||||||
|
'change .price': function(event, template) {
|
||||||
|
template.price.set(parseFloat($(event.target).val()).toFixed(2));
|
||||||
|
},
|
||||||
|
'change .amount': function(event, template) {
|
||||||
|
template.amount.set(parseFloat($(event.target).val()).toFixed(2));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Template.InsertSaleMeasure.helpers({
|
||||||
|
price: function() {
|
||||||
|
return Template.instance().price.get();
|
||||||
|
},
|
||||||
|
total: function() {
|
||||||
|
let template = Template.instance();
|
||||||
|
return template.price.get() * template.amount.get();
|
||||||
|
},
|
||||||
|
amount: function() {
|
||||||
|
return Template.instance().amount.get();
|
||||||
|
}
|
||||||
|
});
|
||||||
34
imports/ui/Subcategories.html
Normal file
34
imports/ui/Subcategories.html
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<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
Normal file
52
imports/ui/Subcategories.import.styl
vendored
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
#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);
|
||||||
76
imports/ui/Subcategories.js
Normal file
76
imports/ui/Subcategories.js
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
|
||||||
|
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] : '';
|
||||||
|
}
|
||||||
|
});
|
||||||
90
imports/ui/UserManagement.html
Normal file
90
imports/ui/UserManagement.html
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
<template name="UserManagement">
|
||||||
|
<div id="userManagement">
|
||||||
|
{{#if Template.subscriptionsReady}}
|
||||||
|
<div class="insert">
|
||||||
|
{{>UserInsert}}
|
||||||
|
</div>
|
||||||
|
<div class="grid">
|
||||||
|
<table class="dataTable table table-striped table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr class="headers">
|
||||||
|
<th>Username</th>
|
||||||
|
<th>Email</th>
|
||||||
|
<th>Roles</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
<tr class="footers">
|
||||||
|
<th>{{>UserSearch columnName='username' maxWidth='40' minWidth='30'}}</th>
|
||||||
|
<th>{{>UserSearch columnName='email' collectionQueryColumnName='name' collection='Items' collectionResultColumnName='_id' maxWidth='150' minWidth='50'}}</th>
|
||||||
|
<th></th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{#each users}}
|
||||||
|
{{> User}}
|
||||||
|
{{/each}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="User">
|
||||||
|
<tr>
|
||||||
|
{{#if editing}}
|
||||||
|
<td><input name="username" class="form-control" type="text" value="{{username}}" required></td>
|
||||||
|
<td><input name="email" class="form-control" type="text" value="{{email}}" required></td>
|
||||||
|
<td class="roles center" style="font-size: 1.2em">
|
||||||
|
{{#each allRoles}}
|
||||||
|
<span class="role {{getRoleState this}} noselect">{{name}}</span>
|
||||||
|
{{/each}}
|
||||||
|
</td>
|
||||||
|
<td class="center tdLarge"><i class="editorApply fa fa-check-square-o fa-lg noselect clickable" aria-hidden="true"></i> / <i class="editorCancel fa fa-times-circle fa-lg noselect clickable" aria-hidden="true"></i></td>
|
||||||
|
{{else}}
|
||||||
|
<td class="tdLarge noselect nonclickable">{{username}}</td>
|
||||||
|
<td class="tdLarge noselect nonclickable">{{email}}</td>
|
||||||
|
<td class="tdLarge noselect nonclickable">{{roles}}</td>
|
||||||
|
<td class="center tdLarge"><i class="userRemove fa fa-times-circle fa-lg noselect clickable" aria-hidden="true"></i> / <i class="userEdit fa fa-pencil-square-o fa-lg noselect clickable" aria-hidden="true"></i></td>
|
||||||
|
{{/if}}
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="UserSearch">
|
||||||
|
<div class="">
|
||||||
|
<input type="text" class="searchInput" placeholder="Filter..." value="{{searchValue}}" style="max-width: {{maxWidth}}px; min-width: {{minWidth}}px;"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="UserInsert">
|
||||||
|
<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 User</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class='control-label'>User Name</label>
|
||||||
|
<input name="username" type="text" class="form-control" required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class='control-label'>Email</label>
|
||||||
|
<input name="email" class="form-control" type="text" required/>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class='control-label'>Roles</label>
|
||||||
|
<div class="roles">
|
||||||
|
{{#each allRoles}}
|
||||||
|
<span class="role">{{name}}</span>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="submit" class="btn btn-success" value="Create">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3 col-sm-0"></div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</template>
|
||||||
87
imports/ui/UserManagement.import.styl
vendored
Normal file
87
imports/ui/UserManagement.import.styl
vendored
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
#userManagement
|
||||||
|
margin: 20px 20px
|
||||||
|
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
|
||||||
|
|
||||||
|
.editor
|
||||||
|
height: 100%
|
||||||
|
overflow-y: auto
|
||||||
|
|
||||||
|
.insert
|
||||||
|
flex: none
|
||||||
|
width: 100%
|
||||||
|
|
||||||
|
.col-md-6
|
||||||
|
padding: 10px 30px 0 30px
|
||||||
|
background: #EFEFEF
|
||||||
|
border-radius: 1em
|
||||||
|
|
||||||
|
.formGroupHeading
|
||||||
|
font-size: 1.6em
|
||||||
|
font-family: "Arial Black", "Arial Bold", Gadget, sans-serif
|
||||||
|
font-style: normal
|
||||||
|
font-variant: normal
|
||||||
|
font-weight: 500
|
||||||
|
|
||||||
|
.grid
|
||||||
|
flex: auto
|
||||||
|
align-self: stretch
|
||||||
|
overflow-y: auto
|
||||||
|
overflow-x: auto
|
||||||
|
margin-bottom: 20px
|
||||||
|
border: 0
|
||||||
|
padding-top: 20px
|
||||||
|
|
||||||
|
.table > thead > tr > th
|
||||||
|
border: 0
|
||||||
|
padding-top: 0
|
||||||
|
padding-bottom: 6px
|
||||||
|
|
||||||
|
.dataTable
|
||||||
|
table-layout: fixed
|
||||||
|
|
||||||
|
.tdLarge
|
||||||
|
font-size: 1.5em
|
||||||
|
.userRemove
|
||||||
|
color: red
|
||||||
|
.userEdit
|
||||||
|
color: darkblue
|
||||||
|
.editorApply
|
||||||
|
color: green
|
||||||
|
.editorCancel
|
||||||
|
color: red
|
||||||
|
td.roles
|
||||||
|
.role
|
||||||
|
padding: 4px 4px
|
||||||
|
border: 1px solid #555
|
||||||
|
border-radius: .25em
|
||||||
|
background: white
|
||||||
|
color: #999
|
||||||
|
cursor: pointer
|
||||||
|
.selected
|
||||||
|
color: black
|
||||||
|
|
||||||
|
div.roles
|
||||||
|
padding: 4px 0
|
||||||
|
.role
|
||||||
|
padding: 4px 4px
|
||||||
|
border: 1px solid #555
|
||||||
|
border-radius: .25em
|
||||||
|
background: white
|
||||||
|
color: #999
|
||||||
|
cursor: pointer
|
||||||
|
.selected
|
||||||
|
color: black
|
||||||
|
.center
|
||||||
|
vertical-align: middle !important
|
||||||
178
imports/ui/UserManagement.js
Normal file
178
imports/ui/UserManagement.js
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
|
||||||
|
import './UserManagement.html';
|
||||||
|
import '/imports/util/selectize/selectize.js'
|
||||||
|
|
||||||
|
Tracker.autorun(function() {
|
||||||
|
Meteor.subscribe("users", Session.get('searchQuery'));
|
||||||
|
Meteor.subscribe("roles");
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.UserManagement.helpers({
|
||||||
|
users: function() {
|
||||||
|
return Meteor.collections.Users.find({}, {sort: {username: 1}});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.User.onCreated(function() {
|
||||||
|
this.edited = new ReactiveVar();
|
||||||
|
});
|
||||||
|
Template.User.events({
|
||||||
|
"click .userEdit": function(event, template) {
|
||||||
|
template.edited.set(this);
|
||||||
|
},
|
||||||
|
"click .userRemove": function(event, template) {
|
||||||
|
let _this = this;
|
||||||
|
bootbox.confirm({
|
||||||
|
message: "Delete the user?",
|
||||||
|
buttons: {confirm: {label: "Yes", className: 'btn-success'}, cancel: {label: "No", className: "btn-danger"}},
|
||||||
|
callback: function(result) {
|
||||||
|
if(result) {
|
||||||
|
Meteor.call('deleteUser', _this._id, function(error, result) {
|
||||||
|
if(error) {
|
||||||
|
sAlert.error(error);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sAlert.success("User removed.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
"click .editorCancel": function(event, template) {
|
||||||
|
template.edited.set(undefined);
|
||||||
|
},
|
||||||
|
"click .editorApply": function(event, template) {
|
||||||
|
let username = template.$("input[name='username']").val().trim();
|
||||||
|
let email = template.$("input[name='email']").val().trim();
|
||||||
|
let roleSpans = template.$(".roles > span");
|
||||||
|
let roles = [];
|
||||||
|
|
||||||
|
for(let i = 0; i < roleSpans.length; i++) {
|
||||||
|
if($(roleSpans[i]).hasClass("selected")) {
|
||||||
|
roles.push($(roleSpans[i]).text());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Basic validation.
|
||||||
|
if(username && username.length > 0 && email && email.length > 0) {
|
||||||
|
let emails = _.clone(this.emails);
|
||||||
|
|
||||||
|
if(!emails || emails.length == 0) {
|
||||||
|
emails = [{address: email, verified: true}];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
emails[0].address = email;
|
||||||
|
emails[0].verified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Meteor.call("updateUser", {_id: this._id, username: username, emails: emails, roles: roles}, function(error, result) {
|
||||||
|
if(error) {
|
||||||
|
sAlert.error(error);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sAlert.success("User updated.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
template.edited.set(undefined);
|
||||||
|
},
|
||||||
|
"click .role": function(event, template) {
|
||||||
|
$(event.target).toggleClass("selected");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Template.User.helpers({
|
||||||
|
email: function() {
|
||||||
|
return this.emails && this.emails.length > 0 ? this.emails[0].address : "";
|
||||||
|
},
|
||||||
|
editing: function() {
|
||||||
|
return Template.instance().edited.get() == this;
|
||||||
|
},
|
||||||
|
allRoles: function() {
|
||||||
|
return Meteor.collections.UserRoles.find();
|
||||||
|
},
|
||||||
|
getRoleState: function(role) {
|
||||||
|
let user = Template.parentData(1);
|
||||||
|
|
||||||
|
return user.roles.includes(role.name) ? "selected" : "";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.UserSearch.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.UserSearch.helpers({
|
||||||
|
searchValue: function() {
|
||||||
|
let searchFields = Session.get('searchFields');
|
||||||
|
|
||||||
|
return (searchFields && searchFields[this.columnName]) ? searchFields[this.columnName] : '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.UserInsert.onRendered(function() {
|
||||||
|
this.$('form[name="insert"]').validator();
|
||||||
|
});
|
||||||
|
Template.UserInsert.events({
|
||||||
|
'click input[type="submit"]': function(event, template) {
|
||||||
|
event.preventDefault();
|
||||||
|
template.$('form[name="insert"]').data('bs.validator').validate(function(isValid) {
|
||||||
|
if(isValid) {
|
||||||
|
let user = {};
|
||||||
|
let roles = [];
|
||||||
|
|
||||||
|
user.username = template.$('input[name="username"]').val();
|
||||||
|
user.email = template.$('input[name="email"]').val();
|
||||||
|
|
||||||
|
let roleSpans = template.$('.role.selected');
|
||||||
|
for(let i = 0; i < roleSpans.length; i++) {
|
||||||
|
roles.push($(roleSpans[i]).text());
|
||||||
|
}
|
||||||
|
|
||||||
|
Meteor.call('insertUser', user, roles, function(error, result) {
|
||||||
|
if(error) {
|
||||||
|
sAlert.error(error);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sAlert.success("User created.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
"click .role": function(event, template) {
|
||||||
|
$(event.target).toggleClass("selected");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Template.UserInsert.helpers({
|
||||||
|
allRoles: function() {
|
||||||
|
return Meteor.collections.UserRoles.find();
|
||||||
|
}
|
||||||
|
});
|
||||||
65
imports/ui/accounts/accounts.html
Normal file
65
imports/ui/accounts/accounts.html
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
<template name="Auth_page">
|
||||||
|
<div class="page auth">
|
||||||
|
<nav>
|
||||||
|
<div class="nav-group">
|
||||||
|
<a href="#" class="js-menu nav-item">
|
||||||
|
<span class="icon-list-unordered"></span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="content-scrollable">
|
||||||
|
<div class="wrapper-auth">
|
||||||
|
{{> atForm}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="override-atPwdFormBtn">
|
||||||
|
<button type="submit" class="btn-primary">
|
||||||
|
{{buttonText}}
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="override-atTextInput">
|
||||||
|
<div class="input {{#if isValidating}}validating{{/if}} {{#if hasError}}error{{/if}} {{#if hasSuccess}}has-success{{/if}} {{#if feedback}}has-feedback{{/if}}">
|
||||||
|
<input type="{{type}}" id="at-field-{{_id}}" name="at-field-{{_id}}" placeholder="{{placeholder}}" autocapitalize="none" autocorrect="off">
|
||||||
|
{{#if hasIcon}}
|
||||||
|
<span class="{{iconClass}}"></span>
|
||||||
|
{{/if}}
|
||||||
|
{{#if hasError}}
|
||||||
|
<span>{{errorText}}</span>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="override-atTitle">
|
||||||
|
<h1 class="title-auth">{{title}}</h1>
|
||||||
|
<p class="subtitle-auth">Signing in allows you to have private lists</p>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="override-atError">
|
||||||
|
<div class="list-errors">
|
||||||
|
{{#each error}}
|
||||||
|
<div class="list-item">{{errorText}}</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="override-atPwdForm">
|
||||||
|
<div class="at-pwd-form">
|
||||||
|
<form role="form" id="at-pwd-form" class="{{disabled}}" novalidate action="#" method="POST">
|
||||||
|
{{#each fields}}
|
||||||
|
{{> atInput}}
|
||||||
|
{{/each}}
|
||||||
|
{{#if showReCaptcha}}
|
||||||
|
{{> atReCaptcha}}
|
||||||
|
{{/if}}
|
||||||
|
{{> atPwdFormBtn}}
|
||||||
|
{{#if showForgotPasswordLink}}
|
||||||
|
{{> atPwdLink}}
|
||||||
|
{{/if}}
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
11
imports/ui/accounts/accounts.js
Normal file
11
imports/ui/accounts/accounts.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { Template } from 'meteor/templating';
|
||||||
|
|
||||||
|
import './accounts.html';
|
||||||
|
|
||||||
|
// We identified the templates that need to be overridden by looking at the available templates
|
||||||
|
// here: https://github.com/meteor-useraccounts/unstyled/tree/master/lib
|
||||||
|
// Template['override-atPwdFormBtn'].replaces('atPwdFormBtn');
|
||||||
|
// Template['override-atPwdForm'].replaces('atPwdForm');
|
||||||
|
// Template['override-atTextInput'].replaces('atTextInput');
|
||||||
|
// Template['override-atTitle'].replaces('atTitle');
|
||||||
|
// Template['override-atError'].replaces('atError');
|
||||||
8
imports/ui/helpers.js
Normal file
8
imports/ui/helpers.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
// General use helpers - available to all views.
|
||||||
|
|
||||||
|
UI.registerHelper('currentUserName', function() {
|
||||||
|
if(Meteor.user()){
|
||||||
|
return Meteor.user().emails[0].address;
|
||||||
|
}
|
||||||
|
});
|
||||||
106
imports/ui/layouts/Body.html
Normal file
106
imports/ui/layouts/Body.html
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
<template name="Body">
|
||||||
|
{{> sAlert}}
|
||||||
|
<div id="layoutBody">
|
||||||
|
<div class="mainBody">
|
||||||
|
<div class="leftSidebar">
|
||||||
|
<i class="fa fa-sign-out fa-2x signOut" aria-hidden="true"></i>
|
||||||
|
<div class="logo">
|
||||||
|
<img src="/images/PetitTetonLogo_v2.png"/>
|
||||||
|
</div>
|
||||||
|
<ul>
|
||||||
|
{{#if isInRole 'manage'}}
|
||||||
|
<li class="{{isActiveRoute 'UserManagement'}}">
|
||||||
|
<a href="{{pathFor 'UserManagement'}}">
|
||||||
|
User Management
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
<li class="{{isActiveRoute 'Sales'}}">
|
||||||
|
<a href="{{pathFor 'Sales'}}">
|
||||||
|
Sales <span class="tag">Test Tag</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="{{isActiveRoute 'Production'}}">
|
||||||
|
<a href="{{pathFor 'Production'}}">
|
||||||
|
Production <span class="tag">sample</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="{{isActiveRoute 'Products'}}">
|
||||||
|
<a href="{{pathFor 'Products'}}">
|
||||||
|
Products
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="{{isActiveRoute 'Pricing'}}">
|
||||||
|
<a href="{{pathFor 'Pricing'}}">
|
||||||
|
Pricing
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="{{isActiveRoute 'ProductTags'}}">
|
||||||
|
<a href="{{pathFor 'ProductTags'}}">
|
||||||
|
Tags
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="{{isActiveRoute 'Measures'}}">
|
||||||
|
<a href="{{pathFor 'Measures'}}">
|
||||||
|
Measures
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="contentBody">
|
||||||
|
<div class="contentContainer">
|
||||||
|
<div class="header">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
{{> Template.dynamic template=content}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="footer">
|
||||||
|
© Petit Teton LLC 2017
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!--<template name="Body">-->
|
||||||
|
<!--<div id="layoutBody">-->
|
||||||
|
<!--<div class="bodyTableRow">-->
|
||||||
|
<!--<div class="left bodyTableCell">-->
|
||||||
|
<!--<ul>-->
|
||||||
|
<!--{{#if isInRole 'manage'}}-->
|
||||||
|
<!--<li class="{{isActiveRoute 'UserManagement'}}">-->
|
||||||
|
<!--<a href="{{pathFor 'UserManagement'}}">-->
|
||||||
|
<!--User Management-->
|
||||||
|
<!--</a>-->
|
||||||
|
<!--</li>-->
|
||||||
|
<!--{{/if}}-->
|
||||||
|
<!--<li class="{{isActiveRoute 'Sales'}}">-->
|
||||||
|
<!--<a href="{{pathFor 'Sales'}}">-->
|
||||||
|
<!--Sales <span class="tag">Test Tag</span>-->
|
||||||
|
<!--</a>-->
|
||||||
|
<!--</li>-->
|
||||||
|
<!--<li class="{{isActiveRoute 'Production'}}">-->
|
||||||
|
<!--<a href="{{pathFor 'Production'}}">-->
|
||||||
|
<!--Production <span class="tag">sample</span>-->
|
||||||
|
<!--</a>-->
|
||||||
|
<!--</li>-->
|
||||||
|
<!--</ul>-->
|
||||||
|
<!--</div>-->
|
||||||
|
<!--<div class="bodyTableCell">-->
|
||||||
|
<!--<div class="bodyTable">-->
|
||||||
|
<!--<div class="header bodyTableRow">-->
|
||||||
|
<!-- -->
|
||||||
|
<!--</div>-->
|
||||||
|
<!--<div class="content bodyTableRow">-->
|
||||||
|
<!--{{> Template.dynamic template=content}}-->
|
||||||
|
<!--</div>-->
|
||||||
|
<!--</div>-->
|
||||||
|
<!--</div>-->
|
||||||
|
<!--</div>-->
|
||||||
|
<!--<div class="footer bodyTableRow">-->
|
||||||
|
<!--© Petit Teton LLC 2017-->
|
||||||
|
<!--</div>-->
|
||||||
|
<!--</div>-->
|
||||||
|
<!--</template>-->
|
||||||
279
imports/ui/layouts/Body.import.styl
vendored
Normal file
279
imports/ui/layouts/Body.import.styl
vendored
Normal file
@@ -0,0 +1,279 @@
|
|||||||
|
#layoutBody
|
||||||
|
width: 100%
|
||||||
|
height: 100%
|
||||||
|
display: table
|
||||||
|
text-align: center
|
||||||
|
margin: 0
|
||||||
|
padding: 0
|
||||||
|
border: 0
|
||||||
|
|
||||||
|
.mainBody
|
||||||
|
display: table
|
||||||
|
height: 100%
|
||||||
|
width: 100%
|
||||||
|
margin: 0
|
||||||
|
padding: 0
|
||||||
|
border: 0
|
||||||
|
|
||||||
|
.leftSidebar
|
||||||
|
display: table-cell
|
||||||
|
position: relative
|
||||||
|
border: 0
|
||||||
|
vertical-align: top
|
||||||
|
padding: 0
|
||||||
|
text-align: left
|
||||||
|
width: 220px
|
||||||
|
height: 100%
|
||||||
|
//Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#627d4d+0,1f3b08+100;Olive+3D
|
||||||
|
background: #90b272 //Old browsers
|
||||||
|
background: -moz-linear-gradient(-180deg, #90b272 0%, #4d7727 100%) //FF3.6-15
|
||||||
|
background: -webkit-linear-gradient(-180deg, #90b272 0%,#4d7727 100%) //Chrome10-25,Safari5.1-6
|
||||||
|
background: linear-gradient(180deg, #90b272 0%,#4d7727 100%) //W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+
|
||||||
|
font-size: 14px
|
||||||
|
font-weight: 700
|
||||||
|
|
||||||
|
.signOut
|
||||||
|
position: absolute
|
||||||
|
left: 10px
|
||||||
|
top: 10px
|
||||||
|
color: white
|
||||||
|
cursor: pointer
|
||||||
|
.signOut:hover
|
||||||
|
color: #BBB
|
||||||
|
.signOut:active
|
||||||
|
color: black
|
||||||
|
|
||||||
|
.logo
|
||||||
|
text-align: center
|
||||||
|
margin-top: 20px
|
||||||
|
|
||||||
|
ul
|
||||||
|
padding: 20px 0 0 0
|
||||||
|
margin: 0
|
||||||
|
list-style: none
|
||||||
|
|
||||||
|
li:first-child
|
||||||
|
border-top: 1px solid #e4e5e7
|
||||||
|
li
|
||||||
|
border-bottom: 1px solid #e4e5e7
|
||||||
|
color: #96a2ae
|
||||||
|
text-transform: uppercase
|
||||||
|
display: block
|
||||||
|
|
||||||
|
a
|
||||||
|
color: black
|
||||||
|
padding: 15px 20px
|
||||||
|
cursor: pointer
|
||||||
|
text-decoration: none
|
||||||
|
display: block
|
||||||
|
|
||||||
|
.tag
|
||||||
|
padding: .2em .5em
|
||||||
|
font-size: .7em
|
||||||
|
color: #fff
|
||||||
|
white-space: nowrap
|
||||||
|
vertical-align: baseline
|
||||||
|
border-radius: .25em
|
||||||
|
border: 1px solid #000000
|
||||||
|
float: right
|
||||||
|
li:hover
|
||||||
|
background-color: #333
|
||||||
|
li.active
|
||||||
|
background-color: #333
|
||||||
|
|
||||||
|
a
|
||||||
|
color: #96a2ae
|
||||||
|
.contentBody
|
||||||
|
display: table-cell
|
||||||
|
//background: #4d7727
|
||||||
|
|
||||||
|
.contentContainer
|
||||||
|
display: table
|
||||||
|
width: 100%
|
||||||
|
height: 100%
|
||||||
|
//border-radius 20px
|
||||||
|
//border: 0;
|
||||||
|
background: white
|
||||||
|
|
||||||
|
.header
|
||||||
|
display: table-row
|
||||||
|
background: #90b272
|
||||||
|
width: 100%
|
||||||
|
height: 1px
|
||||||
|
.content
|
||||||
|
display: table-row
|
||||||
|
width: 100%
|
||||||
|
-webkit-box-shadow: inset 4px 2px 6px 2px rgba(168,165,168,1)
|
||||||
|
-moz-box-shadow: inset 4px 2px 6px 2px rgba(168,165,168,1)
|
||||||
|
box-shadow: inset 4px 2px 6px 2px rgba(168,165,168,1)
|
||||||
|
.footer
|
||||||
|
display: table-row
|
||||||
|
height: 1px
|
||||||
|
text-align: center
|
||||||
|
background: #4d7727
|
||||||
|
color: white
|
||||||
|
|
||||||
|
|
||||||
|
//#layoutBody
|
||||||
|
// width: 100%
|
||||||
|
// height: 100%
|
||||||
|
// display: table
|
||||||
|
// margin: 0
|
||||||
|
// padding: 0
|
||||||
|
// border: 0
|
||||||
|
//
|
||||||
|
// .bodyTable
|
||||||
|
// display: table
|
||||||
|
// margin: 0
|
||||||
|
// padding: 0
|
||||||
|
// border: 0
|
||||||
|
// .bodyTableRow
|
||||||
|
// display: table-row
|
||||||
|
// .bodyTableCell
|
||||||
|
// display: table-cell
|
||||||
|
//
|
||||||
|
// .left
|
||||||
|
// display: table-cell
|
||||||
|
// border: 0
|
||||||
|
// vertical-align: top
|
||||||
|
// padding: 0
|
||||||
|
// text-align: left
|
||||||
|
// width: 220px
|
||||||
|
// height: 100%
|
||||||
|
// //Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#627d4d+0,1f3b08+100;Olive+3D
|
||||||
|
// background: #627d4d //Old browsers
|
||||||
|
// background: -moz-linear-gradient(-180deg, #627d4d 0%, #1f3b08 100%) //FF3.6-15
|
||||||
|
// background: -webkit-linear-gradient(-180deg, #627d4d 0%,#1f3b08 100%) //Chrome10-25,Safari5.1-6
|
||||||
|
// background: linear-gradient(180deg, #627d4d 0%,#1f3b08 100%) //W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+
|
||||||
|
// font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif
|
||||||
|
// font-size: 14px
|
||||||
|
// font-weight: 700
|
||||||
|
//
|
||||||
|
// ul
|
||||||
|
// padding: 50px 0 0 0
|
||||||
|
// margin: 0
|
||||||
|
// list-style: none
|
||||||
|
//
|
||||||
|
// li:first-child
|
||||||
|
// border-top: 1px solid #e4e5e7
|
||||||
|
// li
|
||||||
|
// border-bottom: 1px solid #e4e5e7
|
||||||
|
// color: #96a2ae
|
||||||
|
// text-transform: uppercase
|
||||||
|
// display: block
|
||||||
|
//
|
||||||
|
// a
|
||||||
|
// color: #96a2ae
|
||||||
|
// padding: 15px 20px
|
||||||
|
// cursor: pointer
|
||||||
|
// text-decoration: none
|
||||||
|
// display: block
|
||||||
|
//
|
||||||
|
// .tag
|
||||||
|
// padding: .2em .5em
|
||||||
|
// font-size: .7em
|
||||||
|
// color: #fff
|
||||||
|
// white-space: nowrap
|
||||||
|
// vertical-align: baseline
|
||||||
|
// border-radius: .25em
|
||||||
|
// border: 1px solid #000000
|
||||||
|
// float: right
|
||||||
|
// li:hover
|
||||||
|
// background-color: #333
|
||||||
|
// li.active
|
||||||
|
// background-color: #333
|
||||||
|
//
|
||||||
|
// .header
|
||||||
|
// height: 1px
|
||||||
|
// background: #627d4d
|
||||||
|
// width: 100%
|
||||||
|
// .content
|
||||||
|
// background: white
|
||||||
|
// .footer
|
||||||
|
// text-align: center
|
||||||
|
// height: 1px;
|
||||||
|
// background: #1f3b08
|
||||||
|
// color: white
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
//.header
|
||||||
|
// display: table-row
|
||||||
|
// height: 1px
|
||||||
|
// background: #627d4d
|
||||||
|
//
|
||||||
|
//#layoutBody.body
|
||||||
|
// display: table
|
||||||
|
// margin: 0
|
||||||
|
// padding: 0
|
||||||
|
// width: 100%
|
||||||
|
// height: 100%
|
||||||
|
//
|
||||||
|
// .body
|
||||||
|
// display: table-row
|
||||||
|
// width: 100%
|
||||||
|
//
|
||||||
|
// .left
|
||||||
|
// display: table-cell
|
||||||
|
// border: 0
|
||||||
|
// vertical-align: top
|
||||||
|
// padding: 0
|
||||||
|
// text-align: left
|
||||||
|
// width: 220px
|
||||||
|
// //Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#627d4d+0,1f3b08+100;Olive+3D
|
||||||
|
// background: #627d4d //Old browsers
|
||||||
|
// background: -moz-linear-gradient(-180deg, #627d4d 0%, #1f3b08 100%) //FF3.6-15
|
||||||
|
// background: -webkit-linear-gradient(-180deg, #627d4d 0%,#1f3b08 100%) //Chrome10-25,Safari5.1-6
|
||||||
|
// background: linear-gradient(180deg, #627d4d 0%,#1f3b08 100%) //W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+
|
||||||
|
// font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif
|
||||||
|
// font-size: 14px;
|
||||||
|
// font-weight: 700
|
||||||
|
//
|
||||||
|
// ul
|
||||||
|
// padding: 50px 0 0 0
|
||||||
|
// margin: 0
|
||||||
|
// list-style: none
|
||||||
|
//
|
||||||
|
// li:first-child
|
||||||
|
// border-top: 1px solid #e4e5e7
|
||||||
|
// li
|
||||||
|
// border-bottom: 1px solid #e4e5e7
|
||||||
|
// color: #96a2ae
|
||||||
|
// text-transform: uppercase
|
||||||
|
// display: block
|
||||||
|
//
|
||||||
|
// a
|
||||||
|
// color: #96a2ae
|
||||||
|
// padding: 15px 20px
|
||||||
|
// cursor: pointer
|
||||||
|
// text-decoration: none
|
||||||
|
// display: block
|
||||||
|
//
|
||||||
|
// .tag
|
||||||
|
// padding: .2em .5em
|
||||||
|
// font-size: .7em
|
||||||
|
// color: #fff
|
||||||
|
// white-space: nowrap
|
||||||
|
// vertical-align: baseline
|
||||||
|
// border-radius: .25em
|
||||||
|
// border: 1px solid #000000
|
||||||
|
// float: right
|
||||||
|
// li:hover
|
||||||
|
// background-color: #333
|
||||||
|
// li.active
|
||||||
|
// background-color: #333
|
||||||
|
// .main
|
||||||
|
// display: table-row
|
||||||
|
// background: white
|
||||||
|
// border: 0
|
||||||
|
// vertical-align: top
|
||||||
|
// padding: 0
|
||||||
|
// text-align: left
|
||||||
|
//
|
||||||
|
// .footer
|
||||||
|
// display: table-row
|
||||||
|
// text-align: center
|
||||||
|
// height: 1px;
|
||||||
|
// background: #1f3b08
|
||||||
|
// color: white
|
||||||
9
imports/ui/layouts/Body.js
Normal file
9
imports/ui/layouts/Body.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { Template } from 'meteor/templating';
|
||||||
|
import './Body.html';
|
||||||
|
|
||||||
|
|
||||||
|
Template.Body.events({
|
||||||
|
"click .signOut": function(event, template) {
|
||||||
|
AccountsTemplates.logout();
|
||||||
|
}
|
||||||
|
});
|
||||||
7
imports/ui/layouts/Full.html
Normal file
7
imports/ui/layouts/Full.html
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<template name="Full">
|
||||||
|
<div id="full" class="content">
|
||||||
|
<div class="form">
|
||||||
|
{{> Template.dynamic template=content}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
11
imports/ui/layouts/Full.import.styl
vendored
Normal file
11
imports/ui/layouts/Full.import.styl
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#full.content
|
||||||
|
//width: 100%
|
||||||
|
//height: 100%
|
||||||
|
//background-image: linear-gradient(to bottom, #315481, #918e82 100%)'
|
||||||
|
background: white
|
||||||
|
|
||||||
|
.form
|
||||||
|
//margin: 5% auto 0 auto
|
||||||
|
margin: 0 auto
|
||||||
|
width: 300px
|
||||||
|
|
||||||
1
imports/ui/layouts/Full.js
Normal file
1
imports/ui/layouts/Full.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import './Full.html';
|
||||||
19
imports/util/blaze.js
Normal file
19
imports/util/blaze.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/**
|
||||||
|
* Get the parent template instance.
|
||||||
|
* @param {Number} [levels] How many levels to go up. Default is 1
|
||||||
|
* @returns {Blaze.TemplateInstance}
|
||||||
|
*/
|
||||||
|
Blaze.TemplateInstance.prototype.parentTemplate = function(levels) {
|
||||||
|
let view = this.view;
|
||||||
|
|
||||||
|
levels = (typeof levels === "undefined") ? 1 : levels;
|
||||||
|
|
||||||
|
while(view) {
|
||||||
|
//if(view.name.substring(0, 9) === "Template." && !(levels--)) {
|
||||||
|
if(view.template && !(levels--)) {
|
||||||
|
//return view.templateInstance();
|
||||||
|
return view.templateInstance();
|
||||||
|
}
|
||||||
|
view = view.parentView;
|
||||||
|
}
|
||||||
|
};
|
||||||
11
imports/util/csv.js
Normal file
11
imports/util/csv.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
let fs = require("fs");
|
||||||
|
let csv = require('csv-parse');
|
||||||
|
let result = function(csvFilePath, callback) {
|
||||||
|
let parser = csv(Assets.getText(csvFilePath), {delimiter: '\t'}, function(error, data) {
|
||||||
|
if(error) callback(error);
|
||||||
|
else callback(null, data);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export default result;
|
||||||
9
imports/util/date.js
Normal file
9
imports/util/date.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
//
|
||||||
|
// Add a method to get a timezone adjusted date for an input field that is a date picker.
|
||||||
|
// Use $('input[name="date"]').val(new Date().toDateInputValue()) to set the date of the input field.
|
||||||
|
//
|
||||||
|
Date.prototype.toDateInputValue = (function() {
|
||||||
|
let local = new Date(this);
|
||||||
|
local.setMinutes(this.getMinutes() - this.getTimezoneOffset());
|
||||||
|
return local.toJSON().slice(0,10);
|
||||||
|
});
|
||||||
31
imports/util/de.combo.import.styl
vendored
Normal file
31
imports/util/de.combo.import.styl
vendored
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
.comboList {
|
||||||
|
z-index: 1000;
|
||||||
|
max-height: 160px;
|
||||||
|
overflow-y: auto;
|
||||||
|
-moz-box-shadow: 0 2px 3px #ccc;
|
||||||
|
-webkit-box-shadow: 0 2px 3px #ccc;
|
||||||
|
box-shadow: 0 2px 3px #ccc;
|
||||||
|
border: 1px solid #d1d1d1;
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
display: none;
|
||||||
|
background: white;
|
||||||
|
|
||||||
|
li {
|
||||||
|
display: block;
|
||||||
|
padding: 5px 10px;
|
||||||
|
margin: 0;
|
||||||
|
text-indent: 0
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
li.selected {
|
||||||
|
background-color: #ffe184 !important;
|
||||||
|
}
|
||||||
|
li[role='node'] {
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
li[role='leaf'] {
|
||||||
|
padding-left: 2em;
|
||||||
|
}
|
||||||
|
}
|
||||||
398
imports/util/de.combo.js
Normal file
398
imports/util/de.combo.js
Normal file
@@ -0,0 +1,398 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
//
|
||||||
|
// Takes a input form element and a hidden form element (to store the selected id in) along with an array of objects, to build a dropdown select control that allows the user to type part of the selection to filter the list.
|
||||||
|
// Modified for meteor.
|
||||||
|
//
|
||||||
|
(function($) {
|
||||||
|
let Combo = function($input, $hidden, options) {
|
||||||
|
let _this = this;
|
||||||
|
|
||||||
|
this.focusCounter = 0;
|
||||||
|
this.$input = $input;
|
||||||
|
this.$hidden = $hidden;
|
||||||
|
this.options = $.extend({}, Combo.DEFAULTS, options);
|
||||||
|
this.$selected = null;
|
||||||
|
this.$listContainer = $('<div/>', {style: 'position: relative; height: 0;'});
|
||||||
|
this.$list = $('<ul/>', {role: 'menu', class: this.options.listClass});
|
||||||
|
|
||||||
|
//Ensure that if the hidden field exists and changes, that the hidden field's id matches the text in the input field. If not then the hidden id field was changed manually and externally and the text field should be updated.
|
||||||
|
if(this.$hidden) {
|
||||||
|
this.$hidden.on('change', hiddenInputChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
function hiddenInputChanged() {
|
||||||
|
let id = _this.$hidden.val();
|
||||||
|
let $li = _this.$list.children("[role!='node']");
|
||||||
|
|
||||||
|
for(let i = 0; i < $li.length; i++) {
|
||||||
|
let $next = $($li[i]);
|
||||||
|
|
||||||
|
if($next.data('model').id == id) {
|
||||||
|
if(_this.$input.val() != $next.text())
|
||||||
|
_this.$input.val($next.text());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//this.$list.appendTo($input.parent());
|
||||||
|
this.$list.appendTo(this.$listContainer);
|
||||||
|
this.$listContainer.appendTo($input.parent());
|
||||||
|
|
||||||
|
//Setup the list to highlight the item the user is hovering over, to select the item the user clicks, and to remove the hover styling when the list closes due to a selection being made.
|
||||||
|
this.$list
|
||||||
|
.on('mousemove', 'li', function() {
|
||||||
|
// _this.$list.find(_this.options.selectionClass).removeClass(_this.options.selectionClass);
|
||||||
|
let $this = $(this);
|
||||||
|
|
||||||
|
//Skip nodes.
|
||||||
|
while($this && $this.attr('role') == 'node') {
|
||||||
|
$this = $this.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
//If we could find a non-node element then highlight it.
|
||||||
|
if($this) $this.addClass(_this.options.selectionClass).siblings().removeClass(_this.options.selectionClass);
|
||||||
|
})
|
||||||
|
.on('mousedown', 'li', function() {
|
||||||
|
let $this = $(this);
|
||||||
|
|
||||||
|
//Skip nodes.
|
||||||
|
while($this && $this.attr('role') == 'node') {
|
||||||
|
$this = $this.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
//If we could find a non-node element then highlight it.
|
||||||
|
if($this) _this.select($this);
|
||||||
|
})
|
||||||
|
.on('mouseup', 'li', function() {
|
||||||
|
//Remove the selection highlighting.
|
||||||
|
_this.$list.children().removeClass(_this.options.selectionClass);
|
||||||
|
//Hide the list.
|
||||||
|
_this.hide();
|
||||||
|
});
|
||||||
|
//Setup the input field to handle opening the list when it receives focus, and close it when it loses focus.
|
||||||
|
this.$input
|
||||||
|
.on('focus', $.proxy(_this.focus, _this))
|
||||||
|
.on('blur', $.proxy(_this.blur, _this));
|
||||||
|
// this.$listContainer
|
||||||
|
// .on('focus', $.proxy(_this.focus, _this, "list container"))
|
||||||
|
// .on('blur', $.proxy(_this.blur, _this, "list container"));
|
||||||
|
// this.$list
|
||||||
|
// .on('focus', $.proxy(_this.focus, _this, "list"))
|
||||||
|
// .on('blur', $.proxy(_this.blur, _this, "list"));
|
||||||
|
//Handle key events on the input field. Up/down arrows should change the selection in the list. Enter should select an item and close the list. Tab and escape should hide the list before moving to the next focusable element on the page.
|
||||||
|
this.$input.on('input keydown', function(event) {
|
||||||
|
switch(event.keyCode) {
|
||||||
|
case 38: { //Up
|
||||||
|
let visibles = _this.$list.find('li.visible[role!="node"]');
|
||||||
|
let selected = visibles.index(visibles.filter('.' + _this.options.selectionClass)) || 0;
|
||||||
|
_this.highlight(selected - 1);
|
||||||
|
event.preventDefault();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 40: { //Down
|
||||||
|
let visibles = _this.$list.find('li.visible[role!="node"]');
|
||||||
|
let selected = visibles.index(visibles.filter('li.selected')) || 0;
|
||||||
|
_this.highlight(selected + 1);
|
||||||
|
event.preventDefault();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 13: //Enter
|
||||||
|
if(_this.$list.is(':visible')) {
|
||||||
|
_this.select(_this.$list.find('li.selected'));
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 9: //Tab
|
||||||
|
_this.select(_this.$list.find('li.selected'));
|
||||||
|
break;
|
||||||
|
case 27: //Esc
|
||||||
|
if(_this.$input.hasClass('open')) {
|
||||||
|
_this.hide();
|
||||||
|
//Try to stop any default behavior from occurring.
|
||||||
|
if(event.stopPropagation) event.stopPropagation();
|
||||||
|
else event.cancelBubble = true; //IE 6-8
|
||||||
|
event.preventDefault();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
_this.filter();
|
||||||
|
_this.highlight(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
// Adds one or more elements to the control.
|
||||||
|
// data: The item or array of items to add. This will be the root tree elements if groupFunctions is provided.
|
||||||
|
function add(data) {
|
||||||
|
let groupFunctions = _this.options.groupFunctions;
|
||||||
|
|
||||||
|
let addOne = function(data, parent) { //role is optional.
|
||||||
|
let text = $.isFunction(_this.options.textAttr) ? _this.options.textAttr(data) : data[_this.options.textAttr];
|
||||||
|
let li = $("<li" + (parent ? " role='leaf'" : "") + ">" + text + "</li>");
|
||||||
|
|
||||||
|
li.appendTo(_this.$list);
|
||||||
|
li.data('model', data);
|
||||||
|
if(parent) li.data('parent-li', parent);
|
||||||
|
};
|
||||||
|
let addOneGroup = function(data, text, children) {
|
||||||
|
let li = $("<li role='node'>" + text + "</li>");
|
||||||
|
|
||||||
|
li.appendTo(_this.$list);
|
||||||
|
li.data('model', data);
|
||||||
|
|
||||||
|
for(let childIndex = 0; childIndex < children.length; childIndex++) {
|
||||||
|
addOne(children[childIndex], li);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let addOneBranch = function(data) {
|
||||||
|
let parents = $.isFunction(groupFunctions.groupParents) ? groupFunctions.groupParents(data) : data;
|
||||||
|
|
||||||
|
//Since there may be one or more parents identified for each data element passed to us...
|
||||||
|
if(Array.isArray(parents)) {
|
||||||
|
for(let parentIndex = 0; parentIndex < parents.length; parentIndex++) {
|
||||||
|
addOneGroup(parents[parentIndex], groupFunctions.parentText(parents[parentIndex]), groupFunctions.children(parents[parentIndex]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
addOneGroup(parents, groupFunctions.parentText(parents), groupFunctions.children(parents));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if(groupFunctions instanceof Object && $.isFunction(groupFunctions.children) && $.isFunction(groupFunctions.parentText)) {
|
||||||
|
if(Array.isArray(data)) {
|
||||||
|
for(let dataIndex = 0; dataIndex < data.length; dataIndex++) {
|
||||||
|
addOneBranch(data[dataIndex]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
addOneBranch(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(Array.isArray(data)) {
|
||||||
|
for(let dataIndex = 0; dataIndex < data.length; dataIndex++) {
|
||||||
|
addOne(data[dataIndex]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
addOne(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Filter the set of elements so that only those matching the text in the input field are marked as visible.
|
||||||
|
_this.filter();
|
||||||
|
}
|
||||||
|
|
||||||
|
Tracker.autorun(function() {
|
||||||
|
this.$list.empty();
|
||||||
|
//Add the initial set of data.
|
||||||
|
add(options.cursor.fetch());
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
|
//Check the hidden input field for an ID, and setup the selection based in it if there is one.
|
||||||
|
if(this.$hidden && _this.$hidden.val()) {
|
||||||
|
hiddenInputChanged();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Combo.DEFAULTS = {
|
||||||
|
cursor: undefined, //A meteor Cursor.
|
||||||
|
selection: undefined, //A meteor ReactiveVar whose value will be set to the current selection.
|
||||||
|
textAttr: 'text', //The attribute of the data elements to use for the name. This can also be a function that takes the data object and returns the text.
|
||||||
|
idAttr: 'id', //The attribute of the data elements to use for the ID. This can also be a function that takes the data obejct and returns the ID.
|
||||||
|
// groupFunctions: The object containing three functions: 'groupParent', 'parentText', 'children'.
|
||||||
|
// groupParents(data) will take a data element and return the objects that best represents the parents of the children (for a multi layer tree, this would be the node just before the leaf nodes).
|
||||||
|
// parentText(parent) will be passed the group parent and the data object that generated it, and will return the text that represents the path to that parent.
|
||||||
|
// children(parent) will be passed the group parent (returned by groupParents()), and will return an array of children or leaf nodes for the tree.
|
||||||
|
groupFunctions: undefined,
|
||||||
|
filter: true, //Whether to filter the list as the user types.
|
||||||
|
effects: 'fade',
|
||||||
|
duration: '200',
|
||||||
|
listClass: 'de.combo-list',
|
||||||
|
selectionClass: 'selected' //The class to use for the selected element in the dropdown list.
|
||||||
|
};
|
||||||
|
|
||||||
|
Combo.prototype.select = function($li) {
|
||||||
|
if($li.length == 0) {
|
||||||
|
if(this.$input.val() != '') {
|
||||||
|
this.$input.val("")
|
||||||
|
if(this.$hidden) this.$hidden.val(undefined).change();
|
||||||
|
this.filter();
|
||||||
|
//Note: Don't trigger the select event - for some reason it causes the dropdown to reopen and the control to retain focus when clicking out of the widget.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(!this.$list.has($li) || !$li.is('li.visible')) return;
|
||||||
|
|
||||||
|
//No need to change selection if the selection has not changed.
|
||||||
|
if(this.$input.val() != $li.text()) {
|
||||||
|
this.$input.val($li.text()); //Save the selected text into the text input.
|
||||||
|
if(this.$hidden) {
|
||||||
|
this.$hidden.val($li.data('model')[this.options.idAttr]);
|
||||||
|
this.$hidden.change();
|
||||||
|
} //Save the ID into the hidden form input if it exists.
|
||||||
|
this.hide();
|
||||||
|
this.filter();
|
||||||
|
//this.trigger('select', $li);
|
||||||
|
|
||||||
|
//Set the reactive var for the selection if one is provided.
|
||||||
|
if(this.options.selection) {
|
||||||
|
this.options.selection.set($li.data('model'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//Filters the list items by marking those that match the text in the text field as having the class 'visible'.
|
||||||
|
Combo.prototype.filter = function() {
|
||||||
|
try {
|
||||||
|
let search = this.$input.val();
|
||||||
|
let _this = this;
|
||||||
|
|
||||||
|
search = search ? search : "";
|
||||||
|
search = search.toLowerCase().trim();
|
||||||
|
|
||||||
|
//Show all list elements.
|
||||||
|
this.$list.find('li').addClass('visible').show();
|
||||||
|
//Hide any node list elements.
|
||||||
|
this.$list.find('li[role="node"]').removeClass('visible').hide();
|
||||||
|
|
||||||
|
if(this.options.filter) {
|
||||||
|
//Hide non-node elements (leaf nodes) that don't match.
|
||||||
|
let li = this.$list.children();
|
||||||
|
|
||||||
|
let searches = search && search.length > 0 ? search.split(/\s+/) : undefined;
|
||||||
|
let regexs = searches ? [] : undefined;
|
||||||
|
|
||||||
|
if(searches) {
|
||||||
|
for(let i = 0; i < searches.length; i++) {
|
||||||
|
regexs.push(new RegExp("\\b" + searches[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Iterate over the list elements:
|
||||||
|
// hide all list items that are nodes;
|
||||||
|
// show all list items that are not nodes and whose text matches the input value;
|
||||||
|
// show all node list items associated with visible child list items (they occur after the parent, so the parent will be hidden first, then made visible).
|
||||||
|
for(let i = 0; i < li.length; i++) {
|
||||||
|
let $next = $(li[i]);
|
||||||
|
let node = $next.attr('role') == 'node';
|
||||||
|
//let hidden = node || $next.text().toLowerCase().indexOf(search) < 0;
|
||||||
|
let text = $next.text().toLowerCase();
|
||||||
|
let match = true;
|
||||||
|
|
||||||
|
if(!node && searches) {
|
||||||
|
for(let i = 0; match && i < regexs.length; i++) {
|
||||||
|
match = regexs[i].test(text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//let match = text.match(/\bxxx/gi);
|
||||||
|
let hidden = node || !match;
|
||||||
|
|
||||||
|
if(hidden) $next.removeClass('visible').hide();
|
||||||
|
|
||||||
|
//If this isn't hidden and we have a tree with grouping, then turn on the group (parent) associated with this option.
|
||||||
|
if(!hidden && _this.options.groupFunctions) {
|
||||||
|
let parent = $next.data('parent-li');
|
||||||
|
|
||||||
|
if(!parent.hasClass('visible')) parent.addClass('visible').show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//If we hid all elements then hide the whole list.
|
||||||
|
if(this.$list.find('li.visible').length == 0) this.hide();
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Combo.prototype.focus = function() {
|
||||||
|
this.show();
|
||||||
|
this.$input.select();
|
||||||
|
};
|
||||||
|
|
||||||
|
Combo.prototype.blur = function() {
|
||||||
|
this.hide();
|
||||||
|
this.select(this.$list.find('li.selected'));
|
||||||
|
};
|
||||||
|
|
||||||
|
Combo.prototype.show = function() {
|
||||||
|
//Position the list relative to the edit field.
|
||||||
|
this.$list.css({position: 'absolute', top: 0, left: 0, width: this.$input.outerWidth()});
|
||||||
|
|
||||||
|
if(!this.$list.is(':visible') && this.$list.find('li.visible').length > 0) {
|
||||||
|
let fns = {default: 'show', fade: 'fadeIn', slide: 'slideDown'};
|
||||||
|
let fn = fns[this.options.effects];
|
||||||
|
|
||||||
|
this.trigger('show');
|
||||||
|
this.$input.addClass('open');
|
||||||
|
this.$list[fn](this.options.duration, $.proxy(this.trigger, this, 'shown'));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Combo.prototype.hide = function() {
|
||||||
|
let fns = {default: 'hide', fade: 'fadeOut', slide: 'slideUp'};
|
||||||
|
let fn = fns[this.options.effects];
|
||||||
|
|
||||||
|
this.trigger('hide');
|
||||||
|
this.$input.removeClass('open');
|
||||||
|
this.$list[fn](this.options.duration, $.proxy(this.trigger, this, 'hidden'));
|
||||||
|
};
|
||||||
|
|
||||||
|
// goDown: true/false - defaults to true - indicating whether the highlighting should go up or down if the requested item is a node. Nodes cannot be highlighted or selected.
|
||||||
|
Combo.prototype.highlight = function(index) {
|
||||||
|
let _this = this;
|
||||||
|
|
||||||
|
this.show();
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
let visibles = _this.$list.find('li.visible[role!="node"]');
|
||||||
|
let oldSelected = _this.$list.find('li.' + _this.options.selectionClass).removeClass(_this.options.selectionClass);
|
||||||
|
let oldSelectedIndex = visibles.index(oldSelected);
|
||||||
|
|
||||||
|
if(visibles.length > 0) {
|
||||||
|
let selectedIndex = (visibles.length + index) % visibles.length;
|
||||||
|
let selected = visibles.eq(selectedIndex);
|
||||||
|
let top = selected.position().top;
|
||||||
|
|
||||||
|
if(selected.attr('role') != 'node') selected.addClass(_this.options.selectionClass);
|
||||||
|
|
||||||
|
if(selectedIndex < oldSelectedIndex && top < 0)
|
||||||
|
_this.$list.scrollTop(_this.$list.scrollTop() + top);
|
||||||
|
if(selectedIndex > oldSelectedIndex && top + selected.outerHeight() > _this.$list.outerHeight())
|
||||||
|
_this.$list.scrollTop(_this.$list.scrollTop() + selected.outerHeight() + 2 * (top - _this.$list.outerHeight()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Combo.prototype.trigger = function(event) {
|
||||||
|
let params = Array.prototype.slice.call(arguments, 1);
|
||||||
|
let args = [event + '.de.combo'];
|
||||||
|
|
||||||
|
args.push(params);
|
||||||
|
|
||||||
|
if(this.$select) this.$select.trigger.apply(this.$select, args);
|
||||||
|
this.$input.trigger.apply(this.$input, args);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.fn.buildCombo = function(options) {
|
||||||
|
for(let index = 0; index < this.length; index++) {
|
||||||
|
let $next = $(this[index]);
|
||||||
|
let nextCombo = new Combo($next, $next.siblings('input[type=hidden]').first(), options);
|
||||||
|
|
||||||
|
$next.data("de.combo", nextCombo);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
$.fn.getCombo = function() {
|
||||||
|
if(this.length > 0) {
|
||||||
|
return $(this[0]).data('de.combo');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})(jQuery);
|
||||||
3
imports/util/regex.js
Normal file
3
imports/util/regex.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
RegExp.escape = function(s) {
|
||||||
|
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
|
||||||
|
};
|
||||||
515
imports/util/resize/ElementQueries.js
Normal file
515
imports/util/resize/ElementQueries.js
Normal file
@@ -0,0 +1,515 @@
|
|||||||
|
/**
|
||||||
|
* Copyright Marc J. Schmidt. See the LICENSE file at the top-level
|
||||||
|
* directory of this distribution and at
|
||||||
|
* https://github.com/marcj/css-element-queries/blob/master/LICENSE.
|
||||||
|
*/
|
||||||
|
;
|
||||||
|
(function (root, factory) {
|
||||||
|
if (typeof define === "function" && define.amd) {
|
||||||
|
define(['./ResizeSensor.js'], factory);
|
||||||
|
} else if (typeof exports === "object") {
|
||||||
|
module.exports = factory(require('./ResizeSensor.js'));
|
||||||
|
} else {
|
||||||
|
root.ElementQueries = factory(root.ResizeSensor);
|
||||||
|
}
|
||||||
|
}(this, function (ResizeSensor) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {Function}
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var ElementQueries = function() {
|
||||||
|
|
||||||
|
var trackingActive = false;
|
||||||
|
var elements = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param element
|
||||||
|
* @returns {Number}
|
||||||
|
*/
|
||||||
|
function getEmSize(element) {
|
||||||
|
if (!element) {
|
||||||
|
element = document.documentElement;
|
||||||
|
}
|
||||||
|
var fontSize = window.getComputedStyle(element, null).fontSize;
|
||||||
|
return parseFloat(fontSize) || 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @copyright https://github.com/Mr0grog/element-query/blob/master/LICENSE
|
||||||
|
*
|
||||||
|
* @param {HTMLElement} element
|
||||||
|
* @param {*} value
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
|
function convertToPx(element, value) {
|
||||||
|
var numbers = value.split(/\d/);
|
||||||
|
var units = numbers[numbers.length-1];
|
||||||
|
value = parseFloat(value);
|
||||||
|
switch (units) {
|
||||||
|
case "px":
|
||||||
|
return value;
|
||||||
|
case "em":
|
||||||
|
return value * getEmSize(element);
|
||||||
|
case "rem":
|
||||||
|
return value * getEmSize();
|
||||||
|
// Viewport units!
|
||||||
|
// According to http://quirksmode.org/mobile/tableViewport.html
|
||||||
|
// documentElement.clientWidth/Height gets us the most reliable info
|
||||||
|
case "vw":
|
||||||
|
return value * document.documentElement.clientWidth / 100;
|
||||||
|
case "vh":
|
||||||
|
return value * document.documentElement.clientHeight / 100;
|
||||||
|
case "vmin":
|
||||||
|
case "vmax":
|
||||||
|
var vw = document.documentElement.clientWidth / 100;
|
||||||
|
var vh = document.documentElement.clientHeight / 100;
|
||||||
|
var chooser = Math[units === "vmin" ? "min" : "max"];
|
||||||
|
return value * chooser(vw, vh);
|
||||||
|
default:
|
||||||
|
return value;
|
||||||
|
// for now, not supporting physical units (since they are just a set number of px)
|
||||||
|
// or ex/ch (getting accurate measurements is hard)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {HTMLElement} element
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
function SetupInformation(element) {
|
||||||
|
this.element = element;
|
||||||
|
this.options = {};
|
||||||
|
var key, option, width = 0, height = 0, value, actualValue, attrValues, attrValue, attrName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Object} option {mode: 'min|max', property: 'width|height', value: '123px'}
|
||||||
|
*/
|
||||||
|
this.addOption = function(option) {
|
||||||
|
var idx = [option.mode, option.property, option.value].join(',');
|
||||||
|
this.options[idx] = option;
|
||||||
|
};
|
||||||
|
|
||||||
|
var attributes = ['min-width', 'min-height', 'max-width', 'max-height'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts the computed width/height and sets to min/max- attribute.
|
||||||
|
*/
|
||||||
|
this.call = function() {
|
||||||
|
// extract current dimensions
|
||||||
|
width = this.element.offsetWidth;
|
||||||
|
height = this.element.offsetHeight;
|
||||||
|
|
||||||
|
attrValues = {};
|
||||||
|
|
||||||
|
for (key in this.options) {
|
||||||
|
if (!this.options.hasOwnProperty(key)){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
option = this.options[key];
|
||||||
|
|
||||||
|
value = convertToPx(this.element, option.value);
|
||||||
|
|
||||||
|
actualValue = option.property == 'width' ? width : height;
|
||||||
|
attrName = option.mode + '-' + option.property;
|
||||||
|
attrValue = '';
|
||||||
|
|
||||||
|
if (option.mode == 'min' && actualValue >= value) {
|
||||||
|
attrValue += option.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (option.mode == 'max' && actualValue <= value) {
|
||||||
|
attrValue += option.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!attrValues[attrName]) attrValues[attrName] = '';
|
||||||
|
if (attrValue && -1 === (' '+attrValues[attrName]+' ').indexOf(' ' + attrValue + ' ')) {
|
||||||
|
attrValues[attrName] += ' ' + attrValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var k in attributes) {
|
||||||
|
if(!attributes.hasOwnProperty(k)) continue;
|
||||||
|
|
||||||
|
if (attrValues[attributes[k]]) {
|
||||||
|
this.element.setAttribute(attributes[k], attrValues[attributes[k]].substr(1));
|
||||||
|
} else {
|
||||||
|
this.element.removeAttribute(attributes[k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {HTMLElement} element
|
||||||
|
* @param {Object} options
|
||||||
|
*/
|
||||||
|
function setupElement(element, options) {
|
||||||
|
if (element.elementQueriesSetupInformation) {
|
||||||
|
element.elementQueriesSetupInformation.addOption(options);
|
||||||
|
} else {
|
||||||
|
element.elementQueriesSetupInformation = new SetupInformation(element);
|
||||||
|
element.elementQueriesSetupInformation.addOption(options);
|
||||||
|
element.elementQueriesSensor = new ResizeSensor(element, function() {
|
||||||
|
element.elementQueriesSetupInformation.call();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
element.elementQueriesSetupInformation.call();
|
||||||
|
|
||||||
|
if (trackingActive && elements.indexOf(element) < 0) {
|
||||||
|
elements.push(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {String} selector
|
||||||
|
* @param {String} mode min|max
|
||||||
|
* @param {String} property width|height
|
||||||
|
* @param {String} value
|
||||||
|
*/
|
||||||
|
var allQueries = {};
|
||||||
|
function queueQuery(selector, mode, property, value) {
|
||||||
|
if (typeof(allQueries[mode]) == 'undefined') allQueries[mode] = {};
|
||||||
|
if (typeof(allQueries[mode][property]) == 'undefined') allQueries[mode][property] = {};
|
||||||
|
if (typeof(allQueries[mode][property][value]) == 'undefined') allQueries[mode][property][value] = selector;
|
||||||
|
else allQueries[mode][property][value] += ','+selector;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getQuery() {
|
||||||
|
var query;
|
||||||
|
if (document.querySelectorAll) query = document.querySelectorAll.bind(document);
|
||||||
|
if (!query && 'undefined' !== typeof $$) query = $$;
|
||||||
|
if (!query && 'undefined' !== typeof jQuery) query = jQuery;
|
||||||
|
|
||||||
|
if (!query) {
|
||||||
|
throw 'No document.querySelectorAll, jQuery or Mootools\'s $$ found.';
|
||||||
|
}
|
||||||
|
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the magic. Go through all collected rules (readRules()) and attach the resize-listener.
|
||||||
|
*/
|
||||||
|
function findElementQueriesElements() {
|
||||||
|
var query = getQuery();
|
||||||
|
|
||||||
|
for (var mode in allQueries) if (allQueries.hasOwnProperty(mode)) {
|
||||||
|
|
||||||
|
for (var property in allQueries[mode]) if (allQueries[mode].hasOwnProperty(property)) {
|
||||||
|
for (var value in allQueries[mode][property]) if (allQueries[mode][property].hasOwnProperty(value)) {
|
||||||
|
var elements = query(allQueries[mode][property][value]);
|
||||||
|
for (var i = 0, j = elements.length; i < j; i++) {
|
||||||
|
setupElement(elements[i], {
|
||||||
|
mode: mode,
|
||||||
|
property: property,
|
||||||
|
value: value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {HTMLElement} element
|
||||||
|
*/
|
||||||
|
function attachResponsiveImage(element) {
|
||||||
|
var children = [];
|
||||||
|
var rules = [];
|
||||||
|
var sources = [];
|
||||||
|
var defaultImageId = 0;
|
||||||
|
var lastActiveImage = -1;
|
||||||
|
var loadedImages = [];
|
||||||
|
|
||||||
|
for (var i in element.children) {
|
||||||
|
if(!element.children.hasOwnProperty(i)) continue;
|
||||||
|
|
||||||
|
if (element.children[i].tagName && element.children[i].tagName.toLowerCase() === 'img') {
|
||||||
|
children.push(element.children[i]);
|
||||||
|
|
||||||
|
var minWidth = element.children[i].getAttribute('min-width') || element.children[i].getAttribute('data-min-width');
|
||||||
|
//var minHeight = element.children[i].getAttribute('min-height') || element.children[i].getAttribute('data-min-height');
|
||||||
|
var src = element.children[i].getAttribute('data-src') || element.children[i].getAttribute('url');
|
||||||
|
|
||||||
|
sources.push(src);
|
||||||
|
|
||||||
|
var rule = {
|
||||||
|
minWidth: minWidth
|
||||||
|
};
|
||||||
|
|
||||||
|
rules.push(rule);
|
||||||
|
|
||||||
|
if (!minWidth) {
|
||||||
|
defaultImageId = children.length - 1;
|
||||||
|
element.children[i].style.display = 'block';
|
||||||
|
} else {
|
||||||
|
element.children[i].style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lastActiveImage = defaultImageId;
|
||||||
|
|
||||||
|
function check() {
|
||||||
|
var imageToDisplay = false, i;
|
||||||
|
|
||||||
|
for (i in children){
|
||||||
|
if(!children.hasOwnProperty(i)) continue;
|
||||||
|
|
||||||
|
if (rules[i].minWidth) {
|
||||||
|
if (element.offsetWidth > rules[i].minWidth) {
|
||||||
|
imageToDisplay = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!imageToDisplay) {
|
||||||
|
//no rule matched, show default
|
||||||
|
imageToDisplay = defaultImageId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastActiveImage != imageToDisplay) {
|
||||||
|
//image change
|
||||||
|
|
||||||
|
if (!loadedImages[imageToDisplay]){
|
||||||
|
//image has not been loaded yet, we need to load the image first in memory to prevent flash of
|
||||||
|
//no content
|
||||||
|
|
||||||
|
var image = new Image();
|
||||||
|
image.onload = function() {
|
||||||
|
children[imageToDisplay].src = sources[imageToDisplay];
|
||||||
|
|
||||||
|
children[lastActiveImage].style.display = 'none';
|
||||||
|
children[imageToDisplay].style.display = 'block';
|
||||||
|
|
||||||
|
loadedImages[imageToDisplay] = true;
|
||||||
|
|
||||||
|
lastActiveImage = imageToDisplay;
|
||||||
|
};
|
||||||
|
|
||||||
|
image.src = sources[imageToDisplay];
|
||||||
|
} else {
|
||||||
|
children[lastActiveImage].style.display = 'none';
|
||||||
|
children[imageToDisplay].style.display = 'block';
|
||||||
|
lastActiveImage = imageToDisplay;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//make sure for initial check call the .src is set correctly
|
||||||
|
children[imageToDisplay].src = sources[imageToDisplay];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
element.resizeSensor = new ResizeSensor(element, check);
|
||||||
|
check();
|
||||||
|
|
||||||
|
if (trackingActive) {
|
||||||
|
elements.push(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function findResponsiveImages(){
|
||||||
|
var query = getQuery();
|
||||||
|
|
||||||
|
var elements = query('[data-responsive-image],[responsive-image]');
|
||||||
|
for (var i = 0, j = elements.length; i < j; i++) {
|
||||||
|
attachResponsiveImage(elements[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var regex = /,?[\s\t]*([^,\n]*?)((?:\[[\s\t]*?(?:min|max)-(?:width|height)[\s\t]*?[~$\^]?=[\s\t]*?"[^"]*?"[\s\t]*?])+)([^,\n\s\{]*)/mgi;
|
||||||
|
var attrRegex = /\[[\s\t]*?(min|max)-(width|height)[\s\t]*?[~$\^]?=[\s\t]*?"([^"]*?)"[\s\t]*?]/mgi;
|
||||||
|
/**
|
||||||
|
* @param {String} css
|
||||||
|
*/
|
||||||
|
function extractQuery(css) {
|
||||||
|
var match;
|
||||||
|
var smatch;
|
||||||
|
css = css.replace(/'/g, '"');
|
||||||
|
while (null !== (match = regex.exec(css))) {
|
||||||
|
smatch = match[1] + match[3];
|
||||||
|
attrs = match[2];
|
||||||
|
|
||||||
|
while (null !== (attrMatch = attrRegex.exec(attrs))) {
|
||||||
|
queueQuery(smatch, attrMatch[1], attrMatch[2], attrMatch[3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {CssRule[]|String} rules
|
||||||
|
*/
|
||||||
|
function readRules(rules) {
|
||||||
|
var selector = '';
|
||||||
|
if (!rules) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ('string' === typeof rules) {
|
||||||
|
rules = rules.toLowerCase();
|
||||||
|
if (-1 !== rules.indexOf('min-width') || -1 !== rules.indexOf('max-width')) {
|
||||||
|
extractQuery(rules);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (var i = 0, j = rules.length; i < j; i++) {
|
||||||
|
if (1 === rules[i].type) {
|
||||||
|
selector = rules[i].selectorText || rules[i].cssText;
|
||||||
|
if (-1 !== selector.indexOf('min-height') || -1 !== selector.indexOf('max-height')) {
|
||||||
|
extractQuery(selector);
|
||||||
|
}else if(-1 !== selector.indexOf('min-width') || -1 !== selector.indexOf('max-width')) {
|
||||||
|
extractQuery(selector);
|
||||||
|
}
|
||||||
|
} else if (4 === rules[i].type) {
|
||||||
|
readRules(rules[i].cssRules || rules[i].rules);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultCssInjected = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches all css rules and setups the event listener to all elements with element query rules..
|
||||||
|
*
|
||||||
|
* @param {Boolean} withTracking allows and requires you to use detach, since we store internally all used elements
|
||||||
|
* (no garbage collection possible if you don not call .detach() first)
|
||||||
|
*/
|
||||||
|
this.init = function(withTracking) {
|
||||||
|
trackingActive = typeof withTracking === 'undefined' ? false : withTracking;
|
||||||
|
|
||||||
|
for (var i = 0, j = document.styleSheets.length; i < j; i++) {
|
||||||
|
try {
|
||||||
|
readRules(document.styleSheets[i].cssRules || document.styleSheets[i].rules || document.styleSheets[i].cssText);
|
||||||
|
} catch(e) {
|
||||||
|
if (e.name !== 'SecurityError') {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!defaultCssInjected) {
|
||||||
|
var style = document.createElement('style');
|
||||||
|
style.type = 'text/css';
|
||||||
|
style.innerHTML = '[responsive-image] > img, [data-responsive-image] {overflow: hidden; padding: 0; } [responsive-image] > img, [data-responsive-image] > img { width: 100%;}';
|
||||||
|
document.getElementsByTagName('head')[0].appendChild(style);
|
||||||
|
defaultCssInjected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
findElementQueriesElements();
|
||||||
|
findResponsiveImages();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Boolean} withTracking allows and requires you to use detach, since we store internally all used elements
|
||||||
|
* (no garbage collection possible if you don not call .detach() first)
|
||||||
|
*/
|
||||||
|
this.update = function(withTracking) {
|
||||||
|
this.init(withTracking);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.detach = function() {
|
||||||
|
if (!this.withTracking) {
|
||||||
|
throw 'withTracking is not enabled. We can not detach elements since we don not store it.' +
|
||||||
|
'Use ElementQueries.withTracking = true; before domready or call ElementQueryes.update(true).';
|
||||||
|
}
|
||||||
|
|
||||||
|
var element;
|
||||||
|
while (element = elements.pop()) {
|
||||||
|
ElementQueries.detach(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
elements = [];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Boolean} withTracking allows and requires you to use detach, since we store internally all used elements
|
||||||
|
* (no garbage collection possible if you don not call .detach() first)
|
||||||
|
*/
|
||||||
|
ElementQueries.update = function(withTracking) {
|
||||||
|
ElementQueries.instance.update(withTracking);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all sensor and elementquery information from the element.
|
||||||
|
*
|
||||||
|
* @param {HTMLElement} element
|
||||||
|
*/
|
||||||
|
ElementQueries.detach = function(element) {
|
||||||
|
if (element.elementQueriesSetupInformation) {
|
||||||
|
//element queries
|
||||||
|
element.elementQueriesSensor.detach();
|
||||||
|
delete element.elementQueriesSetupInformation;
|
||||||
|
delete element.elementQueriesSensor;
|
||||||
|
|
||||||
|
} else if (element.resizeSensor) {
|
||||||
|
//responsive image
|
||||||
|
|
||||||
|
element.resizeSensor.detach();
|
||||||
|
delete element.resizeSensor;
|
||||||
|
} else {
|
||||||
|
//console.log('detached already', element);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ElementQueries.withTracking = false;
|
||||||
|
|
||||||
|
ElementQueries.init = function() {
|
||||||
|
if (!ElementQueries.instance) {
|
||||||
|
ElementQueries.instance = new ElementQueries();
|
||||||
|
}
|
||||||
|
|
||||||
|
ElementQueries.instance.init(ElementQueries.withTracking);
|
||||||
|
};
|
||||||
|
|
||||||
|
var domLoaded = function (callback) {
|
||||||
|
/* Internet Explorer */
|
||||||
|
/*@cc_on
|
||||||
|
@if (@_win32 || @_win64)
|
||||||
|
document.write('<script id="ieScriptLoad" defer src="//:"><\/script>');
|
||||||
|
document.getElementById('ieScriptLoad').onreadystatechange = function() {
|
||||||
|
if (this.readyState == 'complete') {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@end @*/
|
||||||
|
/* Mozilla, Chrome, Opera */
|
||||||
|
if (document.addEventListener) {
|
||||||
|
document.addEventListener('DOMContentLoaded', callback, false);
|
||||||
|
}
|
||||||
|
/* Safari, iCab, Konqueror */
|
||||||
|
else if (/KHTML|WebKit|iCab/i.test(navigator.userAgent)) {
|
||||||
|
var DOMLoadTimer = setInterval(function () {
|
||||||
|
if (/loaded|complete/i.test(document.readyState)) {
|
||||||
|
callback();
|
||||||
|
clearInterval(DOMLoadTimer);
|
||||||
|
}
|
||||||
|
}, 10);
|
||||||
|
}
|
||||||
|
/* Other web browsers */
|
||||||
|
else window.onload = callback;
|
||||||
|
};
|
||||||
|
|
||||||
|
ElementQueries.listen = function() {
|
||||||
|
domLoaded(ElementQueries.init);
|
||||||
|
};
|
||||||
|
|
||||||
|
// make available to common module loader
|
||||||
|
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
|
||||||
|
module.exports = ElementQueries;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
window.ElementQueries = ElementQueries;
|
||||||
|
ElementQueries.listen();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ElementQueries;
|
||||||
|
|
||||||
|
}));
|
||||||
227
imports/util/resize/ResizeSensor.js
Normal file
227
imports/util/resize/ResizeSensor.js
Normal file
@@ -0,0 +1,227 @@
|
|||||||
|
/**
|
||||||
|
* Copyright Marc J. Schmidt. See the LICENSE file at the top-level
|
||||||
|
* directory of this distribution and at
|
||||||
|
* https://github.com/marcj/css-element-queries/blob/master/LICENSE.
|
||||||
|
*/
|
||||||
|
;
|
||||||
|
(function (root, factory) {
|
||||||
|
if (typeof define === "function" && define.amd) {
|
||||||
|
define(factory);
|
||||||
|
} else if (typeof exports === "object") {
|
||||||
|
module.exports = factory();
|
||||||
|
} else {
|
||||||
|
root.ResizeSensor = factory();
|
||||||
|
}
|
||||||
|
}(this, function () {
|
||||||
|
|
||||||
|
//Make sure it does not throw in a SSR (Server Side Rendering) situation
|
||||||
|
if (typeof window === "undefined") {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// Only used for the dirty checking, so the event callback count is limted to max 1 call per fps per sensor.
|
||||||
|
// In combination with the event based resize sensor this saves cpu time, because the sensor is too fast and
|
||||||
|
// would generate too many unnecessary events.
|
||||||
|
var requestAnimationFrame = window.requestAnimationFrame ||
|
||||||
|
window.mozRequestAnimationFrame ||
|
||||||
|
window.webkitRequestAnimationFrame ||
|
||||||
|
function (fn) {
|
||||||
|
return window.setTimeout(fn, 20);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterate over each of the provided element(s).
|
||||||
|
*
|
||||||
|
* @param {HTMLElement|HTMLElement[]} elements
|
||||||
|
* @param {Function} callback
|
||||||
|
*/
|
||||||
|
function forEachElement(elements, callback){
|
||||||
|
var elementsType = Object.prototype.toString.call(elements);
|
||||||
|
var isCollectionTyped = ('[object Array]' === elementsType
|
||||||
|
|| ('[object NodeList]' === elementsType)
|
||||||
|
|| ('[object HTMLCollection]' === elementsType)
|
||||||
|
|| ('[object Object]' === elementsType)
|
||||||
|
|| ('undefined' !== typeof jQuery && elements instanceof jQuery) //jquery
|
||||||
|
|| ('undefined' !== typeof Elements && elements instanceof Elements) //mootools
|
||||||
|
);
|
||||||
|
var i = 0, j = elements.length;
|
||||||
|
if (isCollectionTyped) {
|
||||||
|
for (; i < j; i++) {
|
||||||
|
callback(elements[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback(elements);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for dimension change detection.
|
||||||
|
*
|
||||||
|
* @param {Element|Element[]|Elements|jQuery} element
|
||||||
|
* @param {Function} callback
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var ResizeSensor = function(element, callback) {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
function EventQueue() {
|
||||||
|
var q = [];
|
||||||
|
this.add = function(ev) {
|
||||||
|
q.push(ev);
|
||||||
|
};
|
||||||
|
|
||||||
|
var i, j;
|
||||||
|
this.call = function() {
|
||||||
|
for (i = 0, j = q.length; i < j; i++) {
|
||||||
|
q[i].call();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.remove = function(ev) {
|
||||||
|
var newQueue = [];
|
||||||
|
for(i = 0, j = q.length; i < j; i++) {
|
||||||
|
if(q[i] !== ev) newQueue.push(q[i]);
|
||||||
|
}
|
||||||
|
q = newQueue;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.length = function() {
|
||||||
|
return q.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {HTMLElement} element
|
||||||
|
* @param {String} prop
|
||||||
|
* @returns {String|Number}
|
||||||
|
*/
|
||||||
|
function getComputedStyle(element, prop) {
|
||||||
|
if (element.currentStyle) {
|
||||||
|
return element.currentStyle[prop];
|
||||||
|
} else if (window.getComputedStyle) {
|
||||||
|
return window.getComputedStyle(element, null).getPropertyValue(prop);
|
||||||
|
} else {
|
||||||
|
return element.style[prop];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {HTMLElement} element
|
||||||
|
* @param {Function} resized
|
||||||
|
*/
|
||||||
|
function attachResizeEvent(element, resized) {
|
||||||
|
if (!element.resizedAttached) {
|
||||||
|
element.resizedAttached = new EventQueue();
|
||||||
|
element.resizedAttached.add(resized);
|
||||||
|
} else if (element.resizedAttached) {
|
||||||
|
element.resizedAttached.add(resized);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
element.resizeSensor = document.createElement('div');
|
||||||
|
element.resizeSensor.className = 'resize-sensor';
|
||||||
|
var style = 'position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: hidden; z-index: -1; visibility: hidden;';
|
||||||
|
var styleChild = 'position: absolute; left: 0; top: 0; transition: 0s;';
|
||||||
|
|
||||||
|
element.resizeSensor.style.cssText = style;
|
||||||
|
element.resizeSensor.innerHTML =
|
||||||
|
'<div class="resize-sensor-expand" style="' + style + '">' +
|
||||||
|
'<div style="' + styleChild + '"></div>' +
|
||||||
|
'</div>' +
|
||||||
|
'<div class="resize-sensor-shrink" style="' + style + '">' +
|
||||||
|
'<div style="' + styleChild + ' width: 200%; height: 200%"></div>' +
|
||||||
|
'</div>';
|
||||||
|
element.appendChild(element.resizeSensor);
|
||||||
|
|
||||||
|
if (getComputedStyle(element, 'position') == 'static') {
|
||||||
|
element.style.position = 'relative';
|
||||||
|
}
|
||||||
|
|
||||||
|
var expand = element.resizeSensor.childNodes[0];
|
||||||
|
var expandChild = expand.childNodes[0];
|
||||||
|
var shrink = element.resizeSensor.childNodes[1];
|
||||||
|
var dirty, rafId, newWidth, newHeight;
|
||||||
|
var lastWidth = element.offsetWidth;
|
||||||
|
var lastHeight = element.offsetHeight;
|
||||||
|
|
||||||
|
var reset = function() {
|
||||||
|
expandChild.style.width = '100000px';
|
||||||
|
expandChild.style.height = '100000px';
|
||||||
|
|
||||||
|
expand.scrollLeft = 100000;
|
||||||
|
expand.scrollTop = 100000;
|
||||||
|
|
||||||
|
shrink.scrollLeft = 100000;
|
||||||
|
shrink.scrollTop = 100000;
|
||||||
|
};
|
||||||
|
|
||||||
|
reset();
|
||||||
|
|
||||||
|
var onResized = function() {
|
||||||
|
rafId = 0;
|
||||||
|
|
||||||
|
if (!dirty) return;
|
||||||
|
|
||||||
|
lastWidth = newWidth;
|
||||||
|
lastHeight = newHeight;
|
||||||
|
|
||||||
|
if (element.resizedAttached) {
|
||||||
|
element.resizedAttached.call();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var onScroll = function() {
|
||||||
|
newWidth = element.offsetWidth;
|
||||||
|
newHeight = element.offsetHeight;
|
||||||
|
dirty = newWidth != lastWidth || newHeight != lastHeight;
|
||||||
|
|
||||||
|
if (dirty && !rafId) {
|
||||||
|
rafId = requestAnimationFrame(onResized);
|
||||||
|
}
|
||||||
|
|
||||||
|
reset();
|
||||||
|
};
|
||||||
|
|
||||||
|
var addEvent = function(el, name, cb) {
|
||||||
|
if (el.attachEvent) {
|
||||||
|
el.attachEvent('on' + name, cb);
|
||||||
|
} else {
|
||||||
|
el.addEventListener(name, cb);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
addEvent(expand, 'scroll', onScroll);
|
||||||
|
addEvent(shrink, 'scroll', onScroll);
|
||||||
|
}
|
||||||
|
|
||||||
|
forEachElement(element, function(elem){
|
||||||
|
attachResizeEvent(elem, callback);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.detach = function(ev) {
|
||||||
|
ResizeSensor.detach(element, ev);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
ResizeSensor.detach = function(element, ev) {
|
||||||
|
forEachElement(element, function(elem){
|
||||||
|
if(elem.resizedAttached && typeof ev == "function"){
|
||||||
|
elem.resizedAttached.remove(ev);
|
||||||
|
if(elem.resizedAttached.length()) return;
|
||||||
|
}
|
||||||
|
if (elem.resizeSensor) {
|
||||||
|
if (elem.contains(elem.resizeSensor)) {
|
||||||
|
elem.removeChild(elem.resizeSensor);
|
||||||
|
}
|
||||||
|
delete elem.resizeSensor;
|
||||||
|
delete elem.resizedAttached;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return ResizeSensor;
|
||||||
|
|
||||||
|
}));
|
||||||
314
imports/util/selectize/selectize.default.import.styl
vendored
Normal file
314
imports/util/selectize/selectize.default.import.styl
vendored
Normal file
@@ -0,0 +1,314 @@
|
|||||||
|
/**
|
||||||
|
* selectize.default.css (v0.12.0) - Default Theme
|
||||||
|
* Copyright (c) 2013–2015 Brian Reavis & contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
|
||||||
|
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||||
|
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||||
|
* ANY KIND, either express or implied. See the License for the specific language
|
||||||
|
* governing permissions and limitations under the License.
|
||||||
|
*
|
||||||
|
* @author Brian Reavis <brian@thirdroute.com>
|
||||||
|
*/
|
||||||
|
.selectize-control.plugin-drag_drop.multi > .selectize-input > div.ui-sortable-placeholder
|
||||||
|
visibility visible !important
|
||||||
|
background #f2f2f2 !important
|
||||||
|
background rgba(0, 0, 0, 0.06) !important
|
||||||
|
border 0 none !important
|
||||||
|
-webkit-box-shadow inset 0 0 12px 4px #ffffff
|
||||||
|
box-shadow inset 0 0 12px 4px #ffffff
|
||||||
|
.selectize-control.plugin-drag_drop .ui-sortable-placeholder::after
|
||||||
|
content '!'
|
||||||
|
visibility hidden
|
||||||
|
.selectize-control.plugin-drag_drop .ui-sortable-helper
|
||||||
|
-webkit-box-shadow 0 2px 5px rgba(0, 0, 0, 0.2)
|
||||||
|
box-shadow 0 2px 5px rgba(0, 0, 0, 0.2)
|
||||||
|
.selectize-dropdown-header
|
||||||
|
position relative
|
||||||
|
padding 5px 8px
|
||||||
|
border-bottom 1px solid #d0d0d0
|
||||||
|
background #f8f8f8
|
||||||
|
-webkit-border-radius 3px 3px 0 0
|
||||||
|
-moz-border-radius 3px 3px 0 0
|
||||||
|
border-radius 3px 3px 0 0
|
||||||
|
.selectize-dropdown-header-close
|
||||||
|
position absolute
|
||||||
|
right 8px
|
||||||
|
top 50%
|
||||||
|
color #303030
|
||||||
|
opacity 0.4
|
||||||
|
margin-top -12px
|
||||||
|
line-height 20px
|
||||||
|
font-size 20px !important
|
||||||
|
.selectize-dropdown-header-close:hover
|
||||||
|
color #000000
|
||||||
|
.selectize-dropdown.plugin-optgroup_columns .optgroup
|
||||||
|
border-right 1px solid #f2f2f2
|
||||||
|
border-top 0 none
|
||||||
|
float left
|
||||||
|
-webkit-box-sizing border-box
|
||||||
|
-moz-box-sizing border-box
|
||||||
|
box-sizing border-box
|
||||||
|
.selectize-dropdown.plugin-optgroup_columns .optgroup:last-child
|
||||||
|
border-right 0 none
|
||||||
|
.selectize-dropdown.plugin-optgroup_columns .optgroup:before
|
||||||
|
display none
|
||||||
|
.selectize-dropdown.plugin-optgroup_columns .optgroup-header
|
||||||
|
border-top 0 none
|
||||||
|
.selectize-control.plugin-remove_button [data-value]
|
||||||
|
position relative
|
||||||
|
padding-right 24px !important
|
||||||
|
.selectize-control.plugin-remove_button [data-value] .remove
|
||||||
|
z-index 1
|
||||||
|
/* fixes ie bug (see #392) */
|
||||||
|
position absolute
|
||||||
|
top 0
|
||||||
|
right 0
|
||||||
|
bottom 0
|
||||||
|
width 17px
|
||||||
|
text-align center
|
||||||
|
font-weight bold
|
||||||
|
font-size 12px
|
||||||
|
color inherit
|
||||||
|
text-decoration none
|
||||||
|
vertical-align middle
|
||||||
|
display inline-block
|
||||||
|
padding 2px 0 0 0
|
||||||
|
border-left 1px solid #0073bb
|
||||||
|
-webkit-border-radius 0 2px 2px 0
|
||||||
|
-moz-border-radius 0 2px 2px 0
|
||||||
|
border-radius 0 2px 2px 0
|
||||||
|
-webkit-box-sizing border-box
|
||||||
|
-moz-box-sizing border-box
|
||||||
|
box-sizing border-box
|
||||||
|
.selectize-control.plugin-remove_button [data-value] .remove:hover
|
||||||
|
background rgba(0, 0, 0, 0.05)
|
||||||
|
.selectize-control.plugin-remove_button [data-value].active .remove
|
||||||
|
border-left-color #00578d
|
||||||
|
.selectize-control.plugin-remove_button .disabled [data-value] .remove:hover
|
||||||
|
background none
|
||||||
|
.selectize-control.plugin-remove_button .disabled [data-value] .remove
|
||||||
|
border-left-color #aaaaaa
|
||||||
|
.selectize-control
|
||||||
|
position relative
|
||||||
|
.selectize-dropdown, .selectize-input, .selectize-input input
|
||||||
|
color #303030
|
||||||
|
font-family inherit
|
||||||
|
font-size 13px
|
||||||
|
line-height 18px
|
||||||
|
-webkit-font-smoothing inherit
|
||||||
|
.selectize-input, .selectize-control.single .selectize-input.input-active
|
||||||
|
background #ffffff
|
||||||
|
cursor text
|
||||||
|
display inline-block
|
||||||
|
.selectize-input
|
||||||
|
border 1px solid #d0d0d0
|
||||||
|
padding 8px 8px
|
||||||
|
display inline-block
|
||||||
|
width 100%
|
||||||
|
overflow hidden
|
||||||
|
position relative
|
||||||
|
z-index 1
|
||||||
|
-webkit-box-sizing border-box
|
||||||
|
-moz-box-sizing border-box
|
||||||
|
box-sizing border-box
|
||||||
|
-webkit-box-shadow inset 0 1px 1px rgba(0, 0, 0, 0.1)
|
||||||
|
box-shadow inset 0 1px 1px rgba(0, 0, 0, 0.1)
|
||||||
|
-webkit-border-radius 3px
|
||||||
|
-moz-border-radius 3px
|
||||||
|
border-radius 3px
|
||||||
|
.selectize-control.multi .selectize-input.has-items
|
||||||
|
padding 5px 8px 2px
|
||||||
|
.selectize-input.full
|
||||||
|
background-color #ffffff
|
||||||
|
.selectize-input.disabled, .selectize-input.disabled *
|
||||||
|
cursor default !important
|
||||||
|
.selectize-input.focus
|
||||||
|
-webkit-box-shadow inset 0 1px 2px rgba(0, 0, 0, 0.15)
|
||||||
|
box-shadow inset 0 1px 2px rgba(0, 0, 0, 0.15)
|
||||||
|
.selectize-input.dropdown-active
|
||||||
|
-webkit-border-radius 3px 3px 0 0
|
||||||
|
-moz-border-radius 3px 3px 0 0
|
||||||
|
border-radius 3px 3px 0 0
|
||||||
|
.selectize-input > *
|
||||||
|
vertical-align baseline
|
||||||
|
display -moz-inline-stack
|
||||||
|
display inline-block
|
||||||
|
zoom 1
|
||||||
|
*display inline .selectize-control.multi .selectize-input > div
|
||||||
|
cursor pointer
|
||||||
|
margin 0 3px 3px 0
|
||||||
|
padding 2px 6px
|
||||||
|
background #1da7ee
|
||||||
|
color #ffffff
|
||||||
|
border 1px solid #0073bb
|
||||||
|
.selectize-control.multi .selectize-input > div.active
|
||||||
|
background #92c836
|
||||||
|
color #ffffff
|
||||||
|
border 1px solid #00578d
|
||||||
|
.selectize-control.multi .selectize-input.disabled > div, .selectize-control.multi .selectize-input.disabled > div.active
|
||||||
|
color #ffffff
|
||||||
|
background #d2d2d2
|
||||||
|
border 1px solid #aaaaaa
|
||||||
|
.selectize-input > input
|
||||||
|
display inline-block !important
|
||||||
|
padding 0 !important
|
||||||
|
min-height 0 !important
|
||||||
|
max-height none !important
|
||||||
|
max-width 100% !important
|
||||||
|
margin 0 1px !important
|
||||||
|
text-indent 0 !important
|
||||||
|
border 0 none !important
|
||||||
|
background none !important
|
||||||
|
line-height inherit !important
|
||||||
|
-webkit-user-select auto !important
|
||||||
|
-webkit-box-shadow none !important
|
||||||
|
box-shadow none !important
|
||||||
|
.selectize-input > input::-ms-clear
|
||||||
|
display none
|
||||||
|
.selectize-input > input:focus
|
||||||
|
outline none !important
|
||||||
|
.selectize-input::after
|
||||||
|
content ' '
|
||||||
|
display block
|
||||||
|
clear left
|
||||||
|
.selectize-input.dropdown-active::before
|
||||||
|
content ' '
|
||||||
|
display block
|
||||||
|
position absolute
|
||||||
|
background #f0f0f0
|
||||||
|
height 1px
|
||||||
|
bottom 0
|
||||||
|
left 0
|
||||||
|
right 0
|
||||||
|
.selectize-dropdown
|
||||||
|
position absolute
|
||||||
|
z-index 10
|
||||||
|
border 1px solid #d0d0d0
|
||||||
|
background #ffffff
|
||||||
|
margin -1px 0 0 0
|
||||||
|
border-top 0 none
|
||||||
|
-webkit-box-sizing border-box
|
||||||
|
-moz-box-sizing border-box
|
||||||
|
box-sizing border-box
|
||||||
|
-webkit-box-shadow 0 1px 3px rgba(0, 0, 0, 0.1)
|
||||||
|
box-shadow 0 1px 3px rgba(0, 0, 0, 0.1)
|
||||||
|
-webkit-border-radius 0 0 3px 3px
|
||||||
|
-moz-border-radius 0 0 3px 3px
|
||||||
|
border-radius 0 0 3px 3px
|
||||||
|
.selectize-dropdown [data-selectable]
|
||||||
|
cursor pointer
|
||||||
|
overflow hidden
|
||||||
|
.selectize-dropdown [data-selectable] .highlight
|
||||||
|
background rgba(125, 168, 208, 0.2)
|
||||||
|
-webkit-border-radius 1px
|
||||||
|
-moz-border-radius 1px
|
||||||
|
border-radius 1px
|
||||||
|
.selectize-dropdown [data-selectable], .selectize-dropdown .optgroup-header
|
||||||
|
padding 5px 8px
|
||||||
|
.selectize-dropdown .optgroup:first-child .optgroup-header
|
||||||
|
border-top 0 none
|
||||||
|
.selectize-dropdown .optgroup-header
|
||||||
|
color #303030
|
||||||
|
background #ffffff
|
||||||
|
cursor default
|
||||||
|
.selectize-dropdown .active
|
||||||
|
background-color #f5fafd
|
||||||
|
color #495c68
|
||||||
|
.selectize-dropdown .active.create
|
||||||
|
color #495c68
|
||||||
|
.selectize-dropdown .create
|
||||||
|
color rgba(48, 48, 48, 0.5)
|
||||||
|
.selectize-dropdown-content
|
||||||
|
overflow-y auto
|
||||||
|
overflow-x hidden
|
||||||
|
max-height 200px
|
||||||
|
.selectize-control.single .selectize-input, .selectize-control.single .selectize-input input
|
||||||
|
cursor pointer
|
||||||
|
.selectize-control.single .selectize-input.input-active, .selectize-control.single .selectize-input.input-active input
|
||||||
|
cursor text
|
||||||
|
.selectize-control.single .selectize-input:after
|
||||||
|
content ' '
|
||||||
|
display block
|
||||||
|
position absolute
|
||||||
|
top 50%
|
||||||
|
right 15px
|
||||||
|
margin-top -3px
|
||||||
|
width 0
|
||||||
|
height 0
|
||||||
|
border-style solid
|
||||||
|
border-width 5px 5px 0 5px
|
||||||
|
border-color #808080 transparent transparent transparent
|
||||||
|
.selectize-control.single .selectize-input.dropdown-active:after
|
||||||
|
margin-top -4px
|
||||||
|
border-width 0 5px 5px 5px
|
||||||
|
border-color transparent transparent #808080 transparent
|
||||||
|
.selectize-control.rtl.single .selectize-input:after
|
||||||
|
left 15px
|
||||||
|
right auto
|
||||||
|
.selectize-control.rtl .selectize-input > input
|
||||||
|
margin 0 4px 0 -2px !important
|
||||||
|
.selectize-control .selectize-input.disabled
|
||||||
|
opacity 0.5
|
||||||
|
background-color #fafafa
|
||||||
|
.selectize-control.multi .selectize-input.has-items
|
||||||
|
padding-left 5px
|
||||||
|
padding-right 5px
|
||||||
|
.selectize-control.multi .selectize-input.disabled [data-value]
|
||||||
|
color #999
|
||||||
|
text-shadow none
|
||||||
|
background none
|
||||||
|
-webkit-box-shadow none
|
||||||
|
box-shadow none
|
||||||
|
.selectize-control.multi .selectize-input.disabled [data-value], .selectize-control.multi .selectize-input.disabled [data-value] .remove
|
||||||
|
border-color #e6e6e6
|
||||||
|
.selectize-control.multi .selectize-input.disabled [data-value] .remove
|
||||||
|
background none
|
||||||
|
.selectize-control.multi .selectize-input [data-value]
|
||||||
|
text-shadow 0 1px 0 rgba(0, 51, 83, 0.3)
|
||||||
|
-webkit-border-radius 3px
|
||||||
|
-moz-border-radius 3px
|
||||||
|
border-radius 3px
|
||||||
|
background-color #1b9dec
|
||||||
|
background-image -moz-linear-gradient(top, rgb(29, 167, 238, 1), rgb(23, 142, 233, 1))
|
||||||
|
background-image -webkit-gradient(linear, 0 0, 0 100%, from(rgb(29, 167, 238, 1)), to(rgb(23, 142, 233, 1)))
|
||||||
|
background-image -webkit-linear-gradient(top, rgb(29, 167, 238, 1), rgb(23, 142, 233, 1))
|
||||||
|
background-image -o-linear-gradient(top, rgb(29, 167, 238, 1), rgb(23, 142, 233, 1))
|
||||||
|
background-image linear-gradient(to bottom, rgb(29, 167, 238, 1), rgb(23, 142, 233, 1))
|
||||||
|
background-repeat repeat-x
|
||||||
|
filter unquote("progid:DXImageTransform.Microsoft.gradient('#ff1da7ee', '#ff178ee9', 0)")
|
||||||
|
-webkit-box-shadow 0 1px 0 rgba(0, 0, 0, 0.2), inset 0 1px rgba(255, 255, 255, 0.03)
|
||||||
|
box-shadow 0 1px 0 rgba(0, 0, 0, 0.2), inset 0 1px rgba(255, 255, 255, 0.03)
|
||||||
|
.selectize-control.multi .selectize-input [data-value].active
|
||||||
|
background-color #0085d4
|
||||||
|
background-image -moz-linear-gradient(top, rgb(0, 143, 216, 1), rgb(0, 117, 207, 1))
|
||||||
|
background-image -webkit-gradient(linear, 0 0, 0 100%, from(rgb(0, 143, 216, 1)), to(rgb(0, 117, 207, 1)))
|
||||||
|
background-image -webkit-linear-gradient(top, rgb(0, 143, 216, 1), rgb(0, 117, 207, 1))
|
||||||
|
background-image -o-linear-gradient(top, rgb(0, 143, 216, 1), rgb(0, 117, 207, 1))
|
||||||
|
background-image linear-gradient(to bottom, rgb(0, 143, 216, 1), rgb(0, 117, 207, 1))
|
||||||
|
background-repeat repeat-x
|
||||||
|
filter unquote("progid:DXImageTransform.Microsoft.gradient('#ff008fd8', '#ff0075cf', 0)")
|
||||||
|
.selectize-control.single .selectize-input
|
||||||
|
-webkit-box-shadow 0 1px 0 rgba(0, 0, 0, 0.05), inset 0 1px 0 rgba(255, 255, 255, 0.8)
|
||||||
|
box-shadow 0 1px 0 rgba(0, 0, 0, 0.05), inset 0 1px 0 rgba(255, 255, 255, 0.8)
|
||||||
|
background-color #f9f9f9
|
||||||
|
background-image -moz-linear-gradient(top, rgb(254, 254, 254, 1), rgb(242, 242, 242, 1))
|
||||||
|
background-image -webkit-gradient(linear, 0 0, 0 100%, from(rgb(254, 254, 254, 1)), to(rgb(242, 242, 242, 1)))
|
||||||
|
background-image -webkit-linear-gradient(top, rgb(254, 254, 254, 1), rgb(242, 242, 242, 1))
|
||||||
|
background-image -o-linear-gradient(top, rgb(254, 254, 254, 1), rgb(242, 242, 242, 1))
|
||||||
|
background-image linear-gradient(to bottom, rgb(254, 254, 254, 1), rgb(242, 242, 242, 1))
|
||||||
|
background-repeat repeat-x
|
||||||
|
filter unquote("progid:DXImageTransform.Microsoft.gradient('#fffefefe', '#fff2f2f2', 0)")
|
||||||
|
.selectize-control.single .selectize-input, .selectize-dropdown.single
|
||||||
|
border-color #b8b8b8
|
||||||
|
.selectize-dropdown .optgroup-header
|
||||||
|
padding-top 7px
|
||||||
|
font-weight bold
|
||||||
|
font-size 0.85em
|
||||||
|
.selectize-dropdown .optgroup
|
||||||
|
border-top 1px solid #f0f0f0
|
||||||
|
.selectize-dropdown .optgroup:first-child
|
||||||
|
border-top 0 none
|
||||||
57
imports/util/selectize/selectize.html
Normal file
57
imports/util/selectize/selectize.html
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
<template name="Selectize">
|
||||||
|
<div class="selectize-control selectize {{#if multiple}}multi{{else}}single{{/if}} {{#if removeButton}}plugin-remove_button{{/if}} {{#if loading}}loading{{/if}}">
|
||||||
|
<select name={{name}} multiple={{multiple}} id={{id}} data-schema-key={{dataSchemaKey}}>
|
||||||
|
<option value=""></option>
|
||||||
|
{{#each getItems}}
|
||||||
|
<option value={{value}} selected={{selected}}>{{label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<div class="selectize-input items not-full has-options has-items {{#if disabled}}disabled{{/if}} {{#if open}}focus input-active dropdown-active{{/if}}">
|
||||||
|
{{#if getPlaceholder}}
|
||||||
|
<div class="selectize-placeholder {{#if open}}hidden{{/if}}">
|
||||||
|
{{getPlaceholder}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if inputPosition -1}}
|
||||||
|
<input type="text" autocomplete="off" tabindex="" class="js-selectizeInput">
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#each getItemsSelected}}
|
||||||
|
<div data-value={{value}} class="item">
|
||||||
|
{{label}}
|
||||||
|
{{#if removeButton}}
|
||||||
|
<a href="#" class="remove" tabindex="-1" title="Remove">×</a>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{#if inputPosition @index}}
|
||||||
|
<input type="text" autocomplete="off" tabindex="" class="js-selectizeInput">
|
||||||
|
{{/if}}
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="selectize-dropdown js-selectize-dropdown {{#unless open}}hidden{{/unless}}">
|
||||||
|
<div class="selectize-dropdown-content">
|
||||||
|
{{#each getItemsUnselected}}
|
||||||
|
<div data-value={{value}} data-index={{@index}} data-selectable class="option {{#if activeOption @index}}active{{/if}} {{isPlaceholder}}">
|
||||||
|
{{label}}
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
{{#if create}}
|
||||||
|
{{#if getSearchText}}
|
||||||
|
<div data-selectable="" data-index='create' class="create {{#if activeOption 'create'}}active{{/if}}">
|
||||||
|
{{#if createText}}
|
||||||
|
{{{createText}}}
|
||||||
|
{{else}}
|
||||||
|
Add
|
||||||
|
{{/if}}
|
||||||
|
<strong>{{getSearchText}}</strong>…
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
38
imports/util/selectize/selectize.import.styl
vendored
Normal file
38
imports/util/selectize/selectize.import.styl
vendored
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
|
||||||
|
.selectize.selectize-control
|
||||||
|
position relative
|
||||||
|
.hidden
|
||||||
|
display none
|
||||||
|
select
|
||||||
|
display none
|
||||||
|
.selectize-input
|
||||||
|
input
|
||||||
|
width 4px
|
||||||
|
opacity 1
|
||||||
|
position relative
|
||||||
|
left 0px
|
||||||
|
div.selectize-placeholder
|
||||||
|
color #bbb
|
||||||
|
background none
|
||||||
|
border none
|
||||||
|
&.input-active
|
||||||
|
div.selectize-placeholder
|
||||||
|
display none
|
||||||
|
.selectize-dropdown
|
||||||
|
width 100% !important
|
||||||
|
top 36px
|
||||||
|
&.loading:after
|
||||||
|
content ""
|
||||||
|
width 16px
|
||||||
|
height 16px
|
||||||
|
//background '/packages/vazco_selectize/img/loading.gif' no-repeat
|
||||||
|
background 'public/images/loading.gif' no-repeat
|
||||||
|
position absolute
|
||||||
|
top 10px
|
||||||
|
right 10px
|
||||||
|
z-index 1000
|
||||||
|
&.multi
|
||||||
|
.selectize-input
|
||||||
|
height 36px
|
||||||
|
.uniPlaceholder
|
||||||
|
color #bbb
|
||||||
696
imports/util/selectize/selectize.js
Normal file
696
imports/util/selectize/selectize.js
Normal file
@@ -0,0 +1,696 @@
|
|||||||
|
|
||||||
|
import './selectize.html';
|
||||||
|
|
||||||
|
/* Meteor need globals */
|
||||||
|
/* eslint strict: 0 */
|
||||||
|
/* jshint strict: false */
|
||||||
|
|
||||||
|
UniSelectize = function (options, template) {
|
||||||
|
this.items = new ReactiveVar([]);
|
||||||
|
this.itemsSelected = new ReactiveVar([]);
|
||||||
|
this.itemsUnselected = new ReactiveVar([]);
|
||||||
|
|
||||||
|
this.open = new ReactiveVar(false);
|
||||||
|
this.loading = new ReactiveVar(false);
|
||||||
|
this.searchText = new ReactiveVar();
|
||||||
|
this.activeOption = new ReactiveVar(-1);
|
||||||
|
this.inputPosition = new ReactiveVar(-1);
|
||||||
|
this.optionsMethodParams = new ReactiveVar();
|
||||||
|
|
||||||
|
this.create = options.create;
|
||||||
|
this.template = template;
|
||||||
|
this.multiple = options.multiple;
|
||||||
|
this.sortMethod = _.isUndefined(options.sortMethod) ? 'label' : options.sortMethod;
|
||||||
|
this.placeholder = options.placeholder;
|
||||||
|
this.removeButton = options.removeButton !== false;
|
||||||
|
this.createMethod = options.createMethod;
|
||||||
|
this.optionsMethod = options.optionsMethod;
|
||||||
|
this.optionsPlaceholder = options.optionsPlaceholder;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
UniSelectize.prototype.triggerChangeEvent = function() {
|
||||||
|
var self = this;
|
||||||
|
Meteor.defer(function () {
|
||||||
|
$(self.template.find('select')).change();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
UniSelectize.prototype.setItems = function (items, value) {
|
||||||
|
if (!_.isArray(items)) {
|
||||||
|
console.warn('invalid options format');
|
||||||
|
}
|
||||||
|
|
||||||
|
var values = value && (_.isArray(value) ? value : [value]);
|
||||||
|
|
||||||
|
items = _.filter(items, function (item) {
|
||||||
|
if (!item.value || !item.label) {
|
||||||
|
console.info('invalid option', item);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
var itemValues = items.map(function (item) {
|
||||||
|
return item.value;
|
||||||
|
});
|
||||||
|
|
||||||
|
_.each(values, function (val) {
|
||||||
|
if (!_.contains(itemValues, val) && val) {
|
||||||
|
items.push({
|
||||||
|
value: val,
|
||||||
|
label: val
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_.each(items, function (item) {
|
||||||
|
if (_.contains(values, item.value)) {
|
||||||
|
item.selected = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.items.set(items);
|
||||||
|
};
|
||||||
|
|
||||||
|
UniSelectize.prototype.addItems = function (newItems, value) {
|
||||||
|
if (!_.isArray(newItems)) {
|
||||||
|
console.warn('invalid options format');
|
||||||
|
}
|
||||||
|
|
||||||
|
var values = value && (_.isArray(value) ? value : [value]);
|
||||||
|
var items = this.items.get();
|
||||||
|
var itemsValues = items.map(function (item) {
|
||||||
|
return item.value;
|
||||||
|
});
|
||||||
|
|
||||||
|
_.each(newItems, function (newItem) {
|
||||||
|
if (!newItem.value || !newItem.label) {
|
||||||
|
console.info('invalid option', newItem);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_.contains(itemsValues, newItem.value)) {
|
||||||
|
var item = {
|
||||||
|
value: newItem.value,
|
||||||
|
label: newItem.label,
|
||||||
|
selected: newItem.selected
|
||||||
|
};
|
||||||
|
|
||||||
|
if (_.contains(values, newItem.value)) {
|
||||||
|
item.selected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
items.push(item);
|
||||||
|
} else if (typeof newItem.selected !== 'undefined') {
|
||||||
|
var item = _.find(items, function (item) {
|
||||||
|
return item.value === newItem.value;
|
||||||
|
});
|
||||||
|
item.selected = newItem.selected;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.items.set(items);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
UniSelectize.prototype.removeUnusedItems = function (newItems) {
|
||||||
|
if (!_.isArray(newItems)) {
|
||||||
|
console.warn('invalid options format');
|
||||||
|
}
|
||||||
|
|
||||||
|
var items = this.items.get();
|
||||||
|
var newItemsValues = newItems.map(function (item) {
|
||||||
|
return item.value;
|
||||||
|
});
|
||||||
|
|
||||||
|
items = _.filter(items, function (item) {
|
||||||
|
return _.contains(newItemsValues, item.value) || item.selected;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.items.set(items);
|
||||||
|
};
|
||||||
|
|
||||||
|
UniSelectize.prototype.itemsAutorun = function () {
|
||||||
|
var items = this.items.get();
|
||||||
|
var itemsSelected = [];
|
||||||
|
var itemsUnselected = [];
|
||||||
|
|
||||||
|
_.each(items, function (item) {
|
||||||
|
if (item.selected) {
|
||||||
|
itemsSelected.push(item);
|
||||||
|
} else {
|
||||||
|
itemsUnselected.push(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (this.sortMethod) {
|
||||||
|
itemsSelected = _.sortBy(itemsSelected, this.sortMethod);
|
||||||
|
itemsUnselected = _.sortBy(itemsUnselected, this.sortMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
var itemsSelectedPrev = this.itemsSelected.get();
|
||||||
|
if (!_.isEqual(itemsSelectedPrev, itemsSelected)) {
|
||||||
|
this.itemsSelected.set(itemsSelected);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.placeholder && this.optionsPlaceholder) {
|
||||||
|
itemsUnselected.unshift({
|
||||||
|
value: '',
|
||||||
|
label: _.isString(this.optionsPlaceholder) ? this.optionsPlaceholder: this.placeholder
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.itemsUnselected.set(itemsUnselected);
|
||||||
|
};
|
||||||
|
|
||||||
|
UniSelectize.prototype.itemsSelectedAutorun = function () {
|
||||||
|
var itemsSelected = this.template.uniSelectize.itemsSelected.get();
|
||||||
|
this.template.uniSelectize.inputPosition.set(itemsSelected.length - 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
UniSelectize.prototype.inputFocus = function () {
|
||||||
|
var self = this;
|
||||||
|
Meteor.defer(function () {
|
||||||
|
var $input = $(self.template.find('input'));
|
||||||
|
$input.focus();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
UniSelectize.prototype.selectItem = function (value) {
|
||||||
|
var items = this.items.get();
|
||||||
|
var multiple = this.multiple;
|
||||||
|
|
||||||
|
_.each(items, function (item) {
|
||||||
|
if (value === '') {
|
||||||
|
item.selected = false;
|
||||||
|
} else if (item.value === value) {
|
||||||
|
item.selected = true;
|
||||||
|
} else if (!multiple) {
|
||||||
|
item.selected = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.setItems(items);
|
||||||
|
this.triggerChangeEvent();
|
||||||
|
};
|
||||||
|
|
||||||
|
UniSelectize.prototype.unselectItem = function (value, reset) {
|
||||||
|
var items = this.items.get();
|
||||||
|
|
||||||
|
_.each(items, function (item) {
|
||||||
|
if (item.value === value || reset) {
|
||||||
|
item.selected = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.setItems(items);
|
||||||
|
this.triggerChangeEvent()
|
||||||
|
};
|
||||||
|
|
||||||
|
UniSelectize.prototype.removeItemBeforeInput = function () {
|
||||||
|
var items = this.itemsSelected.get();
|
||||||
|
var inputPosition = this.inputPosition.get();
|
||||||
|
var itemToRemove;
|
||||||
|
|
||||||
|
_.each(items, function (item, index) {
|
||||||
|
if (index === inputPosition) {
|
||||||
|
itemToRemove = item;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (itemToRemove) {
|
||||||
|
this.unselectItem(itemToRemove.value, false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
UniSelectize.prototype.removeItemAfterInput = function () {
|
||||||
|
var items = this.itemsSelected.get();
|
||||||
|
var inputPosition = this.inputPosition.get();
|
||||||
|
var itemToRemove;
|
||||||
|
|
||||||
|
_.each(items, function (item, index) {
|
||||||
|
if (index === inputPosition + 1) {
|
||||||
|
itemToRemove = item;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (itemToRemove) {
|
||||||
|
this.unselectItem(itemToRemove.value, false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
UniSelectize.prototype.selectActiveItem = function () {
|
||||||
|
var itemsUnselected = this.getItemsUnselectedFiltered();
|
||||||
|
var activeOption = this.activeOption.get();
|
||||||
|
var itemToSelect = itemsUnselected && itemsUnselected[activeOption];
|
||||||
|
|
||||||
|
if (activeOption === itemsUnselected.length && this.create) {
|
||||||
|
this.createItem();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
itemToSelect && this.selectItem(itemToSelect.value);
|
||||||
|
|
||||||
|
if (this.multiple) {
|
||||||
|
this.open.set(true);
|
||||||
|
this.inputFocus();
|
||||||
|
} else {
|
||||||
|
this.open.set(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
UniSelectize.prototype.insertItem = function (item) {
|
||||||
|
var items = this.items.get();
|
||||||
|
|
||||||
|
if (!_.find(items, function (obj) {
|
||||||
|
if (obj.value === item.value) {
|
||||||
|
obj.selected = item.selected;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
})) {
|
||||||
|
items.push(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setItems(items);
|
||||||
|
this.triggerChangeEvent();
|
||||||
|
};
|
||||||
|
|
||||||
|
UniSelectize.prototype.createItem = function () {
|
||||||
|
var self = this;
|
||||||
|
var template = this.template;
|
||||||
|
var searchText = this.searchText.get();
|
||||||
|
|
||||||
|
if (!searchText) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var item = {
|
||||||
|
label: searchText,
|
||||||
|
value: searchText,
|
||||||
|
selected: true
|
||||||
|
};
|
||||||
|
|
||||||
|
if (template.uniSelectize.createMethod) {
|
||||||
|
Meteor.call(template.uniSelectize.createMethod, searchText, searchText, function (error, value) {
|
||||||
|
if (error) {
|
||||||
|
console.error('universe selectize create method error:', error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Meteor.defer(function () {
|
||||||
|
item.value = value || item.value;
|
||||||
|
self.insertItem(item);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.insertItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.multiple) {
|
||||||
|
this.inputFocus();
|
||||||
|
} else {
|
||||||
|
this.open.set(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
UniSelectize.prototype.getItemsUnselectedFiltered = function () {
|
||||||
|
var items = this.itemsUnselected.get();
|
||||||
|
var searchText = this.searchText.get();
|
||||||
|
|
||||||
|
return _.filter(items, function (item) {
|
||||||
|
if (item.label && item.label.search(new RegExp(searchText, 'i')) !== -1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
UniSelectize.prototype.checkDisabled = function () {
|
||||||
|
if (this.template.data.disabled) {
|
||||||
|
throw new Meteor.Error('This field is disabled');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
UniSelectize.prototype.measureString = function (str, $parent) {
|
||||||
|
if (!str) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
var $test = $('<test>').css({
|
||||||
|
position: 'absolute',
|
||||||
|
top: -99999,
|
||||||
|
left: -99999,
|
||||||
|
width: 'auto',
|
||||||
|
padding: 0,
|
||||||
|
whiteSpace: 'pre'
|
||||||
|
}).text(str).appendTo('body');
|
||||||
|
|
||||||
|
this.transferStyles($parent, $test, [
|
||||||
|
'letterSpacing',
|
||||||
|
'fontSize',
|
||||||
|
'fontFamily',
|
||||||
|
'fontWeight',
|
||||||
|
'textTransform'
|
||||||
|
]);
|
||||||
|
|
||||||
|
var width = $test.width();
|
||||||
|
$test.remove();
|
||||||
|
|
||||||
|
return width;
|
||||||
|
};
|
||||||
|
|
||||||
|
UniSelectize.prototype.transferStyles = function ($from, $to, properties) {
|
||||||
|
var i, n, styles = {};
|
||||||
|
|
||||||
|
if (properties) {
|
||||||
|
for (i = 0, n = properties.length; i < n; i++) {
|
||||||
|
styles[properties[i]] = $from.css(properties[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
styles = $from.css();
|
||||||
|
}
|
||||||
|
|
||||||
|
$to.css(styles);
|
||||||
|
};
|
||||||
|
|
||||||
|
UniSelectize.prototype.getOptionsFromMethod = function (values) {
|
||||||
|
var self = this;
|
||||||
|
var methodName = this.optionsMethod;
|
||||||
|
var searchText = this.searchText.get();
|
||||||
|
var params = this.optionsMethodParams.get();
|
||||||
|
|
||||||
|
if (!methodName) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var searchVal = {
|
||||||
|
searchText: searchText,
|
||||||
|
values: values || [],
|
||||||
|
params: params || null
|
||||||
|
};
|
||||||
|
|
||||||
|
self.loading.set(true);
|
||||||
|
Meteor.call(methodName, searchVal, function (err, options) {
|
||||||
|
self.loading.set(false);
|
||||||
|
if (params) {
|
||||||
|
self.removeUnusedItems(options);
|
||||||
|
}
|
||||||
|
self.addItems(options, values);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Template.Selectize.onCreated(function () {
|
||||||
|
var template = this;
|
||||||
|
template.uniSelectize = new UniSelectize(template.data, template);
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.Selectize.onRendered(function () {
|
||||||
|
var template = this;
|
||||||
|
|
||||||
|
template.autorun(function () {
|
||||||
|
var data = Template.currentData();
|
||||||
|
var value = data.value;
|
||||||
|
|
||||||
|
if (template.uniSelectize.optionsMethod) {
|
||||||
|
template.uniSelectize.getOptionsFromMethod(value);
|
||||||
|
} else {
|
||||||
|
var options = data.options;
|
||||||
|
template.uniSelectize.setItems(options, value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
template.autorun(function () {
|
||||||
|
template.uniSelectize.itemsAutorun();
|
||||||
|
});
|
||||||
|
|
||||||
|
template.autorun(function () {
|
||||||
|
template.uniSelectize.itemsSelectedAutorun();
|
||||||
|
});
|
||||||
|
|
||||||
|
template.autorun(function () {
|
||||||
|
var data = Template.currentData();
|
||||||
|
var methodParams = data.optionsMethodParams;
|
||||||
|
var params = _.isFunction(methodParams) ? methodParams() : methodParams;
|
||||||
|
|
||||||
|
template.uniSelectize.optionsMethodParams.set(params);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.form = $(template.find('select')).parents('form');
|
||||||
|
this.form.bind('reset', function () {
|
||||||
|
template.uniSelectize.unselectItem(null, true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.Selectize.onDestroyed(function () {
|
||||||
|
if (this.form) {
|
||||||
|
this.form.unbind('reset');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.Selectize.helpers({
|
||||||
|
multiple: function () {
|
||||||
|
var template = Template.instance();
|
||||||
|
return template.uniSelectize.multiple;
|
||||||
|
},
|
||||||
|
removeButton: function () {
|
||||||
|
var template = Template.instance();
|
||||||
|
return template.uniSelectize.multiple && template.uniSelectize.removeButton;
|
||||||
|
},
|
||||||
|
getItems: function () {
|
||||||
|
var template = Template.instance();
|
||||||
|
return template.uniSelectize.items.get();
|
||||||
|
},
|
||||||
|
getItemsSelected: function () {
|
||||||
|
var template = Template.instance();
|
||||||
|
return template.uniSelectize.itemsSelected.get();
|
||||||
|
},
|
||||||
|
getItemsUnselected: function () {
|
||||||
|
var template = Template.instance();
|
||||||
|
return template.uniSelectize.getItemsUnselectedFiltered();
|
||||||
|
},
|
||||||
|
getSearchText: function () {
|
||||||
|
var template = Template.instance();
|
||||||
|
return template.uniSelectize.searchText.get();
|
||||||
|
},
|
||||||
|
open: function () {
|
||||||
|
var template = Template.instance();
|
||||||
|
return template.uniSelectize.open.get();
|
||||||
|
},
|
||||||
|
loading: function () {
|
||||||
|
var template = Template.instance();
|
||||||
|
return template.uniSelectize.loading.get();
|
||||||
|
},
|
||||||
|
inputPosition: function (position) {
|
||||||
|
var template = Template.instance();
|
||||||
|
var inputPosition = template.uniSelectize.inputPosition.get();
|
||||||
|
return position === inputPosition;
|
||||||
|
},
|
||||||
|
activeOption: function (position) {
|
||||||
|
var template = Template.instance();
|
||||||
|
var activeOption = template.uniSelectize.activeOption.get();
|
||||||
|
var itemsUnselected = template.uniSelectize.getItemsUnselectedFiltered();
|
||||||
|
var createOption = template.uniSelectize.create;
|
||||||
|
|
||||||
|
if (activeOption === itemsUnselected.length && createOption) {
|
||||||
|
return position === 'create';
|
||||||
|
}
|
||||||
|
|
||||||
|
return position === activeOption;
|
||||||
|
},
|
||||||
|
getPlaceholder: function () {
|
||||||
|
var template = Template.instance();
|
||||||
|
var itemsSelected = template.uniSelectize.itemsSelected.get();
|
||||||
|
|
||||||
|
if (itemsSelected.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return template.uniSelectize.placeholder;
|
||||||
|
},
|
||||||
|
isPlaceholder: function () {
|
||||||
|
return this.value === '' ? 'uniPlaceholder' : '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
Template.Selectize.events({
|
||||||
|
'click .selectize-input': function (e, template) {
|
||||||
|
template.uniSelectize.checkDisabled();
|
||||||
|
template.uniSelectize.inputFocus(template);
|
||||||
|
|
||||||
|
template.uniSelectize.getOptionsFromMethod();
|
||||||
|
},
|
||||||
|
'keydown input.js-selectizeInput': function (e, template) {
|
||||||
|
var uniSelectize = template.uniSelectize;
|
||||||
|
var itemsSelected = uniSelectize.itemsSelected.get();
|
||||||
|
var itemsUnselected = uniSelectize.getItemsUnselectedFiltered();
|
||||||
|
var inputPosition = uniSelectize.inputPosition.get();
|
||||||
|
var activeOption = uniSelectize.activeOption.get();
|
||||||
|
|
||||||
|
template.uniSelectize.checkDisabled();
|
||||||
|
|
||||||
|
var $input = $(e.target);
|
||||||
|
var width = template.uniSelectize.measureString($input.val(), $input) + 10;
|
||||||
|
|
||||||
|
$input.width(width);
|
||||||
|
|
||||||
|
switch (e.keyCode) {
|
||||||
|
case 8: // backspace
|
||||||
|
if ($input.val() === '') {
|
||||||
|
e.preventDefault();
|
||||||
|
uniSelectize.removeItemBeforeInput();
|
||||||
|
}
|
||||||
|
uniSelectize.open.set(true);
|
||||||
|
uniSelectize.inputFocus();
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 46: // delete
|
||||||
|
if ($input.val() === '') {
|
||||||
|
uniSelectize.removeItemAfterInput();
|
||||||
|
}
|
||||||
|
uniSelectize.open.set(true);
|
||||||
|
uniSelectize.inputFocus();
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 27: // escape
|
||||||
|
$input.blur();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 13: // enter
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
if (activeOption === -1 && $input.val() === '') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemsUnselected && itemsUnselected.length > 0) {
|
||||||
|
uniSelectize.selectActiveItem(template);
|
||||||
|
uniSelectize.searchText.set('');
|
||||||
|
$input.val('');
|
||||||
|
} else if (uniSelectize.create /*&& createOnBlur*/) {
|
||||||
|
uniSelectize.createItem();
|
||||||
|
uniSelectize.searchText.set('');
|
||||||
|
$input.val('');
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 37: // left
|
||||||
|
if (!uniSelectize.multiple) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (inputPosition > -1) {
|
||||||
|
uniSelectize.inputPosition.set(inputPosition - 1);
|
||||||
|
uniSelectize.inputFocus();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 39: // right
|
||||||
|
if (!uniSelectize.multiple) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (inputPosition < itemsSelected.length - 1) {
|
||||||
|
uniSelectize.inputPosition.set(inputPosition + 1);
|
||||||
|
uniSelectize.inputFocus();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 38: // up
|
||||||
|
if (activeOption > -1) {
|
||||||
|
uniSelectize.activeOption.set(activeOption - 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 40: // down
|
||||||
|
if (activeOption < itemsUnselected.length - 1 ||
|
||||||
|
(activeOption < itemsUnselected.length && uniSelectize.create)) {
|
||||||
|
uniSelectize.activeOption.set(activeOption + 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!template.uniSelectize.multiple && itemsSelected.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'keyup input.js-selectizeInput': function (e, template) {
|
||||||
|
template.uniSelectize.checkDisabled();
|
||||||
|
|
||||||
|
var $el = $(e.target);
|
||||||
|
var value = $el.val();
|
||||||
|
template.uniSelectize.searchText.set(value);
|
||||||
|
template.uniSelectize.getOptionsFromMethod();
|
||||||
|
},
|
||||||
|
'focus input.js-selectizeInput': function (e, template) {
|
||||||
|
template.uniSelectize.checkDisabled();
|
||||||
|
template.uniSelectize.open.set(true);
|
||||||
|
|
||||||
|
Meteor.clearTimeout(template.uniSelectize.timeoutId);
|
||||||
|
},
|
||||||
|
'change input.js-selectizeInput': function(e, template) {
|
||||||
|
template.uniSelectize.checkDisabled();
|
||||||
|
|
||||||
|
// prevent non-autoform fields changes from submitting the form when autosave is enabled
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
},
|
||||||
|
'blur input.js-selectizeInput': function (e, template) {
|
||||||
|
template.uniSelectize.checkDisabled();
|
||||||
|
|
||||||
|
template.uniSelectize.timeoutId = Meteor.setTimeout(function () {
|
||||||
|
template.uniSelectize.open.set(false);
|
||||||
|
}, 500);
|
||||||
|
},
|
||||||
|
'scroll .selectize-dropdown-content': function (e, template) {
|
||||||
|
Meteor.clearTimeout(template.uniSelectize.timeoutId);
|
||||||
|
template.uniSelectize.timeoutId = Meteor.setTimeout(function () {
|
||||||
|
template.uniSelectize.open.set(false);
|
||||||
|
}, 5000);
|
||||||
|
},
|
||||||
|
'click .selectize-dropdown-content > div:not(.create)': function (e, template) {
|
||||||
|
e.preventDefault();
|
||||||
|
template.uniSelectize.checkDisabled();
|
||||||
|
var $input = $(template.find('input'));
|
||||||
|
var itemsUnselected = template.uniSelectize.getItemsUnselectedFiltered();
|
||||||
|
var itemsUnselectedLength = itemsUnselected && itemsUnselected.length;
|
||||||
|
|
||||||
|
template.uniSelectize.selectItem(this.value);
|
||||||
|
template.uniSelectize.searchText.set('');
|
||||||
|
$input.val('');
|
||||||
|
|
||||||
|
if (template.uniSelectize.multiple && itemsUnselectedLength && this.value) {
|
||||||
|
template.uniSelectize.inputFocus();
|
||||||
|
} else {
|
||||||
|
template.uniSelectize.open.set(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'mouseenter .selectize-dropdown-content > div': function (e, template) {
|
||||||
|
var $el = $(e.target);
|
||||||
|
var elIndex = $el.attr('data-index');
|
||||||
|
var itemsUnselected = template.uniSelectize.getItemsUnselectedFiltered();
|
||||||
|
|
||||||
|
if (elIndex === 'create') {
|
||||||
|
elIndex = itemsUnselected.length;
|
||||||
|
} else {
|
||||||
|
elIndex = parseInt(elIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
template.uniSelectize.activeOption.set(elIndex);
|
||||||
|
},
|
||||||
|
'click .create': function (e, template) {
|
||||||
|
e.preventDefault();
|
||||||
|
template.uniSelectize.checkDisabled();
|
||||||
|
var $input = $(template.find('input'));
|
||||||
|
|
||||||
|
template.uniSelectize.createItem();
|
||||||
|
template.uniSelectize.searchText.set('');
|
||||||
|
$input.val('');
|
||||||
|
},
|
||||||
|
'click .remove': function (e, template) {
|
||||||
|
e.preventDefault();
|
||||||
|
template.uniSelectize.checkDisabled();
|
||||||
|
|
||||||
|
template.uniSelectize.unselectItem(this.value, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
0
imports/util/selectize/temp.import.styl
vendored
Normal file
0
imports/util/selectize/temp.import.styl
vendored
Normal file
550
imports/util/validator.js
Normal file
550
imports/util/validator.js
Normal file
@@ -0,0 +1,550 @@
|
|||||||
|
/*!
|
||||||
|
* Validator v0.11.5 for Bootstrap 3, by @1000hz
|
||||||
|
* Copyright 2016 Cina Saffary
|
||||||
|
* Licensed under http://opensource.org/licenses/MIT
|
||||||
|
*
|
||||||
|
* https://github.com/1000hz/bootstrap-validator
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Modified by Wynne Crisman 10/2016.
|
||||||
|
* Modifications Copyright 2016 Wynne Crisman
|
||||||
|
* Modifications licensed under http://opensource.org/licenses/MIT
|
||||||
|
*
|
||||||
|
* Added commenting and formatting to tabs - wtf spaces?! (side note: If you are coding in Notepad or vim, please seek a therapist's help immediately. Perhaps you haven't heard that there are free tools (Notepad++, Emacs) that do formatting for you, or you can go all out and use an actual integrated development environment like a professional developer who values their time might.)
|
||||||
|
* Added semicolons; While not strictly required, they help with readability (knowing, without thinking, where a line ends is really handy when you code all day) and are required by some pretty printing tools for JS.
|
||||||
|
* Removed code that used && as an if block - this is really hard to read, and will confuse even seasoned developers - there is no reason to do it (any performance improvement is due entirely to crappy VM implementations - there is no hard evidence this is worth the aggravation).
|
||||||
|
* Added an optional parameter to validate(..) - a callback function may be passed now. The callback will be provided with a boolean parameter 'isValid' indicating whether the form validated. This allows developers to easily force a validation and take an action on the result (submit the form?).
|
||||||
|
* Added documentation at the top of this file to provide basic usage information.
|
||||||
|
* Added highlighting on input-group elements in addition to form-group elements.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* USAGE INFO
|
||||||
|
*
|
||||||
|
* Getting Started:
|
||||||
|
* Create a form along with any fields in HTML '<form id='myform'>...</form>', then in your javascript block call: $('#myform').validator(); to initialize the validator.
|
||||||
|
* Your form elements may specify additional standard validation tags to help the validator know what to do (for example add 'required' to any form element to tell the validator which elements must have data).
|
||||||
|
* Form elements should be put into form-groups, placing related elements into a common group. Form groups are simply Div's with the class='form-group'.
|
||||||
|
* Useful Functions:
|
||||||
|
* $(form).validator() - Initializes the validator for a form. This does not return the validator instance, but it does attach it to the form element.
|
||||||
|
* $(form).data('bs.validator') - Gets the validator object for the given form. The validator object is stored as data attached to the form with the 'bs.validator' key.
|
||||||
|
* validate(fn) - Forces validation to occur and takes an optional callback which will be passed a flag (boolean) indicating the success of the validation (isValid).
|
||||||
|
* reset() - Resets the form's validation status. Clears all error information, without turning validation off.
|
||||||
|
* update() - Updates the collection of fields that require validation. Call this after making changes to the form, including initializing any form elements that may generate HTML (such as Select2).
|
||||||
|
*/
|
||||||
|
|
||||||
|
+function ($) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// VALIDATOR CLASS DEFINITION
|
||||||
|
// ==========================
|
||||||
|
|
||||||
|
//Gets the value of the HTML element.
|
||||||
|
function getValue($el) {
|
||||||
|
if($el.is('[type="checkbox"]')) {
|
||||||
|
return $el.prop('checked')
|
||||||
|
}
|
||||||
|
else if($el.is('[type="radio"]')) {
|
||||||
|
return !!$('[name="' + $el.attr('name') + '"]:checked').length
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return $el.val();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Gets the actual element to perform the validation on. This returns the input element if the input element isn't a surrogate for a hidden form element.
|
||||||
|
//Some widget libraries (such as Select2) hide the actual element that holds the data, and use custom graphical elements for the control and display logic.
|
||||||
|
//We need the actual element that holds the value, and not the display elements which fire the events we are interested in (focusout, etc).
|
||||||
|
function getActualWidget($el) {
|
||||||
|
if($el.hasClass('select2-search__field')) { //Handle Select2 multi-select controls.
|
||||||
|
//Select2 creates a structure of span elements whose parent span has the .select2 class and whose sibling is a hidden select element that contains the actual selection to be validated.
|
||||||
|
return $el.parents('.select2').siblings('select');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return $el;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//The opposite of getActualWidget($el). Gets the visible surrogate widget for the actual hidden form widget.
|
||||||
|
//The actual hidden widget holds the value and acts like a form element when submitting the form, while the surrogate has the display and functionality desired by the view.
|
||||||
|
function getSurrogate($el) {
|
||||||
|
if($el.hasClass('select2-hidden-accessible')) { //Handle Select2 multi-select controls.
|
||||||
|
//Select2 creates a structure of span elements whose parent span has the .select2 class and whose sibling is a hidden select element that contains the actual selection to be validated.
|
||||||
|
return $el.siblings('.select2').find('.select2-selection');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return $el;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var Validator = function(element, options) {
|
||||||
|
this.options = options;
|
||||||
|
this.validators = $.extend({}, Validator.VALIDATORS, options.custom);
|
||||||
|
this.$element = $(element);
|
||||||
|
this.$btn = $('button[type="submit"], input[type="submit"]')
|
||||||
|
.filter('[form="' + this.$element.attr('id') + '"]')
|
||||||
|
.add(this.$element.find('input[type="submit"], button[type="submit"]'));
|
||||||
|
|
||||||
|
this.update();
|
||||||
|
|
||||||
|
//Register for the events (uses a namespace for easy de-registration).
|
||||||
|
this.$element.on('input.bs.validator change.bs.validator focusout.bs.validator', $.proxy(this.onInput, this));
|
||||||
|
this.$element.on('submit.bs.validator', $.proxy(this.onSubmit, this));
|
||||||
|
this.$element.on('reset.bs.validator', $.proxy(this.reset, this));
|
||||||
|
|
||||||
|
//TODO: What is '[data-match]' ????
|
||||||
|
//This will find some kind of matching elements in the form and when the validation event is detected on the match target (retrieved from the data-match element's 'match' data), a validation event will also be fired on the data-match element.
|
||||||
|
this.$element.find('[data-match]').each(function() {
|
||||||
|
var $this = $(this);
|
||||||
|
var target = $this.data('match');
|
||||||
|
|
||||||
|
//Register an event handler on the match target element and if the match target element has a value, then fire the validator event on the data-match element also.
|
||||||
|
$(target).on('input.bs.validator', function(e) {
|
||||||
|
if(getValue($this)) $this.trigger('input.bs.validator');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
//Force validation on any elements that start with values (ignore those that don't).
|
||||||
|
//Filter the HTML elements we will be validating to get the set that contains values (ignore those that don't have values), then trigger a 'focusout' event on those elements (forcing validation as we start the Validator up).
|
||||||
|
this.$inputs.filter(function() {
|
||||||
|
return getValue($(this))
|
||||||
|
}).trigger('focusout');
|
||||||
|
|
||||||
|
//Diable automatic native validation.
|
||||||
|
this.$element.attr('novalidate', true);
|
||||||
|
//Update the submit elements based on the current error state.
|
||||||
|
this.toggleSubmit();
|
||||||
|
};
|
||||||
|
|
||||||
|
Validator.VERSION = '0.11.5';
|
||||||
|
|
||||||
|
Validator.INPUT_SELECTOR = ':input:not([type="hidden"], [type="submit"], [type="reset"], button, .select2-search__field)'
|
||||||
|
|
||||||
|
Validator.SURROGATE_SELECTOR = '.select2 .select2-selection';
|
||||||
|
|
||||||
|
Validator.FOCUS_OFFSET = 20;
|
||||||
|
|
||||||
|
Validator.DEFAULTS = {
|
||||||
|
delay: 500,
|
||||||
|
html: false,
|
||||||
|
disable: true,
|
||||||
|
focus: true,
|
||||||
|
custom: {},
|
||||||
|
errors: {
|
||||||
|
match: 'Does not match',
|
||||||
|
minlength: 'Not long enough'
|
||||||
|
},
|
||||||
|
feedback: {
|
||||||
|
success: 'glyphicon-ok',
|
||||||
|
error: 'glyphicon-remove'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//The default set of validators to be used.
|
||||||
|
Validator.VALIDATORS = {
|
||||||
|
'native': function($el) {
|
||||||
|
var el = $el[0];
|
||||||
|
if(el.checkValidity) {
|
||||||
|
return !el.checkValidity() && !el.validity.valid && (el.validationMessage || "error!");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'match': function($el) {
|
||||||
|
var target = $el.data('match');
|
||||||
|
return $el.val() !== $(target).val() && Validator.DEFAULTS.errors.match;
|
||||||
|
},
|
||||||
|
'minlength': function($el) {
|
||||||
|
var minlength = $el.data('minlength');
|
||||||
|
return $el.val().length < minlength && Validator.DEFAULTS.errors.minlength;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//Collects a list of HTML elements that require validation using the INPUT_SELECTOR option supplied when the Validator was created, and the default data-validate attribute that can be supplied in the HTML tags.
|
||||||
|
Validator.prototype.update = function() {
|
||||||
|
this.$inputs = this.$element.find(Validator.INPUT_SELECTOR)
|
||||||
|
.add(this.$element.find('[data-validate="true"]'))
|
||||||
|
.not(this.$element.find('[data-validate="false"]'));
|
||||||
|
this.$surrogates = this.$inputs.filter('.select2-hidden-accessible').map(function(el) {
|
||||||
|
return getSurrogate($(this));
|
||||||
|
});
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
//An event handler that will perform validation on a HTML element when that element fires an event.
|
||||||
|
Validator.prototype.onInput = function(e) {
|
||||||
|
var self = this;
|
||||||
|
var $surrogate = $(e.target); //Wrapper the event target with a jquery object.
|
||||||
|
var $el = getActualWidget($surrogate); //Get the actual (hidden) form widget if there is one, otherwise $el will equal (===) $surrogate.
|
||||||
|
var deferErrors = e.type !== 'focusout';
|
||||||
|
|
||||||
|
//If the event target is not in the set of HTML elements that require validation, then ignore it.
|
||||||
|
if(!this.$inputs.is($el)) return;
|
||||||
|
|
||||||
|
//Validate the HTML element and update the submit button's state as necessary.
|
||||||
|
this.validateInput($el, $surrogate, deferErrors).done(function() {
|
||||||
|
self.toggleSubmit();
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
//Runs a complete validation. Returns this validator (does not return the result of the validation since the validation is performed in the future).
|
||||||
|
//@param fn An optional function that will be run after validating, and which will be passed a boolean indicating whether the form passed validation (isValid). [Added by Wynne Crisman 10/2016]
|
||||||
|
// Allows the user to validate and do something based on the form's validity without any complicated gyrations:
|
||||||
|
// $form.data('bs.validator').validate(function(isValid) { if(isValid) { /* Allow form submittal. */ }});
|
||||||
|
Validator.prototype.validate = function(fn) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
//Create a collection of promises by validating each input HTML element, then update the submit logic based on the presence of errors and set the focus to the first element with an error.
|
||||||
|
$.when(this.$inputs.map(function(el) {
|
||||||
|
var $el = $(this); //Wrapper the event target with a jquery object.
|
||||||
|
var $surrogate = getSurrogate($el); //Gets the surrogate widget used to manage the display and functionality. Will === $el if there isn't a surrogate.
|
||||||
|
|
||||||
|
return self.validateInput($el, $surrogate, false);
|
||||||
|
})).then(function() {
|
||||||
|
self.toggleSubmit();
|
||||||
|
self.focusError();
|
||||||
|
|
||||||
|
//Call the callback, passing whether the form is valid (boolean).
|
||||||
|
if(fn instanceof Function) fn(!self.isIncomplete() && !self.hasErrors());
|
||||||
|
});
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
//Validates the value of an HTML element and returns a promise.
|
||||||
|
Validator.prototype.validateInput = function($el, $surrogate, deferErrors) {
|
||||||
|
//var value = getValue($el);
|
||||||
|
var prevErrors = $el.data('bs.validator.errors'); //Get the errors from a previous run of the validator.
|
||||||
|
var errors;
|
||||||
|
|
||||||
|
if($el.is('[type="radio"]')) $el = this.$element.find('input[name="' + $el.attr('name') + '"]');
|
||||||
|
|
||||||
|
//Create a validator event indicating we are about to validate.
|
||||||
|
var e = $.Event('validate.bs.validator', {relatedTarget: $el[0]});
|
||||||
|
//Fire the event.
|
||||||
|
this.$element.trigger(e);
|
||||||
|
//If the event handlers flag that we shouldn't validate then stop here.
|
||||||
|
if(e.isDefaultPrevented()) return;
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
//Run the validators on our HTML element and handle any errors.
|
||||||
|
return this.runValidators($el).done(function(errors) {
|
||||||
|
//Save the errors by attaching them to the HTML element.
|
||||||
|
$el.data('bs.validator.errors', errors);
|
||||||
|
|
||||||
|
//If there were no errors then call clearErrors() to remove the error styling on the view, otherwise we do have errors and we either show them immediately (change styling & HTML) or defer the showing of them until later if told to defer.
|
||||||
|
!errors.length ? self.clearErrors($el) : (deferErrors ? self.defer($el, self.showErrors) : self.showErrors($el));
|
||||||
|
|
||||||
|
//If this is the first run of the validator for this element (prevErrors == undefined), or the previous errors are the same as the new errors (nothing changed), then fire an event notifying listeners of the change in error status.
|
||||||
|
if(!prevErrors || errors.toString() !== prevErrors.toString()) {
|
||||||
|
if(errors.length) {
|
||||||
|
e = $.Event('invalid.bs.validator', {relatedTarget: $el[0], detail: errors});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
e = $.Event('valid.bs.validator', {relatedTarget: $el[0], detail: prevErrors});
|
||||||
|
}
|
||||||
|
|
||||||
|
//Fire the event.
|
||||||
|
self.$element.trigger(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Update the view's submit elements based on the error state of the form.
|
||||||
|
self.toggleSubmit();
|
||||||
|
//Fire an event on the form indicating the related element was validated (irregardless of whether it has errors or not).
|
||||||
|
self.$element.trigger($.Event('validated.bs.validator', {relatedTarget: $el[0]}));
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//Returns a Promise where the result is the array of errors (error messages) found by the validator. The promise will be passed an empty array if there are no errors.
|
||||||
|
Validator.prototype.runValidators = function($el) {
|
||||||
|
var errors = [];
|
||||||
|
var deferred = $.Deferred();
|
||||||
|
|
||||||
|
//If using deferred validation then reject (avoid recursive calls?).
|
||||||
|
if($el.data('bs.validator.deferred')) $el.data('bs.validator.deferred').reject();
|
||||||
|
//Set that validation is deferred (avoid recursive calls?).
|
||||||
|
$el.data('bs.validator.deferred', deferred);
|
||||||
|
|
||||||
|
function getValidatorSpecificError(key) {
|
||||||
|
return $el.data(key + '-error');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getValidityStateError() {
|
||||||
|
var validity = $el[0].validity;
|
||||||
|
return validity.typeMismatch ? $el.data('type-error')
|
||||||
|
: validity.patternMismatch ? $el.data('pattern-error')
|
||||||
|
: validity.stepMismatch ? $el.data('step-error')
|
||||||
|
: validity.rangeOverflow ? $el.data('max-error')
|
||||||
|
: validity.rangeUnderflow ? $el.data('min-error')
|
||||||
|
: validity.valueMissing ? $el.data('required-error')
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getGenericError() {
|
||||||
|
return $el.data('error');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getErrorMessage(key) {
|
||||||
|
return getValidatorSpecificError(key)
|
||||||
|
|| getValidityStateError()
|
||||||
|
|| getGenericError();
|
||||||
|
}
|
||||||
|
|
||||||
|
//For each validator in the validator hashmap (key value pair), call the function f(key,validator) using this as the context (so it has access to 'this' from this method).
|
||||||
|
//See the VALIDATORS hashmap defined above (used as the default set of validator functions).
|
||||||
|
$.each(this.validators, $.proxy(function(key, validator) {
|
||||||
|
var error;
|
||||||
|
|
||||||
|
//If the HTML element has a value OR is required, AND there is data attached to the HTML element for the current validator OR the validator is 'native', AND the validator produces an error.
|
||||||
|
if((getValue($el) || $el.attr('required')) && ($el.data(key) || key == 'native') && (error = validator.call(this, $el))) {
|
||||||
|
//Allow generic or state or specific validator errors to trump the validation error.
|
||||||
|
error = getErrorMessage(key) || error;
|
||||||
|
|
||||||
|
//If the error is not in the list then add it. Use jquery.inArray instead of indexOf since indexOf does not exist in some IE versions.
|
||||||
|
if(!~$.inArray(error, errors)) errors.push(error);
|
||||||
|
}
|
||||||
|
}, this));
|
||||||
|
|
||||||
|
//Get errors from the server if a 'remote' URL is provided (allow it to check the element's value and supply additional errors), and then resolve the promise with the collected errors.
|
||||||
|
//If there are no errors AND the HTML element has a value AND the HTML element has 'remote' data associated, then make an AJAX call sometime in the future to pass the server the element name and value, otherwise resolve the promise passing the error list.
|
||||||
|
if(!errors.length && getValue($el) && $el.data('remote')) {
|
||||||
|
this.defer($el, function() {
|
||||||
|
var data = {};
|
||||||
|
|
||||||
|
//Assign elementName = elementValue to the data object.
|
||||||
|
data[$el.attr('name')] = getValue($el);
|
||||||
|
//Make an AJAX GET call to the URL stored in the element's 'remote' data, passing the object containing the element's name and its value. If there is an error in the AJAX call then add the error to the error list.
|
||||||
|
$.get($el.data('remote'), data)
|
||||||
|
.fail(function(jqXHR, textStatus, error) {
|
||||||
|
errors.push(getErrorMessage('remote') || error)
|
||||||
|
})
|
||||||
|
.always(function() {
|
||||||
|
deferred.resolve(errors)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else deferred.resolve(errors);
|
||||||
|
|
||||||
|
//Return the promise that will be passed the collected errors (array of strings) when the error checking is complete.
|
||||||
|
return deferred.promise();
|
||||||
|
};
|
||||||
|
|
||||||
|
//Changes the focus to the first element with an error.
|
||||||
|
Validator.prototype.focusError = function() {
|
||||||
|
if(!this.options.focus) return;
|
||||||
|
|
||||||
|
var $input = this.$element.find(".has-error:first"); // :input
|
||||||
|
|
||||||
|
if($input.length === 0) return;
|
||||||
|
//Find the input field if it is a input group or form group that has the error markings.
|
||||||
|
if($input.hasClass('form-group') || $input.hasClass('input-group')) {
|
||||||
|
$input = $input.find('input');
|
||||||
|
}
|
||||||
|
|
||||||
|
//If this is a select2 control then look for the child of a sibling that has the .select2-selection class and use it instead.
|
||||||
|
if($input.hasClass('select2-hidden-accessible')) {
|
||||||
|
$input = $input.parent().find('.select2-selection');
|
||||||
|
}
|
||||||
|
|
||||||
|
$('html, body').animate({scrollTop: $input.offset().top - Validator.FOCUS_OFFSET}, 250);
|
||||||
|
$input.focus();
|
||||||
|
};
|
||||||
|
|
||||||
|
//Alters the display to highlight errors in the form.
|
||||||
|
Validator.prototype.showErrors = function($el) {
|
||||||
|
var method = this.options.html ? 'html' : 'text';
|
||||||
|
var errors = $el.data('bs.validator.errors');
|
||||||
|
var $group = $el.closest('.form-group,.input-group');
|
||||||
|
var $block = $group.find('.help-block.with-errors');
|
||||||
|
var $feedback = $group.find('.form-control-feedback');
|
||||||
|
|
||||||
|
if(!errors.length) return;
|
||||||
|
|
||||||
|
errors = $('<ul/>')
|
||||||
|
.addClass('list-unstyled')
|
||||||
|
.append($.map(errors, function(error) {
|
||||||
|
return $('<li/>')[method](error)
|
||||||
|
}));
|
||||||
|
|
||||||
|
if($block.data('bs.validator.originalContent') === undefined)
|
||||||
|
$block.data('bs.validator.originalContent', $block.html());
|
||||||
|
|
||||||
|
$block.empty().append(errors);
|
||||||
|
|
||||||
|
//Add the 'has-error' and 'has-danger' classes to the grouping.
|
||||||
|
$group.addClass('has-error has-danger');
|
||||||
|
|
||||||
|
//If this is a select2 control then look for the child of a sibling that has the .select2-selection class and use it instead.
|
||||||
|
if($el.hasClass('select2-hidden-accessible')) {
|
||||||
|
$el.parent().find('.select2-selection').addClass('has-error has-danger');
|
||||||
|
}
|
||||||
|
|
||||||
|
//If the group has the 'has-feedback' class then remove any success markings and add error markings.
|
||||||
|
if($group.hasClass('has-feedback')) {
|
||||||
|
$feedback.removeClass(this.options.feedback.success);
|
||||||
|
$feedback.addClass(this.options.feedback.error);
|
||||||
|
$group.removeClass('has-success');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//Clears the display of all error information.
|
||||||
|
Validator.prototype.clearErrors = function($el) {
|
||||||
|
var $group = $el.closest('.form-group,.input-group');
|
||||||
|
var $block = $group.find('.help-block.with-errors');
|
||||||
|
var $feedback = $group.find('.form-control-feedback');
|
||||||
|
|
||||||
|
$block.html($block.data('bs.validator.originalContent'));
|
||||||
|
$group.removeClass('has-error has-danger has-success');
|
||||||
|
|
||||||
|
//Clean the sibling controls for select2.
|
||||||
|
$el.parent().find('.select2 .select2-selection').removeClass('has-error has-danger has-success');
|
||||||
|
|
||||||
|
$group.hasClass('has-feedback')
|
||||||
|
&& $feedback.removeClass(this.options.feedback.error)
|
||||||
|
&& $feedback.removeClass(this.options.feedback.success)
|
||||||
|
&& getValue($el)
|
||||||
|
&& $feedback.addClass(this.options.feedback.success)
|
||||||
|
&& $group.addClass('has-success');
|
||||||
|
};
|
||||||
|
|
||||||
|
//Returns whether the form has any errors.
|
||||||
|
//Warning: Calling this externally is dangerous because validation is asynchronous and this call will not wait for validation to finish.
|
||||||
|
// Better to call '$form.data('bs.validator').validate(function(isValid) {...})' instead to ensure validation is done.
|
||||||
|
Validator.prototype.hasErrors = function() {
|
||||||
|
function fieldErrors() {
|
||||||
|
return !!($(this).data('bs.validator.errors') || []).length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return !!this.$inputs.filter(fieldErrors).length;
|
||||||
|
};
|
||||||
|
|
||||||
|
//Returns whether the form is not complete (appears this is due to a text input containing only spaces when a value is required).
|
||||||
|
//Warning: Calling this externally is dangerous because validation is asynchronous and this call will not wait for validation to finish.
|
||||||
|
// Better to call '$form.data('bs.validator').validate(function(isValid) {...})' instead to ensure validation is done.
|
||||||
|
Validator.prototype.isIncomplete = function() {
|
||||||
|
function fieldIncomplete() {
|
||||||
|
var value = getValue($(this));
|
||||||
|
return !(typeof value == "string" ? $.trim(value) : value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return !!this.$inputs.filter('[required]').filter(fieldIncomplete).length;
|
||||||
|
};
|
||||||
|
|
||||||
|
//Prevents form submittal (by setting the preventDefault flag on the event) if the form is not valid or complete.
|
||||||
|
Validator.prototype.onSubmit = function(e) {
|
||||||
|
this.validate();
|
||||||
|
if(this.isIncomplete() || this.hasErrors()) e.preventDefault();
|
||||||
|
};
|
||||||
|
|
||||||
|
//Enables or disables the submit button based on the validation state of the form.
|
||||||
|
Validator.prototype.toggleSubmit = function() {
|
||||||
|
if(!this.options.disable) return;
|
||||||
|
this.$btn.toggleClass('disabled', this.isIncomplete() || this.hasErrors())
|
||||||
|
};
|
||||||
|
|
||||||
|
//Defers the callback function so that it runs sometime in the future. Only one callback may be deferred at any given time. How far into the future it will be deferred depends on the 'delay' option.
|
||||||
|
//Used internally to defer validation as the user interacts with the form such that we don't validated constantly (for every character typed).
|
||||||
|
Validator.prototype.defer = function($el, callback) {
|
||||||
|
//Wrapper the callback so it's 'this' variable will be the validator.
|
||||||
|
callback = $.proxy(callback, this, $el);
|
||||||
|
//If there isn't a delay then run the callback immediately.
|
||||||
|
if(!this.options.delay) return callback();
|
||||||
|
//Clear any callback already being delayed.
|
||||||
|
window.clearTimeout($el.data('bs.validator.timeout'));
|
||||||
|
//Delay the execution of the callback.
|
||||||
|
$el.data('bs.validator.timeout', window.setTimeout(callback, this.options.delay));
|
||||||
|
};
|
||||||
|
|
||||||
|
//Resets the form to its state, removing all validator modifications (but not removing the validator). Returns the validator reference.
|
||||||
|
Validator.prototype.reset = function() {
|
||||||
|
this.$element.find('.form-control-feedback').removeClass(this.options.feedback.error).removeClass(this.options.feedback.success);
|
||||||
|
|
||||||
|
this.$inputs
|
||||||
|
.removeData(['bs.validator.errors', 'bs.validator.deferred'])
|
||||||
|
.each(function() {
|
||||||
|
var $this = $(this);
|
||||||
|
var timeout = $this.data('bs.validator.timeout');
|
||||||
|
window.clearTimeout(timeout) && $this.removeData('bs.validator.timeout');
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$element.find('.help-block.with-errors')
|
||||||
|
.each(function() {
|
||||||
|
var $this = $(this);
|
||||||
|
var originalContent = $this.data('bs.validator.originalContent');
|
||||||
|
|
||||||
|
$this
|
||||||
|
.removeData('bs.validator.originalContent')
|
||||||
|
.html(originalContent);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$btn.removeClass('disabled');
|
||||||
|
this.$element.find('.has-error, .has-danger, .has-success').removeClass('has-error has-danger has-success');
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
//Removes the validator completely and resets the state.
|
||||||
|
Validator.prototype.destroy = function() {
|
||||||
|
this.reset();
|
||||||
|
|
||||||
|
//Remove attributes, data, and event handlers from all elements.
|
||||||
|
this.$element
|
||||||
|
.removeAttr('novalidate')
|
||||||
|
.removeData('bs.validator')
|
||||||
|
.off('.bs.validator');
|
||||||
|
|
||||||
|
//Remove event handlers from input elements.
|
||||||
|
this.$inputs.off('.bs.validator');
|
||||||
|
|
||||||
|
this.options = null;
|
||||||
|
this.validators = null;
|
||||||
|
this.$element = null;
|
||||||
|
this.$btn = null;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
// VALIDATOR PLUGIN DEFINITION
|
||||||
|
// ===========================
|
||||||
|
|
||||||
|
|
||||||
|
//Plugin constructor.
|
||||||
|
function Plugin(option) {
|
||||||
|
return this.each(function() {
|
||||||
|
var $this = $(this);
|
||||||
|
var options = $.extend({}, Validator.DEFAULTS, $this.data(), typeof option == 'object' && option);
|
||||||
|
var data = $this.data('bs.validator');
|
||||||
|
|
||||||
|
if(!data && option == 'destroy') return;
|
||||||
|
if(!data) $this.data('bs.validator', (data = new Validator(this, options)));
|
||||||
|
if(typeof option == 'string') data[option]();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var old = $.fn.validator;
|
||||||
|
|
||||||
|
//JQuery integration.
|
||||||
|
$.fn.validator = Plugin;
|
||||||
|
$.fn.validator.Constructor = Validator;
|
||||||
|
|
||||||
|
|
||||||
|
// VALIDATOR NO CONFLICT
|
||||||
|
// =====================
|
||||||
|
|
||||||
|
$.fn.validator.noConflict = function() {
|
||||||
|
$.fn.validator = old;
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// VALIDATOR DATA-API
|
||||||
|
// ==================
|
||||||
|
|
||||||
|
$(window).on('load', function() {
|
||||||
|
$('form[data-toggle="validator"]').each(function() {
|
||||||
|
var $form = $(this);
|
||||||
|
Plugin.call($form, $form.data());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}(jQuery);
|
||||||
15
package.json
Normal file
15
package.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "PetitTeton",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"start": "meteor run",
|
||||||
|
"build": "meteor build --server-only ../"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"babel-runtime": "^6.18.0",
|
||||||
|
"csv-parse": "latest",
|
||||||
|
"meteor-node-stubs": "^0.2.4",
|
||||||
|
"properties-reader": "0.0.15",
|
||||||
|
"simpl-schema": "0.0.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
public/images/PetitTetonLogo_v2.png
Normal file
BIN
public/images/PetitTetonLogo_v2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user