Add Clinical Meteor packages to Lesion Tracker
This commit is contained in:
parent
383b4ff4c0
commit
b2fa6ead3b
@ -24,7 +24,6 @@ dicomweb
|
||||
accounts-password
|
||||
|
||||
ian:accounts-ui-bootstrap-3
|
||||
iron:router
|
||||
twbs:bootstrap
|
||||
http
|
||||
arsnebula:reactive-promise
|
||||
@ -37,3 +36,14 @@ reactive-dict
|
||||
lesiontracker
|
||||
practicalmeteor:loglevel
|
||||
momentjs:moment
|
||||
|
||||
clinical:router
|
||||
clinical:extended-api
|
||||
clinical:active-entry
|
||||
clinical:static-pages
|
||||
clinical:error-pages
|
||||
clinical:theming
|
||||
clinical:theming-ui
|
||||
clinical:fonts
|
||||
clinical:glass-ui
|
||||
clinical:hipaa-logger
|
||||
|
||||
@ -3,6 +3,7 @@ accounts-password@1.1.4
|
||||
anti:i18n@0.4.3
|
||||
arsnebula:reactive-promise@0.9.1
|
||||
autoupdate@1.2.4
|
||||
awatson1978:fonts-helveticas@1.0.4
|
||||
babel-compiler@5.8.24_1
|
||||
babel-runtime@0.1.4
|
||||
base64@1.0.4
|
||||
@ -15,6 +16,20 @@ caching-compiler@1.0.0
|
||||
caching-html-compiler@1.0.2
|
||||
callback-hook@1.0.4
|
||||
check@1.1.0
|
||||
clinical:active-entry@1.5.14
|
||||
clinical:barcode@3.0.1
|
||||
clinical:error-pages@0.1.1
|
||||
clinical:extended-api@2.2.1
|
||||
clinical:fonts@1.0.0
|
||||
clinical:glass-ui@1.3.7
|
||||
clinical:hipaa-logger@1.0.1
|
||||
clinical:router@2.0.17
|
||||
clinical:router-location@2.0.14
|
||||
clinical:router-middleware-stack@2.0.13
|
||||
clinical:router-url@2.0.15
|
||||
clinical:static-pages@1.0.7
|
||||
clinical:theming@0.3.1
|
||||
clinical:theming-ui@0.2.3
|
||||
coffeescript@1.0.11
|
||||
cornerstone@0.0.1
|
||||
ddp@1.2.2
|
||||
@ -33,6 +48,7 @@ es5-shim@4.1.14
|
||||
fastclick@1.0.7
|
||||
fortawesome:fontawesome@4.4.0
|
||||
geojson-utils@1.0.4
|
||||
grove:less@0.1.1
|
||||
hangingprotocols@0.0.1
|
||||
hot-code-push@1.0.0
|
||||
html-tools@1.0.5
|
||||
@ -45,10 +61,6 @@ iron:controller@1.0.12
|
||||
iron:core@1.0.11
|
||||
iron:dynamic-template@1.0.12
|
||||
iron:layout@1.0.12
|
||||
iron:location@1.0.11
|
||||
iron:middleware-stack@1.0.11
|
||||
iron:router@1.0.12
|
||||
iron:url@1.0.11
|
||||
jquery@1.11.4
|
||||
launch-screen@1.0.4
|
||||
lesiontracker@0.0.1
|
||||
|
||||
36
LesionTracker/activeEntry.js
Normal file
36
LesionTracker/activeEntry.js
Normal file
@ -0,0 +1,36 @@
|
||||
if (Meteor.isClient){
|
||||
ActiveEntry.configure({
|
||||
logo: {
|
||||
url: '/mini-circles.png',
|
||||
displayed: true
|
||||
},
|
||||
signIn: {
|
||||
displayFullName: true,
|
||||
destination: '/worklist'
|
||||
},
|
||||
signUp: {
|
||||
destination: '/worklist'
|
||||
},
|
||||
themeColors: {
|
||||
primary: 'black'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (Meteor.isServer){
|
||||
Accounts.emailTemplates.siteName = 'AwesomeSite';
|
||||
Accounts.emailTemplates.from = 'AwesomeSite Admin <accounts@example.com>';
|
||||
Accounts.emailTemplates.enrollAccount.subject = function(user) {
|
||||
return 'Welcome to Awesome Town, ' + user.profile.name;
|
||||
};
|
||||
|
||||
Accounts.emailTemplates.enrollAccount.text = function(user, url) {
|
||||
return 'You have been selected to participate in building a better future!'
|
||||
+ ' To activate your account, simply click the link below:\n\n'
|
||||
+ url;
|
||||
};
|
||||
|
||||
Meteor.startup(function() {
|
||||
//process.env.MAIL_URL = 'smtp://sandboxid.mailgun.org:mypassword@smtp.mailgun.org:587';
|
||||
});
|
||||
}
|
||||
@ -5,15 +5,14 @@ Object.keys(ViewerData).forEach(function(contentId) {
|
||||
var tabData = ViewerData[contentId];
|
||||
var data = {
|
||||
title: tabData.title,
|
||||
contentid: tabData.contentid,
|
||||
contentid: tabData.contentid
|
||||
};
|
||||
WorklistTabs.insert(data);
|
||||
});
|
||||
|
||||
Router.configure({
|
||||
layoutTemplate: 'layoutLesionTracker',
|
||||
loadingTemplate: 'layoutLesionTracker',
|
||||
notFoundTemplate: 'notFound'
|
||||
loadingTemplate: 'layoutLesionTracker'
|
||||
});
|
||||
|
||||
Router.onBeforeAction('loading');
|
||||
@ -32,6 +31,10 @@ Router.route('/', function() {
|
||||
this.render('worklist', routerOptions);
|
||||
});
|
||||
|
||||
Router.route('/worklist', function() {
|
||||
this.render('worklist', routerOptions);
|
||||
});
|
||||
|
||||
Router.route('/viewer/:_id', {
|
||||
layoutTemplate: 'layoutLesionTracker',
|
||||
name: 'viewer',
|
||||
|
||||
13
Packages/active-entry/.travis.yml
Executable file
13
Packages/active-entry/.travis.yml
Executable file
@ -0,0 +1,13 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "0.10"
|
||||
#sudo: required
|
||||
|
||||
sudo: required
|
||||
|
||||
env:
|
||||
global:
|
||||
- METEOR_ENV=development
|
||||
|
||||
before_install:
|
||||
- "curl -L http://git.io/ejPSng | /bin/sh"
|
||||
29
Packages/active-entry/Contributing.md
Normal file
29
Packages/active-entry/Contributing.md
Normal file
@ -0,0 +1,29 @@
|
||||
## Contributing
|
||||
|
||||
**Quality Assurance**
|
||||
- Pull Requests will be generally accepted as long as the QA tests pass on [Circle CI](https://circleci.com/gh/clinical-meteor/clinical-active-entry).
|
||||
- Begin a Pull Request by logging an Issue for discussion.
|
||||
- Next, clone the package into a project for local development.
|
||||
- Use ``git checkout -b newfeature`` to create a new branch.
|
||||
- Run the package verification tests to ensure that the test runner works.
|
||||
- Add an it() clause at the bottom of the [activeEntryTests.js](https://github.com/clinical-meteor/clinical-active-entry/blob/master/tests/gagarin/activeEntryTests.js) file for each new feature you wish to implement.
|
||||
- Sketch out a test script for a feature.
|
||||
- Run the verification tests, and confirm that the new test fails.
|
||||
- Update the package with the new feature until the new test passes.
|
||||
- Push the package to the repo on GitHub.
|
||||
- Submit a pull-request.
|
||||
- If the PR passes tests on Circle CI, we'll merge it in!
|
||||
|
||||
**Reference Implementation**
|
||||
- Please see the [ChecklistManifest](http://checklist-manifesto.meteor.com/) and it's [source code](https://github.com/clinical-meteor/checklist-manifesto) for a reference implementation of the ActiveEntry package. It's being built as a workqueue, and is being designed to be FDA, HIPAA, and HL7 FHIR compliant.
|
||||
|
||||
**Feature Toggling**
|
||||
- In general, it's a best practice to implement features that can be enabled/disabled. Some people will want a feature; others will not. The best way to toggle features is adding them to a config file, which is what the [ActiveEntry](https://github.com/clinical-meteor/clinical-active-entry/blob/master/lib/ActiveEntry.js) object is for.
|
||||
- It's recommended that fields be added to the ActiveEntryConfig object that can be used to enabled/disable the feature you are implementing.
|
||||
- The ActiveEntryConfig object can be roughly considered as analogous to the ``props`` field that is passed into React templates.
|
||||
|
||||
**Theming and Styling**
|
||||
- Different apps require different presentation/style layers, so Clinical Meteor has implemented a [Theme](https://github.com/clinical-meteor/clinical-theming/blob/master/objects/Theme.js) object which manages theming. Generally speaking, we're trying to avoid the inclusion of third-party component libraries, UI widgets, and CSS frameworks, and keeping the Clinical Meteor packages as close to the default HTML that Blaze produces as possible (while using line styles for animation effects).
|
||||
- Generally speaking, Bootstrap HTML structure in acceptable in designing pages, but avoid including global CSS files, and keep any CSS locally scoped using LESS nested classes. This approach allows people to add the Bootstrap library if they want it, prevents cascading leaks, and allows more fine-grained control over CSS to implement animation effects.
|
||||
- Pull requests that include visual integration with other projects are acceptable, but please submit an issue for discussion before submitting PRs with wholesale changes that include Jade, Material UI, React, etc.
|
||||
- The ActiveEntry pages are designed to be used in an IronRouter Layout template. As such, no height/width constraints are provided. It's assumed that the layout template will take care of such things. But basic padding/margin is provided.
|
||||
127
Packages/active-entry/README.md
Executable file
127
Packages/active-entry/README.md
Executable file
@ -0,0 +1,127 @@
|
||||
## clinical:active-entry
|
||||
|
||||
This package provides the SignIn, SignUp, and ForgotPassword pages.
|
||||
|
||||
[](https://circleci.com/gh/clinical-meteor/clinical-active-entry/tree/master)
|
||||
|
||||
===============================
|
||||
#### Installation
|
||||
|
||||
````
|
||||
meteor add clinical:active-entry
|
||||
````
|
||||
|
||||
===============================
|
||||
#### Entry Flowchart
|
||||
|
||||
The following diagram represents the entry workflow that is being implemented in this package. This package is under active development, and is about half completed. Pull requests which help implement the following workflow will be fast-tracked and accepted into the package.
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
===============================
|
||||
#### Routing API
|
||||
|
||||
````
|
||||
/entrySignIn
|
||||
/entrySignUp
|
||||
/forgotPassword
|
||||
````
|
||||
|
||||
===============================
|
||||
#### Component API
|
||||
|
||||
````
|
||||
{{> entrySignIn }}
|
||||
{{> entrySignUp }}
|
||||
{{> forgotPassword }}
|
||||
````
|
||||
|
||||
|
||||
===============================
|
||||
#### ActiveEntry Configuration
|
||||
|
||||
````js
|
||||
|
||||
if(Meteor.isClient){
|
||||
ActiveEntry.configure({
|
||||
logo: {
|
||||
url: "/mini-circles.png",
|
||||
displayed: true
|
||||
},
|
||||
signIn: {
|
||||
displayFullName: true,
|
||||
destination: "/table/users"
|
||||
},
|
||||
signUp: {
|
||||
destination: "/table/users"
|
||||
},
|
||||
themeColors: {
|
||||
primary: ""
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if(Meteor.isServer){
|
||||
Accounts.emailTemplates.siteName = "AwesomeSite";
|
||||
Accounts.emailTemplates.from = "AwesomeSite Admin <accounts@example.com>";
|
||||
Accounts.emailTemplates.enrollAccount.subject = function (user) {
|
||||
return "Welcome to Awesome Town, " + user.profile.name;
|
||||
};
|
||||
Accounts.emailTemplates.enrollAccount.text = function (user, url) {
|
||||
return "You have been selected to participate in building a better future!"
|
||||
+ " To activate your account, simply click the link below:\n\n"
|
||||
+ url;
|
||||
};
|
||||
|
||||
Meteor.startup(function(){
|
||||
process.env.MAIL_URL = 'smtp://sandboxid.mailgun.org:mypassword@smtp.mailgun.org:587';
|
||||
})
|
||||
}
|
||||
````
|
||||
Alternatively, you may want to set the ``MAIL_URL`` via an external environment variable, particularly if you're using a SaaS hosting provider.
|
||||
|
||||
````sh
|
||||
MAIL_URL = 'smtp://sandboxid.mailgun.org:mypassword@smtp.mailgun.org:587' meteor
|
||||
````
|
||||
|
||||
===============================
|
||||
#### Local Development
|
||||
|
||||
Simply clone the repository into your ``/packages`` directory. You can also specify the packages you want to develop locally in your ``.git-packages.json`` file, and use starrynight to fetch them.
|
||||
|
||||
````bash
|
||||
# clone a single package into your application
|
||||
git clone http://github.com/clinical-meteor/clinical-active-entry packages/active-entry
|
||||
|
||||
# fetch all the packages listed in git-packages.json
|
||||
starrynight fetch
|
||||
````
|
||||
|
||||
===============================
|
||||
#### Quality Assurance Testing
|
||||
|
||||
There are two types of quality assurance tests you can run: verification and validation tests. Verification tests are similar to unit or integration tests; and can run either at the application or package level. Validation tests are application-wide, but often require commands exposed in packages. So you'll need to run the ``autoconfig`` command to scan the filesystem for validation commands. See [http://starrynight.meteor.com/](http://starrynight.meteor.com/) for more details.
|
||||
|
||||
````bash
|
||||
# install the testing utility
|
||||
npm install -g starrynight
|
||||
|
||||
# verification testing (a.k.a. package-level unit/integration testing)
|
||||
starrynight run-tests --type package-verification
|
||||
|
||||
#validation testing (a.k.a. application acceptance/end-to-end testing)
|
||||
starrynight autoscan
|
||||
starrynight run-tests --type validation
|
||||
````
|
||||
|
||||
===============================
|
||||
#### Contributing
|
||||
|
||||
See our [notes on contributing](https://github.com/clinical-meteor/clinical-active-entry/blob/master/Contributing.md).
|
||||
|
||||
===============================
|
||||
#### Licensing
|
||||
|
||||

|
||||
61
Packages/active-entry/circle.yml
Normal file
61
Packages/active-entry/circle.yml
Normal file
@ -0,0 +1,61 @@
|
||||
## Customize the test machine
|
||||
machine:
|
||||
|
||||
# Timezone
|
||||
timezone:
|
||||
America/Los_Angeles # Set the timezone
|
||||
|
||||
# Add some environment variables
|
||||
environment:
|
||||
CIRCLE_ENV: test
|
||||
CXX: g++-4.8
|
||||
DISPLAY: :99.0
|
||||
NPM_PREFIX: /home/ubuntu/nvm/v0.10.33
|
||||
|
||||
|
||||
## Customize checkout
|
||||
checkout:
|
||||
post:
|
||||
#- git submodule sync
|
||||
#- git submodule update --init --recursive # use submodules
|
||||
|
||||
#general:
|
||||
# build_dir: helloworld
|
||||
|
||||
## Customize dependencies
|
||||
dependencies:
|
||||
cache_directories:
|
||||
- "~/.meteor" # relative to the user's home directory
|
||||
|
||||
override:
|
||||
- meteor || curl https://install.meteor.com | /bin/sh
|
||||
- npm install starrynight -g
|
||||
- meteor create --release METEOR@1.1.0.3 helloworld
|
||||
- cd helloworld
|
||||
- cd helloworld && ls -la
|
||||
- cd helloworld && rm helloworld.*
|
||||
- cd helloworld && meteor add anti:gagarin@0.4.11 accounts-base accounts-password session meteor-platform clinical:active-entry clinical:user-model
|
||||
- cd helloworld && git clone http://github.com/clinical-meteor/clinical-active-entry packages/active-entry
|
||||
- cd helloworld && starrynight autoconfig
|
||||
|
||||
## Customize test commands
|
||||
test:
|
||||
pre:
|
||||
- cd helloworld && meteor:
|
||||
background: true
|
||||
- sleep 80
|
||||
override:
|
||||
- cd helloworld && starrynight run-tests --type package-verification
|
||||
|
||||
## Customize deployment commands
|
||||
#deployment:
|
||||
# production:
|
||||
# branch: master
|
||||
# commands:
|
||||
# - printf "<Meteor username>\n<Meteor password>\n" | meteor deploy circlecivelocity.meteor.com
|
||||
|
||||
## Custom notifications
|
||||
#notify:
|
||||
#webhooks:
|
||||
# A list of hashes representing hooks. Only the url field is supported.
|
||||
#- url: https://someurl.com/hooks/circle
|
||||
52
Packages/active-entry/components/entryPages.js
Executable file
52
Packages/active-entry/components/entryPages.js
Executable file
@ -0,0 +1,52 @@
|
||||
|
||||
/**
|
||||
* @summary Determines if a block of code should be displayed based on whether the logo is set to be displayed.
|
||||
* @locus Client
|
||||
* @memberOf Entry
|
||||
* @name {{logoIsDisplayed}}
|
||||
* @version 1.2.3
|
||||
* @returns {Boolean}
|
||||
* @example
|
||||
* ```html
|
||||
* {{#if logoIsDisplayed}}
|
||||
* <div class="entryLogo" style="background-image: url('{{logoUrl}}')"></div>
|
||||
* {{/if}}
|
||||
* ```
|
||||
*/
|
||||
Template.registerHelper("logoIsDisplayed", function (argument){
|
||||
var config = Session.get('Photonic.ActiveEntry');
|
||||
if(config && config.logo && config.logo.displayed){
|
||||
return config.logo.displayed;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* @summary Retruns the Url of the logo asset.
|
||||
* @locus Client
|
||||
* @memberOf Entry
|
||||
* @name {{logoUrl}}
|
||||
* @version 1.2.3
|
||||
* @returns {String}
|
||||
* @example
|
||||
* ```html
|
||||
* {{#if logoIsDisplayed}}
|
||||
* <div class="entryLogo" style="background-image: url('{{logoUrl}}')"></div>
|
||||
* {{/if}}
|
||||
* ```
|
||||
*/
|
||||
Template.registerHelper("logoUrl", function (argument){
|
||||
var config = Session.get('Photonic.ActiveEntry');
|
||||
if(config && config.logo && config.logo.url){
|
||||
return config.logo.url;
|
||||
}else{
|
||||
return "";
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Template.registerHelper("getButtonColor", function (argument){
|
||||
return "background-color: " + Theme.getPaletteColor("colorB") + "; ";
|
||||
});
|
||||
168
Packages/active-entry/components/entryPages.less
Executable file
168
Packages/active-entry/components/entryPages.less
Executable file
@ -0,0 +1,168 @@
|
||||
// @import 'client/app/stylesheets/util/reset.lessimport';
|
||||
// @import 'client/app/stylesheets/util/lesshat.lessimport';
|
||||
// @import 'client/app/stylesheets/util/typography.lessimport';
|
||||
|
||||
|
||||
// this probably wants to be moved into clinical:glass-ui
|
||||
input, button, select{
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
font-family: 'Open Sans', "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-style: 400;
|
||||
padding: .75rem 0;
|
||||
line-height: 1.5rem !important;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
box-sizing: border-box;
|
||||
//color: #333333;
|
||||
outline: none;
|
||||
padding-left: 3em;
|
||||
}
|
||||
|
||||
|
||||
.entryLogo{
|
||||
//background-color: lightgray;
|
||||
height: 200px;
|
||||
width: 200px;
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.btn-primary{
|
||||
background-color: forestgreen;
|
||||
color: #ffffff;
|
||||
}
|
||||
.btn-gray{
|
||||
background-color: #aaaaaa;
|
||||
color: white;
|
||||
}
|
||||
.btn-main{
|
||||
font-weight: 300;
|
||||
letter-spacing: 3px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.input-symbol {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.entryPage {
|
||||
text-align: center;
|
||||
|
||||
input, button{
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.fa{
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
padding-left: 15px;
|
||||
padding-top: 14px;
|
||||
}
|
||||
|
||||
.checkmarkIcon{
|
||||
position: absolute;
|
||||
color: #831d2c;
|
||||
}
|
||||
.btn-gray{
|
||||
width: 100%;
|
||||
}
|
||||
.checkmarkTitle{
|
||||
padding-bottom: 100px;
|
||||
}
|
||||
.fa{
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
padding-left: 15px;
|
||||
padding-top: 16px;
|
||||
// color: #555555;
|
||||
}
|
||||
|
||||
.wrapper-auth {
|
||||
//padding-top: 4em;
|
||||
|
||||
@media screen and (min-width: 40em) {
|
||||
margin: 0 auto;
|
||||
max-width: 480px;
|
||||
width: 80%;
|
||||
}
|
||||
@media screen and (max-width: 480px) {
|
||||
margin: 0 auto;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
// .input-symbol{
|
||||
// border: 1px solid gray;
|
||||
// }
|
||||
|
||||
.title-auth {
|
||||
color: black;
|
||||
margin-bottom: .75rem;
|
||||
}
|
||||
|
||||
.subtitle-auth {
|
||||
color: black;
|
||||
//margin: 0 15% 3rem;
|
||||
margin-bottom: 2rem;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
form {
|
||||
input{
|
||||
color: #333333;
|
||||
height: 48px;
|
||||
border-left: solid 1px !important;
|
||||
}
|
||||
.input-symbol {
|
||||
margin-bottom: 1px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
//margin: 1em 5% 0;
|
||||
//width: 90%;
|
||||
margin-top: 1em;
|
||||
|
||||
@media screen and (min-width: 40em) {
|
||||
// margin-left: 0;
|
||||
// margin-right: 0;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.list-errors {
|
||||
margin-top: -2rem;
|
||||
.taskItems {
|
||||
//.title-caps;
|
||||
background: white;
|
||||
color: red;
|
||||
font-size: .625em; // 10px
|
||||
margin-bottom: 1px;
|
||||
padding: .7rem 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.link-auth-alt {
|
||||
//.font-s1;
|
||||
//.position(absolute, auto, 0, 1em, 0);
|
||||
color: black;
|
||||
display: inline-block;
|
||||
|
||||
@media screen and (min-width: 40em) {
|
||||
bottom: 0;
|
||||
margin-top: 1rem;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
// @media only screen and (max-width: 704px) {
|
||||
// .fa{
|
||||
// left: 5%;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
10
Packages/active-entry/components/entrySignIn/.tests/actions/meteorLogout.js
Executable file
10
Packages/active-entry/components/entrySignIn/.tests/actions/meteorLogout.js
Executable file
@ -0,0 +1,10 @@
|
||||
|
||||
|
||||
exports.command = function () {
|
||||
this
|
||||
.execute(function () {
|
||||
return Meteor.logout();
|
||||
}).pause(1000);
|
||||
|
||||
return this;
|
||||
};
|
||||
23
Packages/active-entry/components/entrySignIn/.tests/actions/signIn.js
Executable file
23
Packages/active-entry/components/entrySignIn/.tests/actions/signIn.js
Executable file
@ -0,0 +1,23 @@
|
||||
exports.command = function (email, password) {
|
||||
|
||||
this.verify.elementPresent("#entrySignIn");
|
||||
|
||||
if (email) {
|
||||
this
|
||||
.verify.elementPresent("#signInPageEmailInput")
|
||||
.clearValue("#signInPageEmailInput")
|
||||
.setValue("#signInPageEmailInput", email);
|
||||
}
|
||||
|
||||
|
||||
if (password) {
|
||||
this
|
||||
.verify.elementPresent("#signInPagePasswordInput")
|
||||
.clearValue("#signInPagePasswordInput")
|
||||
.setValue("#signInPagePasswordInput", password);
|
||||
}
|
||||
|
||||
this.click("#signInToAppButton").pause(1000);
|
||||
|
||||
return this;
|
||||
};
|
||||
22
Packages/active-entry/components/entrySignIn/.tests/actions/signOut.js
Executable file
22
Packages/active-entry/components/entrySignIn/.tests/actions/signOut.js
Executable file
@ -0,0 +1,22 @@
|
||||
exports.command = function (fullname) {
|
||||
this
|
||||
.sectionBreak(".signOut()");
|
||||
|
||||
if (fullname) {
|
||||
this
|
||||
.verify.elementPresent("#usernameLink")
|
||||
.verify.containsText("#usernameLink", fullname);
|
||||
}
|
||||
|
||||
this
|
||||
.verify.elementPresent("#logoutLink")
|
||||
.click("#logoutLink").pause(1000);
|
||||
|
||||
if (fullname) {
|
||||
this
|
||||
.verify.elementPresent("#usernameLink")
|
||||
.verify.containsText("#usernameLink", "Sign In");
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
35
Packages/active-entry/components/entrySignIn/.tests/reviewSignIn.js
Executable file
35
Packages/active-entry/components/entrySignIn/.tests/reviewSignIn.js
Executable file
@ -0,0 +1,35 @@
|
||||
exports.command = function (email, password, title, message) {
|
||||
this
|
||||
// .verify.element("#entrySignIn").to.be.visible
|
||||
// .verify.element("#signInPageTitle").to.be.visible
|
||||
// .verify.element("#signInPageMessage").to.be.visible
|
||||
// .verify.element("#signInPageEmailInput").to.be.visible
|
||||
// .verify.element("#signInPagePasswordInput").to.be.visible
|
||||
// .verify.element("#signInToAppButton").to.be.visible
|
||||
// .verify.element("#needAnAccountButton").to.be.visible
|
||||
//
|
||||
|
||||
.verify.elementPresent("#entrySignIn")
|
||||
.verify.elementPresent("#signInPageTitle")
|
||||
.verify.elementPresent("#signInPageMessage")
|
||||
.verify.elementPresent("#signInPageEmailInput")
|
||||
.verify.elementPresent("#signInPagePasswordInput")
|
||||
.verify.elementPresent("#signInToAppButton")
|
||||
.verify.elementPresent("#needAnAccountButton");
|
||||
|
||||
if (email) {
|
||||
this.verify.containsText("#signInPageEmailInput", email);
|
||||
}
|
||||
if (password) {
|
||||
this.verify.containsText("#signInPageEmailInput", password);
|
||||
}
|
||||
|
||||
if (title) {
|
||||
this.verify.containsText("#signInPageTitle", title);
|
||||
}
|
||||
if (message) {
|
||||
this.verify.containsText("#signInPageMessage", message);
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
46
Packages/active-entry/components/entrySignIn/entrySignIn.html
Executable file
46
Packages/active-entry/components/entrySignIn/entrySignIn.html
Executable file
@ -0,0 +1,46 @@
|
||||
<template name="entrySignIn">
|
||||
<div id="entrySignIn" class="page entryPage" style="{{getOpacityWithCorner}}">
|
||||
|
||||
<div class="content-scrollable">
|
||||
<div class="wrapper-auth">
|
||||
{{#if logoIsDisplayed}}
|
||||
<div id="entryAppLogo" class="entryLogo" style="background-image: url('{{logoUrl}}')"></div>
|
||||
{{/if}}
|
||||
|
||||
{{#if isLoggedIn}}
|
||||
<h1 id="signInPageTitle" class="title-auth">{{fullName}}</h1>
|
||||
<div id="signInPageMessage" class="subtitle-auth">You are currently signed in.</div>
|
||||
|
||||
<button id="logoutButton" class="btn-primary btn-main btn-large" style="{{getButtonColor}}">Logout</button>
|
||||
{{else}}
|
||||
<h1 id="signInPageTitle" class="title-auth">Sign In.</h1>
|
||||
<p id="signInPageMessage" class="subtitle-auth" style="{{getSignInMessageColor}}">{{getSignInMessage}}</p>
|
||||
|
||||
<form>
|
||||
<div class="input-symbol">
|
||||
<input id="signInPageEmailInput" type="text" name="email" placeholder="Your Email" style="{{getEmailValidationStyling}}" />
|
||||
<i class="fa fa-envelope-o" title="Your Email"></i>
|
||||
</div>
|
||||
<br><br>
|
||||
|
||||
<div class="input-symbol">
|
||||
<input id="signInPagePasswordInput" type="password" name="password" placeholder="Password" style={{getPasswordValidationStyling}} />
|
||||
<span class="fa fa-lock" title="Password"></span>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<br><br>
|
||||
<button id="signInToAppButton" class="btn-primary btn-main btn-large" style="{{getButtonColor}}">{{getButtonText}}</button>
|
||||
|
||||
<br><br>
|
||||
<button id="needAnAccountButton" class="btn-gray btn-main btn-large">Need an account?</button>
|
||||
|
||||
<br><br>
|
||||
<button id="forgotPasswordButton" class="btn-gray btn-main btn-large">Forgot password?</button>
|
||||
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
131
Packages/active-entry/components/entrySignIn/entrySignIn.js
Executable file
131
Packages/active-entry/components/entrySignIn/entrySignIn.js
Executable file
@ -0,0 +1,131 @@
|
||||
|
||||
// REFACTOR: Move to ActiveRecord object
|
||||
Session.set("defaultSignInMessage", "Improve your clinical practice with checklists.");
|
||||
|
||||
//==================================================================================================
|
||||
// ROUTER
|
||||
|
||||
Router.route('/entrySignIn', {
|
||||
template: 'entrySignIn',
|
||||
name: 'entrySignIn'
|
||||
});
|
||||
Router.route('/sign-in', {
|
||||
template: 'entrySignIn',
|
||||
name: 'signInRoute'
|
||||
});
|
||||
|
||||
//==================================================================================================
|
||||
// COMPONENT OUTPUTS
|
||||
|
||||
|
||||
|
||||
|
||||
Template.entrySignIn.helpers({
|
||||
getSignInMessageColor: function (){
|
||||
if (ActiveEntry.errorMessages.get('signInError')) {
|
||||
return "color: #a94442; background-color: #f2dede; border-color: #ebccd1;"
|
||||
} else {
|
||||
return "color: black;"
|
||||
}
|
||||
},
|
||||
getSignInMessage: function (){
|
||||
if (ActiveEntry.errorMessages.get('signInError')) {
|
||||
return ActiveEntry.errorMessages.get('signInError');
|
||||
} else {
|
||||
return Session.get('defaultSignInMessage');
|
||||
}
|
||||
},
|
||||
getButtonText: function () {
|
||||
return "Sign In";
|
||||
// if (ActiveEntry.errorMessages.get('signInError')){
|
||||
// return ActiveEntry.errorMessages.get('signInError');
|
||||
// } else {
|
||||
// return "Sign In";
|
||||
// }
|
||||
},
|
||||
getEmailValidationStyling: function () {
|
||||
if (ActiveEntry.errorMessages.equals('email', "Email is required")) {
|
||||
return "border: 1px solid #a94442";
|
||||
} else if (ActiveEntry.errorMessages.equals('email', "Email is poorly formatted")) {
|
||||
return "border: 1px solid #f2dede";
|
||||
} else if (ActiveEntry.errorMessages.equals('email', "Email present")) {
|
||||
return "border: 1px solid green";
|
||||
} else {
|
||||
return "border: 1px solid gray";
|
||||
}
|
||||
},
|
||||
getPasswordValidationStyling: function () {
|
||||
if (ActiveEntry.errorMessages.equals('password', "Password is required")) {
|
||||
return "border: 1px solid #a94442";
|
||||
} else if (ActiveEntry.errorMessages.equals('password', "Password is weak")) {
|
||||
return "border: 1px solid #f2dede";
|
||||
} else if (ActiveEntry.errorMessages.equals('password', "Password present")) {
|
||||
return "border: 1px solid green";
|
||||
} else {
|
||||
return "border: 1px solid gray";
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
// COMPONENT OUTPUTS
|
||||
|
||||
Template.entrySignIn.events({
|
||||
'click #logoutButton': function () {
|
||||
Meteor.logout();
|
||||
},
|
||||
'click #forgotPasswordButton': function (event) {
|
||||
event.preventDefault();
|
||||
Router.go('/forgotPassword');
|
||||
},
|
||||
"click #needAnAccountButton": function (event) {
|
||||
event.preventDefault();
|
||||
Router.go('/entrySignUp');
|
||||
},
|
||||
'keyup input[name="email"]': function (event, template) {
|
||||
var email = $('input[name="email"]').val();
|
||||
|
||||
ActiveEntry.verifyEmail(email);
|
||||
ActiveEntry.errorMessages.set('signInError', null);
|
||||
},
|
||||
'change input[name="email"]': function (event, template) {
|
||||
var email = $('input[name="email"]').val();
|
||||
|
||||
ActiveEntry.verifyEmail(email);
|
||||
ActiveEntry.errorMessages.set('signInError', null);
|
||||
},
|
||||
'keyup #signInPagePasswordInput': function (event, template) {
|
||||
var password = $('input[name="password"]').val();
|
||||
|
||||
ActiveEntry.verifyPassword(password);
|
||||
ActiveEntry.errorMessages.set('signInError', null);
|
||||
},
|
||||
'change #signInPagePasswordInput': function (event, template) {
|
||||
var password = $('input[name="password"]').val();
|
||||
|
||||
ActiveEntry.verifyPassword(password);
|
||||
ActiveEntry.errorMessages.set('signInError', null);
|
||||
},
|
||||
// 'submit': function (event, template) {
|
||||
// event.preventDefault();
|
||||
// var emailValue = template.$('[name=email]').val();
|
||||
// var passwordValue = template.$('[name=password]').val();
|
||||
//
|
||||
// ActiveEntry.signIn(emailValue, passwordValue);
|
||||
// },
|
||||
'click #signInToAppButton': function (event, template){
|
||||
console.log('click #signInToAppButton');
|
||||
// var emailValue = template.$('[name=email]').val();
|
||||
// var passwordValue = template.$('[name=password]').val();
|
||||
var emailValue = template.$('#signInPageEmailInput').val();
|
||||
var passwordValue = template.$('#signInPagePasswordInput').val();
|
||||
|
||||
ActiveEntry.signIn(emailValue, passwordValue);
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
17
Packages/active-entry/components/entrySignIn/entrySignIn.less
Executable file
17
Packages/active-entry/components/entrySignIn/entrySignIn.less
Executable file
@ -0,0 +1,17 @@
|
||||
#entrySignIn{
|
||||
padding: 40px;
|
||||
input{
|
||||
padding-left: 40px;
|
||||
color: #333333 !important;
|
||||
}
|
||||
#errorMessages{
|
||||
padding-top: .5rem;
|
||||
padding-bottom: .5rem;
|
||||
font-size: 14px;
|
||||
box-sizing: border-box;
|
||||
width: 100.5%;
|
||||
margin-bottom: 15px;
|
||||
color: red;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
// async version calls method on the server
|
||||
exports.command = function () {
|
||||
var client = this;
|
||||
|
||||
this
|
||||
.timeoutsAsyncScript(5000)
|
||||
.executeAsync(function (data, meteorCallback) {
|
||||
//return HipaaLogger.logEventObject(data);
|
||||
Meteor.call("dropEntryUsers", data, function (meteorError, meteorResult) {
|
||||
var response = (meteorError ? {
|
||||
error: meteorError
|
||||
} : {
|
||||
result: meteorResult
|
||||
});
|
||||
meteorCallback(response);
|
||||
});
|
||||
}, [], function (result) {
|
||||
//console.log("result.value", result.value);
|
||||
//client.assert.ok(result.value);
|
||||
}).pause(1000);
|
||||
return this;
|
||||
};
|
||||
@ -0,0 +1,11 @@
|
||||
|
||||
// resetEntry.js
|
||||
exports.command = function () {
|
||||
|
||||
this
|
||||
.timeoutsAsyncScript(5000)
|
||||
.executeAsync(function (data, meteorCallback) {
|
||||
ActiveEntry.reset();
|
||||
}, []).pause(1000);
|
||||
return this;
|
||||
};
|
||||
37
Packages/active-entry/components/entrySignUp/.tests/actions/signUp.js
Executable file
37
Packages/active-entry/components/entrySignUp/.tests/actions/signUp.js
Executable file
@ -0,0 +1,37 @@
|
||||
exports.command = function (email, password, fullName) {
|
||||
|
||||
this.verify.elementPresent("#entrySignUp");
|
||||
|
||||
if (email) {
|
||||
this
|
||||
.verify.elementPresent("#signUpPageEmailInput")
|
||||
.clearValue("#signUpPageEmailInput")
|
||||
.setValue("#signUpPageEmailInput", email);
|
||||
}
|
||||
|
||||
|
||||
if (password) {
|
||||
this
|
||||
.verify.elementPresent("#signUpPagePasswordInput")
|
||||
.clearValue("#signUpPagePasswordInput")
|
||||
.setValue("#signUpPagePasswordInput", password)
|
||||
|
||||
.verify.elementPresent("#signUpPagePasswordConfirmInput")
|
||||
.clearValue("#signUpPagePasswordConfirmInput")
|
||||
.setValue("#signUpPagePasswordConfirmInput", password);
|
||||
}
|
||||
|
||||
|
||||
if (fullName) {
|
||||
this
|
||||
.verify.elementPresent("#signUpPageFullNameInput")
|
||||
.clearValue("#signUpPageFullNameInput")
|
||||
.setValue("#signUpPageFullNameInput", fullName);
|
||||
}
|
||||
|
||||
|
||||
this.click("#signUpPageJoinNowButton").pause(300);
|
||||
|
||||
|
||||
return this;
|
||||
};
|
||||
31
Packages/active-entry/components/entrySignUp/.tests/reviewSignUp.js
Executable file
31
Packages/active-entry/components/entrySignUp/.tests/reviewSignUp.js
Executable file
@ -0,0 +1,31 @@
|
||||
exports.command = function (email, password, fullName, message) {
|
||||
this
|
||||
.verify.elementPresent("#entrySignUp")
|
||||
.verify.elementPresent("#signUpPageTitle")
|
||||
.verify.elementPresent("#signUpPageMessage")
|
||||
.verify.elementPresent("#signUpPageFullNameInput")
|
||||
.verify.elementPresent("#signUpPageEmailInput")
|
||||
.verify.elementPresent("#signUpPagePasswordInput")
|
||||
.verify.elementPresent("#signUpPagePasswordConfirmInput")
|
||||
|
||||
.verify.elementPresent("#signUpPageJoinNowButton")
|
||||
.verify.elementPresent("#signUpPageSignInButton");
|
||||
|
||||
if (email) {
|
||||
this.verify.containsText("#signUpPageEmailInput", email);
|
||||
}
|
||||
if (password) {
|
||||
this.verify.containsText("#signUpPagePasswordInput", password)
|
||||
.verify.containsText("#signUpPagePasswordConfirmInput", password);
|
||||
}
|
||||
if (fullName) {
|
||||
this.verify.containsText("#signUpPageFullNameInput", fullName);
|
||||
}
|
||||
if (message) {
|
||||
this.verify.elementPresent("#errorMessages")
|
||||
.verify.containsText("#errorMessages", message);
|
||||
}
|
||||
|
||||
|
||||
return this;
|
||||
};
|
||||
63
Packages/active-entry/components/entrySignUp/entrySignUp.html
Executable file
63
Packages/active-entry/components/entrySignUp/entrySignUp.html
Executable file
@ -0,0 +1,63 @@
|
||||
<template name="entrySignUp">
|
||||
<div id="entrySignUp" class="page entryPage" style="{{getOpacityWithCorner}}">
|
||||
|
||||
<div class="content-scrollable">
|
||||
<div class="wrapper-auth">
|
||||
{{#if logoIsDisplayed}}
|
||||
<div id="entryAppLogo" class="entryLogo" style="background-image: url('{{logoUrl}}')"></div>
|
||||
{{/if}}
|
||||
|
||||
<h1 id="signUpPageTitle" class="title-auth">Join.</h1>
|
||||
<div id="signUpPageMessage" class="subtitle-auth" style="{{getSignUpMessageColor}}">{{getSignUpMessage}}</div>
|
||||
|
||||
<form>
|
||||
{{#if errorMessages}}
|
||||
<div id="errorMessages" class="list-errors">
|
||||
{{#each errorMessages}}
|
||||
<div class="alert alert-danger list-item">{{this}}</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="input-symbol ">
|
||||
<input id="signUpPageFullNameInput" type="text" name="fullName" placeholder="Full Name" style="{{getFullNameStyling}}" />
|
||||
<i class="fa fa-user" title="Full Name"></i>
|
||||
</div>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
<div class="input-symbol">
|
||||
<input id="signUpPageEmailInput" type="email" name="email" placeholder="Email Address" style="{{getEmailStyling}}" />
|
||||
<i class="fa fa-envelope-o" title="Your Email"></i>
|
||||
</div>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
<div class="input-symbol ">
|
||||
<input id="signUpPagePasswordInput" type="password" name="password" placeholder="Password" style="{{getPasswordStyling}}" />
|
||||
<span class="fa fa-lock" title="Password"></span>
|
||||
<!-- <span class="icon-lock" title="Password"></span> -->
|
||||
</div>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
<div class="input-symbol">
|
||||
<input id="signUpPagePasswordConfirmInput" type="password" name="confirm" placeholder="Confirm Password" style="{{getConfirmPasswordStyling}}" />
|
||||
<span class="fa fa-lock" title="Confirm Password"></span>
|
||||
<!-- <span class="icon-lock" title="Confirm Password"></span> -->
|
||||
</div>
|
||||
</form>
|
||||
<br>
|
||||
<br>
|
||||
<button id="signUpPageJoinNowButton" type="submit" class="btn-primary btn-main btn-large" style="{{getButtonColor}}">Join Now</button>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
<button id="signUpPageSignInButton" class="btn-gray btn-main btn-large">Have an account? Sign in</button>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- <a id="signUpPageSignInButton" href="{{pathFor 'entrySignIn'}}" class="link-auth-alt">Have an account? Sign in</a> -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
139
Packages/active-entry/components/entrySignUp/entrySignUp.js
Executable file
139
Packages/active-entry/components/entrySignUp/entrySignUp.js
Executable file
@ -0,0 +1,139 @@
|
||||
//==================================================================================================
|
||||
// ROUTER
|
||||
|
||||
Router.route('/entrySignUp', {
|
||||
template: 'entrySignUp',
|
||||
name: 'entrySignUp'
|
||||
});
|
||||
Router.route('/sign-up', {
|
||||
template: 'entrySignUp',
|
||||
name: 'signUpRoute'
|
||||
});
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
|
||||
|
||||
Template.entrySignUp.helpers({
|
||||
getSignUpMessageColor: function (){
|
||||
if (ActiveEntry.errorMessages.get('signInError')) {
|
||||
return "color: #a94442; background-color: #f2dede; border-color: #ebccd1;"
|
||||
} else {
|
||||
return "color: black;"
|
||||
}
|
||||
},
|
||||
getSignUpMessage: function (){
|
||||
if (ActiveEntry.errorMessages.get('signInError')) {
|
||||
return ActiveEntry.errorMessages.get('signInError');
|
||||
} else {
|
||||
return Session.get('defaultSignInMessage');
|
||||
}
|
||||
},
|
||||
getButtonText: function () {
|
||||
if (ActiveEntry.errorMessages.get('signInError')) {
|
||||
return ActiveEntry.errorMessages.get('signInError').message;
|
||||
} else {
|
||||
return "Sign In";
|
||||
}
|
||||
},
|
||||
getEmailStyling: function () {
|
||||
if (ActiveEntry.errorMessages.equals('email', "Email is required")) {
|
||||
return "border: 1px solid #a94442";
|
||||
} else if (ActiveEntry.errorMessages.equals('email', "Email is poorly formatted")) {
|
||||
return "border: 1px solid #f2dede";
|
||||
} else if (ActiveEntry.errorMessages.equals('email', "Email present")) {
|
||||
return "border: 1px solid green";
|
||||
} else {
|
||||
return "border: 1px solid gray";
|
||||
}
|
||||
},
|
||||
getPasswordStyling: function () {
|
||||
if (ActiveEntry.errorMessages.equals('password', "Password is required")) {
|
||||
return "border: 1px solid #a94442";
|
||||
} else if (ActiveEntry.errorMessages.equals('password', "Password is weak")) {
|
||||
return "border: 1px solid #f2dede";
|
||||
} else if (ActiveEntry.errorMessages.equals('password', "Password present")) {
|
||||
return "border: 1px solid green";
|
||||
} else {
|
||||
return "border: 1px solid gray";
|
||||
}
|
||||
},
|
||||
getConfirmPasswordStyling: function () {
|
||||
if (ActiveEntry.errorMessages.equals('confirm', "Password is required")) {
|
||||
return "border: 1px solid #a94442";
|
||||
} else if (ActiveEntry.errorMessages.equals('confirm', "Password is weak")) {
|
||||
return "border: 1px solid #f2dede";
|
||||
} else if (ActiveEntry.errorMessages.equals('confirm', "Passwords match")) {
|
||||
return "border: 1px solid green";
|
||||
} else {
|
||||
return "border: 1px solid gray";
|
||||
}
|
||||
},
|
||||
getFullNameStyling: function () {
|
||||
if (ActiveEntry.errorMessages.equals('fullName', "Name is required")) {
|
||||
return "border: 1px solid #a94442";
|
||||
} else if (ActiveEntry.errorMessages.equals('fullName', "Name is probably not complete")) {
|
||||
return "border: 1px solid #f2dede";
|
||||
} else if (ActiveEntry.errorMessages.equals('fullName', "Name present")) {
|
||||
return "border: 1px solid green";
|
||||
} else {
|
||||
return "border: 1px solid gray";
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Template.entrySignUp.events({
|
||||
"click #signUpPageSignInButton": function (event) {
|
||||
event.preventDefault();
|
||||
Router.go('/entrySignIn');
|
||||
},
|
||||
'change, keyup #signUpPageEmailInput': function (event, template) {
|
||||
var email = $('[name="email"]').val();
|
||||
|
||||
ActiveEntry.verifyEmail(email);
|
||||
ActiveEntry.errorMessages.set('signInError', null);
|
||||
},
|
||||
'change, keyup #signUpPagePasswordInput': function (event, template) {
|
||||
var password = $('[name="password"]').val();
|
||||
|
||||
ActiveEntry.verifyPassword(password);
|
||||
ActiveEntry.errorMessages.set('signInError', null);
|
||||
},
|
||||
'change, keyup #signUpPagePasswordConfirmInput': function (event, template) {
|
||||
|
||||
var password = $('[name="password"]').val();
|
||||
var confirmPassword = $('[name="confirm"]').val();
|
||||
// var password = $('#signUpPagePasswordInput').val();
|
||||
// var confirmPassword = $('#signUpPagePasswordConfirmInput').val();
|
||||
|
||||
ActiveEntry.verifyConfirmPassword(password, confirmPassword);
|
||||
ActiveEntry.errorMessages.set('signInError', null);
|
||||
},
|
||||
'change, keyup #signUpPageFullNameInput': function (event, template) {
|
||||
var fullName = template.$('[name="fullName"]').val();
|
||||
|
||||
ActiveEntry.verifyFullName(fullName);
|
||||
ActiveEntry.errorMessages.set('signInError', null);
|
||||
},
|
||||
// TODO: this is outdated, and should be changed to match the signature/pattern in entrySignIn
|
||||
'click #signUpPageJoinNowButton': function (event, template) {
|
||||
event.preventDefault();
|
||||
|
||||
ActiveEntry.errorMessages.set('signInError', null);
|
||||
ActiveEntry.verifyPassword(event, template);
|
||||
|
||||
var newUser = {
|
||||
fullName: template.$('[name="fullName"]').val(),
|
||||
email: template.$('[name="email"]').val(),
|
||||
password: template.$('[name="password"]').val(),
|
||||
confirm: template.$('[name="confirm"]').val()
|
||||
};
|
||||
|
||||
ActiveEntry.signUp(
|
||||
newUser.email,
|
||||
newUser.password,
|
||||
newUser.confirm,
|
||||
newUser.fullName
|
||||
);
|
||||
}
|
||||
});
|
||||
7
Packages/active-entry/components/entrySignUp/entrySignUp.less
Executable file
7
Packages/active-entry/components/entrySignUp/entrySignUp.less
Executable file
@ -0,0 +1,7 @@
|
||||
#entrySignUp{
|
||||
padding: 40px;
|
||||
input{
|
||||
padding-left: 40px !important;
|
||||
color: black;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
exports.command = function () {
|
||||
this
|
||||
.verify.elementPresent("#forgotPassword"); return this;
|
||||
};
|
||||
24
Packages/active-entry/components/forgotPassword/forgotPassword.html
Executable file
24
Packages/active-entry/components/forgotPassword/forgotPassword.html
Executable file
@ -0,0 +1,24 @@
|
||||
<template name="forgotPassword">
|
||||
<div id="forgotPassword" class="page entryPage" style="{{getOpacityWithCorner}}">
|
||||
<div class="content-scrollable">
|
||||
<div class="wrapper-auth">
|
||||
<div class="entryLogo" style="background-image: url('{{getLogoUrl}}')"></div>
|
||||
|
||||
<h1 id="signInPageTitle" class="title-auth">Forgot Password</h1>
|
||||
<div id="signInPageMessage" class="subtitle-auth" >Imdivrove your clincal practice with checklists.</div>
|
||||
|
||||
<form>
|
||||
<div class="input-symbol">
|
||||
<input id="signInPageEmailInput" type="email" name="email" placeholder="Your Email" style="{{getForgotPasswordStyle}}" />
|
||||
<i class="fa fa-envelope-o" title="Your Email"></i>
|
||||
</div>
|
||||
<br><br>
|
||||
|
||||
<button id="sendReminderButton" type="submit" class="btn-gray btn-main btn-large" style="{{getButtonColor}}">Send Reminder</button><br><br>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
22
Packages/active-entry/components/forgotPassword/forgotPassword.js
Executable file
22
Packages/active-entry/components/forgotPassword/forgotPassword.js
Executable file
@ -0,0 +1,22 @@
|
||||
//==========================================
|
||||
|
||||
Router.route('/forgotPassword', {
|
||||
name: "forgotPassword",
|
||||
template: "forgotPassword"
|
||||
});
|
||||
|
||||
|
||||
Template.forgotPassword.helpers({
|
||||
getForgotPasswordStyle: function (){
|
||||
return "border: 1px solid gray";
|
||||
}
|
||||
});
|
||||
|
||||
Template.forgotPassword.events({
|
||||
"submit": function (event, template) {
|
||||
event.preventDefault();
|
||||
|
||||
console.log('send reminder!');
|
||||
Accounts.forgotPassword({email: $('#signInPageEmailInput').val()});
|
||||
}
|
||||
});
|
||||
5
Packages/active-entry/components/forgotPassword/forgotPassword.less
Executable file
5
Packages/active-entry/components/forgotPassword/forgotPassword.less
Executable file
@ -0,0 +1,5 @@
|
||||
#forgotPassword{
|
||||
input{
|
||||
padding-left: 40px;
|
||||
}
|
||||
}
|
||||
48
Packages/active-entry/lib/Accounts.js
Executable file
48
Packages/active-entry/lib/Accounts.js
Executable file
@ -0,0 +1,48 @@
|
||||
|
||||
|
||||
if (Meteor.isClient) {
|
||||
|
||||
|
||||
Accounts.onResetPasswordLink(function (token, done){
|
||||
console.log('Accounts.onResearchPasswordLink');
|
||||
console.log('Sending reset password email...');
|
||||
console.log('NOT IMPLEMENTED YET. PLEASE LOG AN ISSUE');
|
||||
console.log('token: ' + token);
|
||||
done();
|
||||
});
|
||||
|
||||
|
||||
Accounts.onEnrollmentLink(function (token, done){
|
||||
console.log('Accounts.onResearchPasswordLink');
|
||||
console.log('Sending enrollment email...');
|
||||
console.log('NOT IMPLEMENTED YET. PLEASE LOG AN ISSUE');
|
||||
console.log('token: ' + token);
|
||||
done();
|
||||
});
|
||||
|
||||
Accounts.onEmailVerificationLink(function (token, done){
|
||||
console.log('Accounts.onEmailVerificationLink');
|
||||
console.log('Sending verification email...');
|
||||
console.log('NOT IMPLEMENTED YET. PLEASE LOG AN ISSUE');
|
||||
console.log('token: ' + token);
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (Meteor.isServer){
|
||||
// Support for playing D&D: Roll 3d6 for dexterity
|
||||
Accounts.onCreateUser(function(options, user) {
|
||||
|
||||
var d6 = function () { return Math.floor(Random.fraction() * 6) + 1; };
|
||||
user.dexterity = d6() + d6() + d6();
|
||||
user.role = "user";
|
||||
|
||||
// We still want the default hook's 'profile' behavior.
|
||||
if (options.profile){
|
||||
user.profile = options.profile;
|
||||
}
|
||||
|
||||
return user;
|
||||
});
|
||||
}
|
||||
150
Packages/active-entry/lib/ActiveEntry.js
Executable file
150
Packages/active-entry/lib/ActiveEntry.js
Executable file
@ -0,0 +1,150 @@
|
||||
|
||||
|
||||
ActiveEntry = {};
|
||||
ActiveEntry.isAbc = function () {
|
||||
return "abc";
|
||||
};
|
||||
|
||||
|
||||
|
||||
if (Meteor.isClient) {
|
||||
Session.setDefault('Photonic.ActiveEntry', {
|
||||
logo: {
|
||||
url: "https://upload.wikimedia.org/wikipedia/commons/1/1a/Photon-photon_scattering.png",
|
||||
displayed: true
|
||||
},
|
||||
signIn: {
|
||||
displayFullName: true,
|
||||
destination: "/"
|
||||
},
|
||||
signUp: {
|
||||
destination: "/"
|
||||
},
|
||||
themeColors: {
|
||||
primary: ""
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (Meteor.isClient) {
|
||||
ActiveEntry.errorMessages = new ReactiveDict('errorMessages');
|
||||
ActiveEntry.errorMessages.set('signInError', false);
|
||||
|
||||
}
|
||||
|
||||
|
||||
ActiveEntry.configure = function (configObject) {
|
||||
if (Meteor.isClient) {
|
||||
Session.set('Photonic.ActiveEntry', configObject);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
ActiveEntry.verifyPassword = function (password) {
|
||||
if (password.length === 0) {
|
||||
ActiveEntry.errorMessages.set('password', 'Password is required');
|
||||
} else if (password.length < 8) {
|
||||
ActiveEntry.errorMessages.set('password', 'Password is weak');
|
||||
} else if (password.length >= 8) {
|
||||
ActiveEntry.errorMessages.set('password', 'Password present');
|
||||
}
|
||||
};
|
||||
ActiveEntry.verifyConfirmPassword = function (password, confirmPassword) {
|
||||
if (confirmPassword.length === 0) {
|
||||
ActiveEntry.errorMessages.set('confirm', 'Password is required');
|
||||
} else if (confirmPassword.length < 8) {
|
||||
ActiveEntry.errorMessages.set('confirm', 'Password is weak');
|
||||
}
|
||||
|
||||
if (confirmPassword === password) {
|
||||
ActiveEntry.errorMessages.set('confirm', 'Passwords match');
|
||||
}
|
||||
};
|
||||
ActiveEntry.verifyEmail = function (email) {
|
||||
if (email.length === 0) {
|
||||
ActiveEntry.errorMessages.set('email', 'Email is required');
|
||||
} else if (email.indexOf("@") === -1){
|
||||
ActiveEntry.errorMessages.set('email', 'Email is poorly formatted');
|
||||
} else if (email.indexOf("@") >= 0){
|
||||
ActiveEntry.errorMessages.set('email', 'Email present');
|
||||
}
|
||||
};
|
||||
ActiveEntry.verifyFullName = function (fullName) {
|
||||
if (fullName.length === 0) {
|
||||
ActiveEntry.errorMessages.set('fullName', 'Name is required');
|
||||
} else if (fullName.indexOf(" ") === -1){
|
||||
ActiveEntry.errorMessages.set('fullName', 'Name is probably not complete');
|
||||
} else if (fullName.indexOf(" ") >= 0){
|
||||
ActiveEntry.errorMessages.set('fullName', 'Name present');
|
||||
}
|
||||
};
|
||||
|
||||
ActiveEntry.signIn = function (emailValue, passwordValue){
|
||||
ActiveEntry.verifyPassword(passwordValue);
|
||||
ActiveEntry.verifyEmail(emailValue);
|
||||
|
||||
Meteor.loginWithPassword({email: emailValue}, passwordValue, function (error, result) {
|
||||
if (error) {
|
||||
ActiveEntry.errorMessages.set('signInError', error.message);
|
||||
} else {
|
||||
console.log('result', result);
|
||||
var ActiveEntryConfig = Session.get('Photonic.ActiveEntry');
|
||||
console.log('ActiveEntryConfig', JSON.stringify(ActiveEntryConfig));
|
||||
Router.go(ActiveEntryConfig.signIn.destination);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
ActiveEntry.signUp = function (emailValue, passwordValue, confirmPassword, fullName){
|
||||
ActiveEntry.verifyEmail(emailValue);
|
||||
ActiveEntry.verifyPassword(passwordValue);
|
||||
ActiveEntry.verifyConfirmPassword(passwordValue, confirmPassword);
|
||||
ActiveEntry.verifyFullName(fullName);
|
||||
|
||||
Accounts.createUser({
|
||||
email: emailValue,
|
||||
password: passwordValue,
|
||||
profile: {
|
||||
fullName: fullName
|
||||
}
|
||||
}, function (error, result) {
|
||||
if (error) {
|
||||
console.log(error);
|
||||
ActiveEntry.errorMessages.set('signInError', error.message);
|
||||
} else {
|
||||
var ActiveEntryConfig = Session.get('Photonic.ActiveEntry');
|
||||
Router.go(ActiveEntryConfig.signUp.destination);
|
||||
}
|
||||
});
|
||||
|
||||
// Meteor.loginWithPassword({email: emailValue}, passwordValue, function (error, result) {
|
||||
// if (error) {
|
||||
// console.log(error);
|
||||
// Session.set('errorMessage', error);
|
||||
// }
|
||||
//
|
||||
// if (result) {
|
||||
// console.log('result', result);
|
||||
// }
|
||||
// var ActiveEntryConfig = Session.get('Photonic.ActiveEntry');
|
||||
// console.log('ActiveEntryConfig', JSON.stringify(ActiveEntryConfig));
|
||||
// Router.go(ActiveEntryConfig.signIn.destination);
|
||||
// });
|
||||
};
|
||||
ActiveEntry.signOut = function (){
|
||||
Meteor.logout();
|
||||
};
|
||||
|
||||
ActiveEntry.reset = function (){
|
||||
ActiveEntry.errorMessages.set('fullName', false);
|
||||
ActiveEntry.errorMessages.set('email', false);
|
||||
ActiveEntry.errorMessages.set('confirm', false);
|
||||
ActiveEntry.errorMessages.set('password', false);
|
||||
};
|
||||
ActiveEntry.logoIsDisplayed = function (){
|
||||
var ActiveEntryConfig = Session.get('Photonic.ActiveEntry');
|
||||
return ActiveEntryConfig.logo.displayed;
|
||||
}
|
||||
73
Packages/active-entry/package.js
Executable file
73
Packages/active-entry/package.js
Executable file
@ -0,0 +1,73 @@
|
||||
Package.describe({
|
||||
name: 'clinical:active-entry',
|
||||
version: '1.5.14',
|
||||
summary: 'SignIn, SignUp, and ForgotPassword pages for Clinical Framework.',
|
||||
git: 'https://github.com/clinical-meteor/clinical-active-entry',
|
||||
documentation: 'README.md'
|
||||
});
|
||||
|
||||
Package.onUse(function (api) {
|
||||
api.versionsFrom('1.1.0.3');
|
||||
|
||||
api.use([
|
||||
'meteor-platform',
|
||||
'templating',
|
||||
'clinical:router@2.0.17',
|
||||
'grove:less@0.1.1',
|
||||
'session',
|
||||
'reactive-dict',
|
||||
'accounts-base',
|
||||
'accounts-password'
|
||||
], ['client']);
|
||||
|
||||
api.use([
|
||||
'accounts-base',
|
||||
'accounts-password'
|
||||
], ['server']);
|
||||
|
||||
api.addFiles([
|
||||
'lib/ActiveEntry.js',
|
||||
'lib/Accounts.js'
|
||||
]);
|
||||
|
||||
api.imply('accounts-base');
|
||||
api.imply('accounts-password');
|
||||
|
||||
api.addFiles([
|
||||
'components/entryPages.js',
|
||||
'components/entryPages.less',
|
||||
|
||||
'components/entrySignIn/entrySignIn.html',
|
||||
'components/entrySignIn/entrySignIn.js',
|
||||
'components/entrySignIn/entrySignIn.less',
|
||||
|
||||
'components/entrySignUp/entrySignUp.html',
|
||||
'components/entrySignUp/entrySignUp.js',
|
||||
'components/entrySignUp/entrySignUp.less',
|
||||
|
||||
'components/forgotPassword/forgotPassword.html',
|
||||
'components/forgotPassword/forgotPassword.js',
|
||||
'components/forgotPassword/forgotPassword.less',
|
||||
|
||||
], ['client']);
|
||||
|
||||
|
||||
api.addFiles('server/methods.js', "server", {testOnly: true});
|
||||
|
||||
api.export("ActiveEntry");
|
||||
});
|
||||
|
||||
|
||||
Package.onTest(function (api) {
|
||||
api.use([
|
||||
'templating',
|
||||
'clinical:router@2.0.13',
|
||||
'grove:less@0.1.1',
|
||||
'standard-app-packages'
|
||||
], ['client']);
|
||||
|
||||
api.use('tinytest');
|
||||
api.use('clinical:active-entry');
|
||||
api.use('clinical:verification');
|
||||
api.addFiles('tests/gagarin/activeEntryTests.js');
|
||||
});
|
||||
12
Packages/active-entry/server/methods.js
Normal file
12
Packages/active-entry/server/methods.js
Normal file
@ -0,0 +1,12 @@
|
||||
Meteor.methods({
|
||||
initializeEntryUsers: function (){
|
||||
console.log('Initializing Users', Meteor.users.find().fetch());
|
||||
|
||||
},
|
||||
dropEntryUsers: function (){
|
||||
console.log('Drop Users', Meteor.users.find().fetch());
|
||||
Meteor.users.find().forEach(function(user){
|
||||
Meteor.users.remove({_id: user._id});
|
||||
});
|
||||
}
|
||||
});
|
||||
197
Packages/active-entry/tests/gagarin/activeEntryTests.js
Normal file
197
Packages/active-entry/tests/gagarin/activeEntryTests.js
Normal file
@ -0,0 +1,197 @@
|
||||
// var nightwatch = require('nightwatch');
|
||||
|
||||
describe('clinical:active-entry', function () {
|
||||
var server = meteor();
|
||||
var client = browser(server);
|
||||
|
||||
// before(function () {
|
||||
// return server.promise(function (resolve){
|
||||
// Meteor.users.find().forEach(function(user){
|
||||
// Meteor.users.remove({_id: user._id});
|
||||
// }, function(){
|
||||
// resolve();
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
// afterEach(function (){
|
||||
// return client.promise(function (resolve){
|
||||
// Meteor.logout(function(error, result){
|
||||
// resolve();
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
|
||||
it("ActiveEntry object should be loaded on client and server", function () {
|
||||
return server.execute(function () {
|
||||
expect(ActiveEntry.isAbc()).to.equal('abc');
|
||||
}).then(function (data){
|
||||
return client.execute(function (a) {
|
||||
expect(ActiveEntry.isAbc()).to.equal('abc');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("Error messages should be empty by default", function () {
|
||||
return client.execute(function () {
|
||||
expect(ActiveEntry.errorMessages.get('signInError')).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
// ActiveEntry.verifyEmail
|
||||
it('Email validation confirms it is a properly formatted email.', function () {
|
||||
return client.execute(function (a) {
|
||||
ActiveEntry.verifyEmail('janedoe@somewhere.com');
|
||||
expect(ActiveEntry.errorMessages.get('email')).to.equal("Email present");
|
||||
|
||||
ActiveEntry.verifyEmail('');
|
||||
expect(ActiveEntry.errorMessages.get('email')).to.equal("Email is required");
|
||||
|
||||
ActiveEntry.verifyEmail('janedoe.somewhere.com');
|
||||
expect(ActiveEntry.errorMessages.get('email')).to.equal("Email is poorly formatted");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// ActiveEntry.verifyPassword
|
||||
it('Password validation confirms it is a properly formatted password.', function () {
|
||||
return client.execute(function (a) {
|
||||
ActiveEntry.verifyPassword('');
|
||||
expect(ActiveEntry.errorMessages.get('password')).to.equal("Password is required");
|
||||
|
||||
ActiveEntry.verifyPassword('kittens');
|
||||
expect(ActiveEntry.errorMessages.get('password')).to.equal("Password is weak");
|
||||
|
||||
ActiveEntry.verifyPassword('kittens123');
|
||||
expect(ActiveEntry.errorMessages.get('password')).to.equal("Password present");
|
||||
});
|
||||
});
|
||||
|
||||
// ActiveEntry.verifyConfirmPassword
|
||||
it('Password match validation confirms that two passwords are the same.', function () {
|
||||
return client.execute(function (a) {
|
||||
ActiveEntry.verifyConfirmPassword('kittens123', '');
|
||||
expect(ActiveEntry.errorMessages.get('confirm')).to.equal("Password is required");
|
||||
|
||||
ActiveEntry.verifyConfirmPassword('kittens123', 'kittens');
|
||||
expect(ActiveEntry.errorMessages.get('confirm')).to.equal("Password is weak");
|
||||
|
||||
ActiveEntry.verifyConfirmPassword('kittens123', 'kittens123');
|
||||
expect(ActiveEntry.errorMessages.get('confirm')).to.equal("Passwords match");
|
||||
});
|
||||
});
|
||||
|
||||
// ActiveEntry.verifyFullName
|
||||
it('Fullname validation confirms that at least a first and last name are entered.', function () {
|
||||
return client.execute(function (a) {
|
||||
ActiveEntry.verifyFullName('');
|
||||
expect(ActiveEntry.errorMessages.get('fullName')).to.equal("Name is required");
|
||||
|
||||
ActiveEntry.verifyFullName('Jane');
|
||||
expect(ActiveEntry.errorMessages.get('fullName')).to.equal("Name is probably not complete");
|
||||
|
||||
ActiveEntry.verifyFullName('Jane Doe');
|
||||
expect(ActiveEntry.errorMessages.get('fullName')).to.equal("Name present");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// ActiveEntry.signIn
|
||||
it('Newly created user record should have role, profile, and name set.', function () {
|
||||
return client.execute(function () {
|
||||
ActiveEntry.signUp('janedoe@test.org', 'janedoe123', 'janedoe123', 'Jane Doe');
|
||||
expect(ActiveEntry.errorMessages.get('fullName')).to.equal("Name present");
|
||||
}).then(function (){
|
||||
return server.wait(300, 'until account is created on the server', function () {
|
||||
return Meteor.users.findOne({'emails.address': 'janedoe@test.org'});
|
||||
}).then(function (user){
|
||||
expect(user.role).to.equal('user');
|
||||
expect(user.profile.fullName).to.equal('Jane Doe');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
it("Newly created user should have fullName(), preferredName(), and familyName() methods.", function () {
|
||||
return server.execute(function () {
|
||||
var user = Meteor.users.findOne({'emails.address': 'janedoe@test.org'});
|
||||
expect(user).to.be.ok;
|
||||
expect(user.fullName()).to.equal('Jane Doe');
|
||||
expect(user.givenName()).to.equal('Jane');
|
||||
expect(user.familyName()).to.equal('Doe');
|
||||
}).then(function(){
|
||||
// client.wait(500, "until user is logged out", function(){
|
||||
// Meteor.logout();
|
||||
// });
|
||||
return client.promise(function (resolve){
|
||||
Meteor.logout(function(error, result){
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
it("Newly created user can sign in to the application.", function () {
|
||||
return client.execute(function () {
|
||||
expect(Meteor.userId()).to.not.exist;
|
||||
ActiveEntry.signIn('janedoe@test.org', 'janedoe123');
|
||||
}).then(function (){
|
||||
client.wait(3000, "for user to sign in", function (){
|
||||
expect(Meteor.userId()).to.exist;
|
||||
});
|
||||
});
|
||||
});
|
||||
it("Newly created user can sign out of the application.", function () {
|
||||
return client.execute(function () {
|
||||
expect(Meteor.userId()).to.not.exist;
|
||||
ActiveEntry.signIn('janedoe@test.org', 'janedoe123');
|
||||
}).then(function (){
|
||||
client.wait(3000, "for user to sign in", function (){
|
||||
expect(Meteor.userId()).to.exist;
|
||||
ActiveEntry.signOut('janedoe@test.org');
|
||||
}).then(function (){
|
||||
expect(Meteor.userId()).to.not.exist;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
// it("config should be able to change company logo", function () {
|
||||
//
|
||||
// });
|
||||
// it("config should be able to change entry message text", function () {
|
||||
//
|
||||
// });
|
||||
|
||||
// it("new user should be able to register on desktop", function () {
|
||||
// client.location = "/sign-in";
|
||||
//
|
||||
// client.execute(function () {
|
||||
// expect($('#entrySignIn')).to.exist();
|
||||
// expect($('#signInPageEmailInput')).to.exist();
|
||||
// expect($('#signInPagePasswordInput')).to.exist();
|
||||
// expect($('#signInToAppButton')).to.exist();
|
||||
// }).setValue('#signInPageEmailInput', 'house@test.org')
|
||||
// .setValue('#signInPagePasswordInput', 'house@test.org')
|
||||
// .click('#signInToAppButton').execute(function(){
|
||||
// expect($('#entrySignIn')).to.exist();
|
||||
// expect($('#signInPageEmailInput')).to.exist();
|
||||
// expect($('#signInPagePasswordInput')).to.exist();
|
||||
// expect($('#signInToAppButton')).to.exist();
|
||||
// // expect($('#entrySignIn')).to.not.exist();
|
||||
// // expect($('#signInPageEmailInput')).to.not.exist();
|
||||
// // expect($('#signInPagePasswordInput')).to.not.exist();
|
||||
// // expect($('#signInToAppButton')).to.not.exist();
|
||||
// });
|
||||
// // .then(function(data){
|
||||
// // return server.execute(3000, 'until the account is created', function () {
|
||||
// // expect(Meteor.users.find().count()).to.be.above(20);
|
||||
// // });
|
||||
// // });
|
||||
// });
|
||||
|
||||
|
||||
});
|
||||
22
Packages/active-entry/tests/nightwatch/commands/dropCollaborations.js
Executable file
22
Packages/active-entry/tests/nightwatch/commands/dropCollaborations.js
Executable file
@ -0,0 +1,22 @@
|
||||
// async version calls method on the server
|
||||
exports.command = function () {
|
||||
var client = this;
|
||||
|
||||
this
|
||||
.timeoutsAsyncScript(5000)
|
||||
.executeAsync(function (data, meteorCallback) {
|
||||
//return HipaaLogger.logEventObject(data);
|
||||
Meteor.call("dropCollaborations", data, function (meteorError, meteorResult) {
|
||||
var response = (meteorError ? {
|
||||
error: meteorError
|
||||
} : {
|
||||
result: meteorResult
|
||||
});
|
||||
meteorCallback(response);
|
||||
});
|
||||
}, [], function (result) {
|
||||
console.log("result.value", result.value);
|
||||
client.assert.ok(result.value);
|
||||
}).pause(1000);
|
||||
return this;
|
||||
};
|
||||
184
Packages/active-entry/tests/nightwatch/walkthroughs/activeEntryWalkthrough.js
Executable file
184
Packages/active-entry/tests/nightwatch/walkthroughs/activeEntryWalkthrough.js
Executable file
@ -0,0 +1,184 @@
|
||||
// when new user fills out form and registers, new user should get created
|
||||
// when user signs in with username and password, should redirect to home page
|
||||
// newly created user record should have role
|
||||
// newly created user record should have profile
|
||||
// newly created user record should have full, preferred, and family name
|
||||
// user object should return first name
|
||||
// user object should return last name
|
||||
// user should be able to request reset password email
|
||||
// user should be able to request be able to create new account
|
||||
// guest should be notified if username already exists
|
||||
// guest should be notified if passwords do not match
|
||||
// guest should be notified if email is not correctly formatted
|
||||
// new user should be able to register on desktop
|
||||
// new user should be able to register on tablet
|
||||
// existing user should be able to sign in on desktop
|
||||
// existing user should be able to sign in on tablet
|
||||
// existing user should be able to sign in on phone
|
||||
// company logo should display on sign//in page
|
||||
|
||||
|
||||
|
||||
module.exports = {
|
||||
tags: ['users', 'entry'],
|
||||
before: function(client){
|
||||
client
|
||||
.url("http://localhost:3000/entrySignUp")
|
||||
.initializeUsers()
|
||||
.resizeWindow(1024, 768)
|
||||
},
|
||||
"new user should be able to register on desktop" : function (client) {
|
||||
client
|
||||
.verify.elementPresent("#entrySignUp")
|
||||
.verify.elementPresent("#signUpPageTitle")
|
||||
.verify.elementPresent("#signUpPageMessage")
|
||||
.verify.elementPresent("#signUpPageEmailInput")
|
||||
.verify.elementPresent("#signUpPagePasswordInput")
|
||||
.verify.elementPresent("#signUpPageJoinNowButton")
|
||||
.verify.elementPresent("#signUpPageSignInButton")
|
||||
},
|
||||
"company logo should display on sign-in page" : function (client) {
|
||||
client
|
||||
.verify.elementPresent("#entrySignUp")
|
||||
.verify.elementPresent("#entryAppLogo")
|
||||
},
|
||||
"user should be able to request be able to create new account" : function (client) {
|
||||
client.verify.elementPresent("#signUpPageEmailInput")
|
||||
.verify.elementPresent("#signUpPagePasswordInput")
|
||||
.verify.elementPresent("#signUpPagePasswordInput")
|
||||
.verify.elementPresent("#signUpPageJoinNowButton")
|
||||
},
|
||||
|
||||
"guest should be notified if password is insecure" : function (client) {
|
||||
client
|
||||
.clearValue("input")
|
||||
.verify.elementPresent("#signUpPagePasswordInput")
|
||||
.verify.cssProperty('#signUpPagePasswordInput', 'border', '1px solid gray')
|
||||
.setValue("#signUpPagePasswordInput", "jan")
|
||||
.verify.cssProperty('#signUpPagePasswordInput', 'border', '1px solid rgb(242, 222, 222)')
|
||||
.setValue("#signUpPagePasswordInput", "icedoe123")
|
||||
.verify.cssProperty('#signUpPagePasswordInput', 'border', '1px solid green')
|
||||
|
||||
.verify.cssProperty('#signUpPagePasswordConfirmInput', 'border', '1px solid gray')
|
||||
.setValue("#signUpPagePasswordConfirmInput", "ja")
|
||||
.verify.cssProperty('#signUpPagePasswordConfirmInput', 'border', '1px solid rgb(242, 222, 222)')
|
||||
.clearValue("#signUpPagePasswordConfirmInput")
|
||||
.setValue("#signUpPagePasswordConfirmInput", "janicedoe123")
|
||||
.verify.cssProperty('#signUpPagePasswordConfirmInput', 'border', '1px solid green')
|
||||
},
|
||||
"guest should be notified if passwords do not match" : function (client) {
|
||||
client
|
||||
.clearValue("#signUpPagePasswordConfirmInput")
|
||||
.clearValue("#signUpPagePasswordInput")
|
||||
.resetEntry()
|
||||
.pause(500)
|
||||
.verify.cssProperty('#signUpPagePasswordInput', 'border', '1px solid gray')
|
||||
.verify.cssProperty('#signUpPagePasswordConfirmInput', 'border', '1px solid gray')
|
||||
.setValue("#signUpPagePasswordInput", "janicedoe123")
|
||||
.verify.cssProperty('#signUpPagePasswordInput', 'border', '1px solid green')
|
||||
.verify.cssProperty('#signUpPagePasswordConfirmInput', 'border', '1px solid gray')
|
||||
.setValue("#signUpPagePasswordConfirmInput", "janicedoe123")
|
||||
.verify.cssProperty('#signUpPagePasswordInput', 'border', '1px solid green')
|
||||
.verify.cssProperty('#signUpPagePasswordConfirmInput', 'border', '1px solid green')
|
||||
},
|
||||
"guest should be notified if email is not correctly formatted" : function (client) {
|
||||
client
|
||||
.clearValue("#signUpPageEmailInput")
|
||||
.resetEntry()
|
||||
.verify.elementPresent("#signUpPageEmailInput")
|
||||
.verify.cssProperty('#signUpPageEmailInput', 'border', '1px solid gray')
|
||||
.setValue("#signUpPageEmailInput", "janicedoe")
|
||||
.verify.cssProperty('#signUpPageEmailInput', 'border', '1px solid rgb(242, 222, 222)')
|
||||
.setValue("#signUpPageEmailInput", "@symptomatic.io")
|
||||
.verify.cssProperty('#signUpPageEmailInput', 'border', '1px solid green')
|
||||
},
|
||||
"when new user fills out form and registers, new user should get created" : function (client) {
|
||||
client
|
||||
.verify.elementPresent("#entrySignUp")
|
||||
|
||||
.clearValue("#signUpPagePasswordConfirmInput")
|
||||
.clearValue("#signUpPagePasswordInput")
|
||||
.clearValue("#signUpPageFullNameInput")
|
||||
.clearValue("#signUpPageEmailInput")
|
||||
.resetEntry()
|
||||
|
||||
.setValue("#signUpPageFullNameInput", "Janice Doe")
|
||||
.setValue("#signUpPageEmailInput", "janicedoe@symptomatic.io")
|
||||
.setValue("#signUpPagePasswordInput", "janicedoe123")
|
||||
.setValue("#signUpPagePasswordConfirmInput", "janicedoe123")
|
||||
|
||||
.click("#signUpPageJoinNowButton").pause(1000)
|
||||
|
||||
.verify.containsText("#usernameLink", "janicedoe@symptomatic.io")
|
||||
},
|
||||
"user should be able to signout" : function (client) {
|
||||
client
|
||||
.verify.elementPresent("#logoutButton")
|
||||
.click("#logoutButton").pause(300)
|
||||
.verify.containsText("#usernameLink", "Sign In")
|
||||
},
|
||||
"user should be able to request reset password email" : function (client) {
|
||||
client
|
||||
.url("http://localhost:3000/entrySignIn")
|
||||
.verify.elementPresent("#forgotPasswordButton")
|
||||
.click("#forgotPasswordButton")
|
||||
.verify.elementPresent("#forgotPassword")
|
||||
.verify.elementPresent("#signInPageEmailInput")
|
||||
.verify.elementPresent("#sendReminderButton")
|
||||
},
|
||||
"existing user should be able to sign in on desktop" : function (client) {
|
||||
client
|
||||
.url("http://localhost:3000/entrySignIn")
|
||||
.resizeWindow(1600, 1200)
|
||||
.verify.containsText("#usernameLink", "Sign In")
|
||||
.signIn("janicedoe@symptomatic.io", "janicedoe123").pause(500)
|
||||
.verify.containsText("#usernameLink", "janicedoe@symptomatic.io")
|
||||
.click("#logoutButton").pause(200)
|
||||
.verify.containsText("#usernameLink", "Sign In")
|
||||
},
|
||||
"existing user should be able to sign in on tablet" : function (client) {
|
||||
client
|
||||
.url("http://localhost:3000/entrySignIn")
|
||||
.resizeWindow(1024, 768)
|
||||
.verify.containsText("#usernameLink", "Sign In")
|
||||
.signIn("janicedoe@symptomatic.io", "janicedoe123").pause(500)
|
||||
.verify.containsText("#usernameLink", "janicedoe@symptomatic.io")
|
||||
.click("#logoutButton").pause(200)
|
||||
.verify.containsText("#usernameLink", "Sign In")
|
||||
},
|
||||
"existing user should be able to sign in on phone" : function (client) {
|
||||
client
|
||||
.url("http://localhost:3000/entrySignIn")
|
||||
.resizeWindow(320, 960)
|
||||
// .verify.containsText("#usernameLink", "Sign In")
|
||||
.signIn("janicedoe@symptomatic.io", "janicedoe123").pause(500)
|
||||
.click("#sidebarToggle").pause(300)
|
||||
.verify.containsText("#usernameLink", "janicedoe@symptomatic.io")
|
||||
.click("#logoutButton").pause(200)
|
||||
.verify.containsText("#usernameLink", "Sign In")
|
||||
},
|
||||
"if anonymous user tries to log in with non-existing account, a message is shown" : function (client) {
|
||||
client
|
||||
.url("http://localhost:3000/entrySignIn")
|
||||
.resizeWindow(1024, 768)
|
||||
.signIn("alice@symptomatic.io", "alice123").pause(500)
|
||||
.verify.containsText("#signInPageMessage", "User not found [403]")
|
||||
.verify.cssProperty("#signInPageMessage", "color", "rgba(169, 68, 66, 1)")
|
||||
.verify.cssProperty("#signInPageMessage", "background-color", "rgba(242, 222, 222, 1)")
|
||||
.verify.cssProperty("#signInPageMessage", "border-color", "rgb(235, 204, 209)")
|
||||
},
|
||||
"anonymous guest should be notified if email already exists" : function (client) {
|
||||
client
|
||||
.url("http://localhost:3000/entrySignUp")
|
||||
.resizeWindow(1024, 768)
|
||||
.signUp("janicedoe@symptomatic.io", "janicedoe123").pause(500)
|
||||
.click("#signUpPageEmailInput").pause(500)
|
||||
.verify.elementPresent("#signUpPageMessage")
|
||||
.verify.containsText("#signUpPageMessage", "Email already exists. [403]")
|
||||
},
|
||||
after: function(client){
|
||||
client
|
||||
.dropEntryUsers()
|
||||
.end();
|
||||
}
|
||||
};
|
||||
15
Packages/clinical-themes/README.md
Normal file
15
Packages/clinical-themes/README.md
Normal file
@ -0,0 +1,15 @@
|
||||
## clinical:themes
|
||||
Theme selection component for ClinicalFramework apps.
|
||||
|
||||
------------------------
|
||||
### Installation
|
||||
|
||||
````
|
||||
meteor add clinical:themes
|
||||
````
|
||||
|
||||
|
||||
------------------------
|
||||
### License
|
||||
|
||||
MIT License. Use as you wish, including for commercial purposes.
|
||||
0
Packages/clinical-themes/components/themeCard.html
Normal file
0
Packages/clinical-themes/components/themeCard.html
Normal file
0
Packages/clinical-themes/components/themeCard.js
Normal file
0
Packages/clinical-themes/components/themeCard.js
Normal file
0
Packages/clinical-themes/components/themeCard.less
Normal file
0
Packages/clinical-themes/components/themeCard.less
Normal file
0
Packages/clinical-themes/lib/ActiveThemes.js
Normal file
0
Packages/clinical-themes/lib/ActiveThemes.js
Normal file
31
Packages/clinical-themes/package.js
Normal file
31
Packages/clinical-themes/package.js
Normal file
@ -0,0 +1,31 @@
|
||||
Package.describe({
|
||||
name: 'clinical:themes',
|
||||
version: '0.0.1',
|
||||
// Brief, one-line summary of the package.
|
||||
summary: 'Theme selection component for ClinicalFramework apps.',
|
||||
// URL to the Git repository containing the source code for this package.
|
||||
git: 'https://github.com/awatson1978/clinical-themes',
|
||||
// By default, Meteor will default to using README.md for documentation.
|
||||
// To avoid submitting documentation, set this field to null.
|
||||
documentation: 'README.md'
|
||||
});
|
||||
|
||||
Package.onUse(function (api) {
|
||||
api.versionsFrom('1.2.1');
|
||||
|
||||
api.use('meteor-platform');
|
||||
api.use('less');
|
||||
|
||||
api.addFiles('lib/ActiveThemes.js');
|
||||
|
||||
api.addFiles('components/themeCard.html');
|
||||
api.addFiles('components/themeCard.js');
|
||||
api.addFiles('components/themeCard.less');
|
||||
|
||||
});
|
||||
|
||||
Package.onTest(function (api) {
|
||||
api.use('tinytest');
|
||||
api.use('clinical:themes');
|
||||
api.addFiles('tests/clinical-themes.js');
|
||||
});
|
||||
10
Packages/clinical-themes/tests/clinical-themes.js
Normal file
10
Packages/clinical-themes/tests/clinical-themes.js
Normal file
@ -0,0 +1,10 @@
|
||||
// Write your tests here!
|
||||
// Here is an example.
|
||||
describe('clinical:collaborations-ui', function () {
|
||||
it.client('runs only in client', function () {
|
||||
expect(Meteor.isClient).to.be.true;
|
||||
});
|
||||
it.server('runs only in server', function () {
|
||||
expect(Meteor.isServer).to.be.true;
|
||||
});
|
||||
});
|
||||
1
Packages/clinical-ui-vocabulary/.gitignore
vendored
Normal file
1
Packages/clinical-ui-vocabulary/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
.build*
|
||||
84
Packages/clinical-ui-vocabulary/README.md
Normal file
84
Packages/clinical-ui-vocabulary/README.md
Normal file
@ -0,0 +1,84 @@
|
||||
## clinical:ui-vocabulary
|
||||
|
||||
|
||||
Package to provide semantic CSS classes to your app. Based on Bootstrap3.
|
||||
|
||||
|
||||
=========================
|
||||
#### Installation
|
||||
|
||||
Simply nstall the clinical-ui-vocabulary package from the command line, like so:
|
||||
|
||||
````js
|
||||
meteor add clinical:ui-vocabulary
|
||||
````
|
||||
|
||||
Then feel free to use the following CSS classes in your application.
|
||||
|
||||
=========================
|
||||
#### Vocabulary - Anchoring
|
||||
|
||||
- fixed-layout
|
||||
- left-anchored
|
||||
- right-anchored
|
||||
- bottom-anchored
|
||||
- top-anchored
|
||||
- right-aligned
|
||||
- left-aligned
|
||||
- absolute-layout
|
||||
- fixed-layout
|
||||
|
||||
=========================
|
||||
#### Vocabulary - Borders
|
||||
|
||||
- gray-border
|
||||
- with-rounded-corners
|
||||
|
||||
=========================
|
||||
#### Vocabulary - Fonts
|
||||
|
||||
- monospace
|
||||
|
||||
=========================
|
||||
#### Vocabulary - Haptics
|
||||
|
||||
- clickable
|
||||
- unselectable
|
||||
|
||||
=========================
|
||||
#### Vocabulary - Padding
|
||||
|
||||
- well-behaved
|
||||
- padded
|
||||
- padded-horizontal, with-horizontal-padding, horizontally-padded
|
||||
- padded-vertical, with-vertical-padding, vertically-padded
|
||||
- with-right-padding
|
||||
- with-left-padding
|
||||
|
||||
- without-padding, nopadding, no-padding
|
||||
- without-right-padding
|
||||
- without-left-padding
|
||||
- without-top-padding
|
||||
- without-bottom-padding
|
||||
- without-vertical-padding
|
||||
- without-horizontal-padding
|
||||
|
||||
=========================
|
||||
#### Vocabulary - Colors
|
||||
|
||||
- dark
|
||||
- light
|
||||
- white
|
||||
- black
|
||||
- gray
|
||||
- lightgray
|
||||
- darkgray
|
||||
- transparent
|
||||
- glass
|
||||
- fog
|
||||
- mostly-opaque
|
||||
- red
|
||||
- blue
|
||||
- green
|
||||
- maroon
|
||||
- etc
|
||||
56
Packages/clinical-ui-vocabulary/anchoring.less
Normal file
56
Packages/clinical-ui-vocabulary/anchoring.less
Normal file
@ -0,0 +1,56 @@
|
||||
//---------------------------------
|
||||
// layouts
|
||||
|
||||
.absolute-layout{
|
||||
position:absolute;
|
||||
}
|
||||
.fixed-layout{
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------
|
||||
// anchoring
|
||||
|
||||
.left-anchored{
|
||||
position: fixed;
|
||||
left: 0px;
|
||||
}
|
||||
.right-anchored{
|
||||
position: fixed;
|
||||
right: 0px;
|
||||
}
|
||||
.float-right{
|
||||
position: absolute;
|
||||
float: right;
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
|
||||
.bottom-anchored{
|
||||
position: fixed;
|
||||
bottom: 0px;
|
||||
}
|
||||
.top-anchored{
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
|
||||
// alignment
|
||||
|
||||
.right-aligned{
|
||||
text-align: right;
|
||||
}
|
||||
.left-aligned{
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
|
||||
// layouts
|
||||
.absolute-layout{
|
||||
position:absolute;
|
||||
}
|
||||
.fixed-layout{
|
||||
position: fixed;
|
||||
}
|
||||
6
Packages/clinical-ui-vocabulary/borders.less
Normal file
6
Packages/clinical-ui-vocabulary/borders.less
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
.with-rounded-corners {
|
||||
-moz-border-radius: .4em;
|
||||
-webkit-border-radius: .4em;
|
||||
border-radius: .4em;
|
||||
}
|
||||
66
Packages/clinical-ui-vocabulary/colors.less
Normal file
66
Packages/clinical-ui-vocabulary/colors.less
Normal file
@ -0,0 +1,66 @@
|
||||
.dark{
|
||||
color: white;
|
||||
background-color: black;
|
||||
}
|
||||
.light{
|
||||
color: black;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.maroon{
|
||||
color: #6B1A2C;
|
||||
}
|
||||
.green{
|
||||
color: green;
|
||||
}
|
||||
.red{
|
||||
color: red;
|
||||
}
|
||||
.blue{
|
||||
color: blue;
|
||||
}
|
||||
.yellow{
|
||||
color: yellow;
|
||||
}
|
||||
.purple{
|
||||
color: purple;
|
||||
}
|
||||
.orange{
|
||||
color: orange;
|
||||
}
|
||||
.black{
|
||||
color: black;
|
||||
}
|
||||
.white{
|
||||
color: white;
|
||||
}
|
||||
.gray{
|
||||
color: gray;
|
||||
}
|
||||
.lightgray{
|
||||
color: lightgray;
|
||||
}
|
||||
.darkgray{
|
||||
color: darkgray;
|
||||
}
|
||||
.notepad{
|
||||
background-color: lightyellow;
|
||||
}
|
||||
|
||||
.transparent{
|
||||
opacity: 0.3;
|
||||
}
|
||||
.glass{
|
||||
opacity: 0.8;
|
||||
background: lightgray;
|
||||
}
|
||||
.fog{
|
||||
opacity: 0.8;
|
||||
background: gray;
|
||||
}
|
||||
.mostly-opaque{
|
||||
opacity: 0.2;
|
||||
}
|
||||
.mostly-transparent{
|
||||
|
||||
}
|
||||
3
Packages/clinical-ui-vocabulary/fonts.less
Normal file
3
Packages/clinical-ui-vocabulary/fonts.less
Normal file
@ -0,0 +1,3 @@
|
||||
.monospace{
|
||||
font-family:Consolas,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New, monospace;
|
||||
}
|
||||
13
Packages/clinical-ui-vocabulary/haptics.less
Normal file
13
Packages/clinical-ui-vocabulary/haptics.less
Normal file
@ -0,0 +1,13 @@
|
||||
//-----------------------------------------
|
||||
// Clicking
|
||||
|
||||
.clickable{
|
||||
cursor: pointer;
|
||||
}
|
||||
.unselectable{
|
||||
-moz-user-select: -moz-none;
|
||||
-khtml-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
27
Packages/clinical-ui-vocabulary/package.js
Normal file
27
Packages/clinical-ui-vocabulary/package.js
Normal file
@ -0,0 +1,27 @@
|
||||
Package.describe({
|
||||
summary: "UI vocabulary for ClinicalFramework.",
|
||||
version: "1.0.5",
|
||||
git: "http://github.com/awatson1978/clinical-ui-vocabulary.git",
|
||||
name: "clinical:ui-vocabulary"
|
||||
});
|
||||
|
||||
Package.onUse(function(api) {
|
||||
api.versionsFrom('1.2.1');
|
||||
|
||||
api.use('ian:bootstrap-3@3.3.1');
|
||||
|
||||
api.addFiles('anchoring.less', 'client');
|
||||
api.addFiles('borders.less', 'client');
|
||||
api.addFiles('colors.less', 'client');
|
||||
api.addFiles('fonts.less', 'client');
|
||||
api.addFiles('haptics.less', 'client');
|
||||
api.addFiles('padding.less', 'client');
|
||||
api.addFiles('pages.less', 'client');
|
||||
api.addFiles('sizing.less', 'client');
|
||||
api.addFiles('text.less', 'client');
|
||||
|
||||
});
|
||||
|
||||
Package.onTest(function(api) {
|
||||
api.use('tinytest');
|
||||
});
|
||||
111
Packages/clinical-ui-vocabulary/padding.less
Normal file
111
Packages/clinical-ui-vocabulary/padding.less
Normal file
@ -0,0 +1,111 @@
|
||||
|
||||
.well-behaved{
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Padding
|
||||
|
||||
.padded{
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
}
|
||||
.padded-horizontal, .with-horizontal-padding, .horizontally-padded{
|
||||
box-sizing: border-box;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
.padded-vertical, .with-vertical-padding, .vertically-padded{
|
||||
box-sizing: border-box;
|
||||
padding-top: 20px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.with-right-padding{
|
||||
padding-right: 20px !important;
|
||||
}
|
||||
.with-left-padding{
|
||||
padding-left: 20px !important;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------
|
||||
// Without Padding
|
||||
|
||||
.without-padding, .nopadding, .no-padding{
|
||||
padding: 0px;
|
||||
}
|
||||
.without-right-padding{
|
||||
padding-right: 0px !important;
|
||||
}
|
||||
.without-left-padding{
|
||||
padding-left: 0px !important;
|
||||
}
|
||||
.without-top-padding{
|
||||
padding-top: 0px !important;
|
||||
}
|
||||
.without-bottom-padding{
|
||||
padding-bottom: 0px !important;
|
||||
}
|
||||
.without-vertical-padding{
|
||||
padding-top: 0px !important;
|
||||
padding-bottom: 0px !important;
|
||||
}
|
||||
.without-vertical-padding{
|
||||
padding-left: 0px !important;
|
||||
padding-right: 0px !important;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------
|
||||
// Spacers
|
||||
|
||||
.with-bottom-spacer, .with-bottom-padding{
|
||||
padding-bottom: 20px !important;
|
||||
}
|
||||
.with-top-spacer, .with-top-padding{
|
||||
padding-top:20px !important;
|
||||
}
|
||||
.with-right-spacer{
|
||||
margin-right: 5px !important;
|
||||
}
|
||||
.with-right-spacer{
|
||||
margin-left: 5px !important;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------
|
||||
// Margins
|
||||
|
||||
.margined, .with-margins{
|
||||
margin-left: 20px;
|
||||
margin-right: 20px;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.with-bottom-margin{
|
||||
margin-bottom: 20px !important;
|
||||
}
|
||||
.with-top-margin{
|
||||
margin-top:20px !important;
|
||||
}
|
||||
.with-right-margin{
|
||||
margin-right: 20px !important;
|
||||
}
|
||||
.with-left-margin{
|
||||
margin-left:20px !important;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------
|
||||
// Margins
|
||||
|
||||
.spacer{
|
||||
height: 20px;
|
||||
}
|
||||
4
Packages/clinical-ui-vocabulary/pages.less
Normal file
4
Packages/clinical-ui-vocabulary/pages.less
Normal file
@ -0,0 +1,4 @@
|
||||
.page{
|
||||
padding-top: 50px;
|
||||
padding-bottom: 50px;
|
||||
}
|
||||
10
Packages/clinical-ui-vocabulary/sizing.less
Normal file
10
Packages/clinical-ui-vocabulary/sizing.less
Normal file
@ -0,0 +1,10 @@
|
||||
|
||||
//-----------------------------------------
|
||||
// Sizing
|
||||
|
||||
.fullwidth{
|
||||
width: 100%;
|
||||
}
|
||||
.fullheight{
|
||||
height: 100%;
|
||||
}
|
||||
36
Packages/clinical-ui-vocabulary/text.less
Normal file
36
Packages/clinical-ui-vocabulary/text.less
Normal file
@ -0,0 +1,36 @@
|
||||
//-----------------------------------------
|
||||
// Text and Fonts
|
||||
|
||||
.bold{
|
||||
font-weight: bold;
|
||||
}
|
||||
.centered{
|
||||
text-align: center;
|
||||
}
|
||||
.strikeout{
|
||||
text-decoration: line-through;
|
||||
color: lightgray !important;
|
||||
}
|
||||
.dotted{
|
||||
border-style: dotted;
|
||||
border-width: 2px;
|
||||
border-color: lightgray;
|
||||
}
|
||||
.strikeout{
|
||||
text-decoration: line-through;
|
||||
color: lightgray !important;
|
||||
}
|
||||
|
||||
|
||||
.hidden{
|
||||
visibility: hidden;
|
||||
display: none;
|
||||
}
|
||||
.visible{
|
||||
visibility: visible;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.largish{
|
||||
font-size: 32px;
|
||||
}
|
||||
27
Packages/clinical-ui-vocabulary/versions.json
Normal file
27
Packages/clinical-ui-vocabulary/versions.json
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"dependencies": [
|
||||
[
|
||||
"ian:bootstrap-3",
|
||||
"3.3.1"
|
||||
],
|
||||
[
|
||||
"jquery",
|
||||
"1.0.1"
|
||||
],
|
||||
[
|
||||
"less",
|
||||
"1.0.11"
|
||||
],
|
||||
[
|
||||
"meteor",
|
||||
"1.1.3"
|
||||
],
|
||||
[
|
||||
"underscore",
|
||||
"1.0.1"
|
||||
]
|
||||
],
|
||||
"pluginDependencies": [],
|
||||
"toolVersion": "meteor-tool@1.0.35",
|
||||
"format": "1.0"
|
||||
}
|
||||
@ -100,7 +100,7 @@ Package.onUse(function(api) {
|
||||
api.addFiles('lib/deactivateAllToolData.js', 'client');
|
||||
api.addFiles('lib/clearTools.js', 'client');
|
||||
|
||||
// Export gloabal functions
|
||||
// Export global functions
|
||||
api.export('activateLesion','client');
|
||||
api.export('activateMeasurements','client');
|
||||
api.export('deactivateAllToolData','client');
|
||||
|
||||
Loading…
Reference in New Issue
Block a user