├── .meteor ├── cordova-plugins ├── .gitignore ├── release ├── platforms ├── .id ├── .finished-upgraders └── packages ├── client ├── modals │ ├── tutorialModal.js │ ├── tutorialModal.less │ ├── studySearchModal.less │ ├── formSearch.less │ ├── sponsorSearch.less │ ├── subjectSearch.less │ ├── subjectSearch.js │ ├── sponsorSearch.js │ ├── studySearchModal.js │ ├── studySearchModal.html │ ├── formSearch.html │ ├── subjectSearch.html │ ├── sponsorSearch.html │ ├── tutorialModal.html │ └── formSearch.js ├── workflow │ ├── static │ │ ├── aboutPage.less │ │ ├── eulaPage.less │ │ ├── glossaryPage.less │ │ ├── privacyPage.less │ │ ├── eulaPage.js │ │ ├── aboutPage.js │ │ ├── .landingPage.js │ │ ├── glossaryPage.js │ │ ├── privacyPage.js │ │ ├── .landingPage.less │ │ ├── glossaryPage.html │ │ ├── aboutPage.html │ │ ├── privacyPage.html │ │ ├── eulaPage.html │ │ └── .landingPage.html │ ├── errors │ │ ├── loadingPage.js │ │ ├── loadingPage.less │ │ ├── browserNotSupportedPage.less │ │ ├── app.errors.less │ │ ├── noEmployerSetErrorPage.html │ │ ├── loadingPage.html │ │ └── browserNotSupportedPage.html │ ├── .accounts │ │ ├── entryError │ │ │ ├── entryError.js │ │ │ ├── entryError.html │ │ │ └── entryError.less │ │ ├── accountButtons │ │ │ ├── accountButtons.js │ │ │ ├── accountButtons.less │ │ │ └── accountButtons.html │ │ ├── entrySocial │ │ │ ├── entrySocial.html │ │ │ ├── entrySocial.less │ │ │ └── entrySocial.js │ │ ├── resetPassword │ │ │ ├── resetPassword.less │ │ │ ├── resetPassword.js │ │ │ └── resetPassword.html │ │ ├── forgotPassword │ │ │ ├── forgotPassword.less │ │ │ ├── forgotPassword.js │ │ │ └── forgotPassword.html │ │ ├── entrySignUp │ │ │ ├── entrySignUpPage.less │ │ │ └── entrySignUpPage.html │ │ ├── entry.js │ │ ├── entrySignIn │ │ │ ├── entrySignInPage.less │ │ │ ├── entrySignInPage.js │ │ │ └── entrySignInPage.html │ │ └── ui.helpers.js │ ├── comments │ │ ├── commentsEditPage.less │ │ ├── commentsRecordPage.html │ │ ├── commentsRecordPage.js │ │ ├── commentsEditPage.html │ │ ├── commentsListPage.less │ │ └── commentsListPage.html │ ├── subjects │ │ ├── subjectsEditPage.less │ │ ├── subjectsListPage.less │ │ ├── subjectsRecordPage.html │ │ ├── subjectsRecordPage.js │ │ ├── subjectsEditPage.html │ │ └── subjectsListPage.html │ ├── data │ │ ├── dataBlockPreview.less │ │ ├── dataListPage.less │ │ ├── dataPreviewPage.less │ │ ├── dataPreviewPage.html │ │ └── dataListPage.html │ ├── alerts │ │ ├── inPageAlert.html │ │ ├── inPageAlert.less │ │ └── inPageAlert.js │ ├── studies │ │ ├── studiesEditPage.less │ │ ├── studiesListPage.less │ │ ├── studiesListPage.html │ │ ├── studiesRecordPage.html │ │ └── studiesRecordPage.js │ ├── sponsors │ │ ├── sponsorsPage.less │ │ ├── sponsorsEditPage.html │ │ ├── sponsorsRecordPage.js │ │ ├── sponsorsListPage.html │ │ └── sponsorsEditPage.js │ ├── home │ │ ├── homePage.less │ │ ├── imagePanel.less │ │ └── homePage.js │ ├── builder │ │ ├── builderPage.html │ │ ├── builderPage.less │ │ └── formBlock.js │ ├── forms │ │ ├── formPreviewPage.html │ │ ├── formsListPage.less │ │ ├── formsListPage.html │ │ └── formPreviewPage.js │ ├── users │ │ ├── userEditPage │ │ │ ├── userPreferencesCard.html │ │ │ ├── userEditPage.html │ │ │ └── userSecurityCard.html │ │ ├── myProfilePage │ │ │ └── myProfilePage.js │ │ ├── newUserPage.scss │ │ ├── users.responsive.less │ │ └── usersListPage │ │ │ └── usersListPage.html │ └── landing │ │ ├── landingPage.less │ │ ├── landingPage.theme.cta.less │ │ ├── landingPage.js │ │ ├── landingPage.theme.team.less │ │ └── landingPage.theme.hero.less ├── app │ ├── app.layout.html │ ├── app.startup.js │ ├── app.subscriptions.js │ ├── panels │ │ └── westPanel.less │ ├── app.entry.js │ ├── navbars │ │ ├── navbarFooter.less │ │ ├── navbarHeader.less │ │ ├── navbarHeader.js │ │ └── navbarFooter.html │ ├── app.events.js │ ├── app.dragdrop.js │ ├── app.layout.less │ ├── sidebar │ │ ├── sidebar.html │ │ ├── sidebar.js │ │ └── sidebar.less │ ├── app.syntax.less │ ├── Router.js │ └── app.uservoice.js ├── clinical.ui.syntax.less ├── ActiveEntry.js ├── Theme.js ├── ActiveLayout.js └── stylesheets │ └── custom.bootstrap.json ├── shared ├── methods │ ├── .clients.methods.js │ ├── hooks.methods.js │ ├── accounts.methods.js │ └── items.methods.js ├── objects │ ├── SimpleRationalRanks.js │ └── ClinicalTrials.js └── collections.js ├── packages ├── clinical-ui-modals │ ├── modals │ │ ├── confirm.less │ │ ├── prompt.less │ │ ├── keybindings.js │ │ ├── removeUser.less │ │ ├── keybindings.less │ │ ├── confirm.js │ │ ├── selectRole.less │ │ ├── removeUser.js │ │ ├── selectRole.js │ │ ├── prompt.html │ │ ├── confirm.html │ │ ├── removeUser.html │ │ ├── keybindings.html │ │ ├── selectRole.html │ │ └── prompt.js │ ├── .gitignore │ ├── clinical-ui-modals.js │ ├── clinical-ui-modals-tests.js │ ├── package.js │ └── versions.json └── .gitignore ├── private ├── Data-List.png ├── Forms-List.png ├── HomePage.png ├── LandingPage.png ├── FormBuilder-New.png ├── HomePage-Empty.png ├── Sponsors-Create.png ├── Sponsors-List.png ├── Data-Response-View.png ├── Forms-Manage-Publish.png ├── ResearchStudy-Create.png ├── Data-Response-Approved.png ├── Data-Response-Comment.png ├── FormBuilder-ManyQuestions.png ├── FormBuilder-Question-Add.png ├── FormBuilder-Question-Edit.png ├── FormBuilder-Question-Save.png ├── Forms-Manage-CollectData.png ├── ResearchSubjects-Create.png ├── ResearchSubjects-List-Few.png ├── Data-Response-MoreComments.png ├── HomePage-Study-SelectVisit.png ├── ResearchSubjects-List-More.png ├── Data-Response-CommentsResolved.png ├── FormBuilder-SecondQuestion-Add.png ├── HomePage-Study-SelectSubject.png ├── ResearchSubjects-Create-Empty.png └── FormBuilder-SecondQuestion-Save.png ├── public └── images │ ├── home │ ├── audit.jpg │ ├── forms.jpg │ ├── users.jpeg │ ├── users.jpg │ ├── comments.jpg │ ├── sponsors.jpg │ ├── subjects.jpg │ ├── wordcloud.jpg │ ├── formbuilder.png │ ├── forms-square.jpg │ ├── clinical-studies.jpg │ └── DataScientistJobDescriptions.jpg │ ├── errors │ ├── loading.gif │ ├── notFound.jpg │ └── browserNotSupported.png │ ├── landing │ ├── vials.jpg │ ├── devices.png │ ├── feature1.png │ ├── feature2.png │ ├── feature3.png │ ├── description.png │ ├── slider-bg.png │ ├── child-vaccine.jpg │ ├── hero │ │ └── flu-shot.jpg │ ├── slider │ │ ├── slide1.png │ │ ├── slide2.png │ │ ├── slide3.png │ │ ├── slide4.png │ │ ├── slide5.png │ │ ├── slide-left.png │ │ └── slide-right.png │ ├── clinicaltrials.jpg │ ├── injection-trial.jpeg │ ├── icons │ │ ├── Default_User.png │ │ ├── Default_Male_1.png │ │ ├── Default_Male_2.png │ │ ├── Default_Female_1.png │ │ └── Default_Female_2.png │ ├── devices │ │ ├── device-ipad-2.png │ │ ├── device-ipad.png │ │ ├── device-multi.png │ │ ├── device-macbook.png │ │ ├── device-multi-2.png │ │ ├── hipaa-log-closeup.png │ │ ├── validation-testing.png │ │ ├── device-thunderbolt-2.png │ │ ├── device-ipad-hipaa-log.png │ │ ├── pixelmator.device-ipad.pxm │ │ ├── pixelmator.device-multi.png │ │ ├── pixelmator.device-multi.pxm │ │ ├── pixelmator.device-macbook.pxm │ │ ├── device-macbook-formbuilder.png │ │ └── pixelmator.device-thunderbolt.pxm │ ├── molecular_structures.jpg │ ├── structural-genomics.jpg │ ├── support-forum-on-ipad.jpg │ ├── testimonials │ │ └── abigail.jpg │ ├── molecular_structures_hires.jpg │ └── support-forum-on-thunderbold-monitor.jpg │ ├── wireframes │ ├── 1.png │ ├── 2.png │ ├── 3.png │ ├── 4.png │ └── 5.png │ ├── icons │ ├── Default_User.png │ ├── Default_Male_1.png │ ├── Default_Male_2.png │ ├── Default_Female_1.png │ └── Default_Female_2.png │ └── placeholder-240x240.gif ├── .gitignore ├── server ├── app.environment.js ├── studies.methods.js ├── app.publications.js ├── accounts.initialize.js └── accounts.entry.js └── tests ├── app.layout.js ├── accounts.entry.js ├── app.static.js └── app.staticPages.js /.meteor/cordova-plugins: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.meteor/.gitignore: -------------------------------------------------------------------------------- 1 | local 2 | -------------------------------------------------------------------------------- /client/modals/tutorialModal.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.meteor/release: -------------------------------------------------------------------------------- 1 | METEOR@1.4.4.1 2 | -------------------------------------------------------------------------------- /client/workflow/static/aboutPage.less: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/workflow/static/eulaPage.less: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /shared/methods/.clients.methods.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.meteor/platforms: -------------------------------------------------------------------------------- 1 | browser 2 | server 3 | -------------------------------------------------------------------------------- /client/workflow/static/glossaryPage.less: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/workflow/static/privacyPage.less: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/clinical-ui-modals/modals/confirm.less: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/clinical-ui-modals/modals/prompt.less: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/clinical-ui-modals/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/clinical-ui-modals/modals/keybindings.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/clinical-ui-modals/modals/removeUser.less: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/workflow/static/eulaPage.js: -------------------------------------------------------------------------------- 1 | Template.eulaPage.events({ 2 | 3 | }); 4 | -------------------------------------------------------------------------------- /client/workflow/static/aboutPage.js: -------------------------------------------------------------------------------- 1 | Template.aboutPage.events({ 2 | 3 | }); 4 | -------------------------------------------------------------------------------- /client/workflow/static/.landingPage.js: -------------------------------------------------------------------------------- 1 | Template.landingPage.events({ 2 | 3 | }); 4 | -------------------------------------------------------------------------------- /client/workflow/static/glossaryPage.js: -------------------------------------------------------------------------------- 1 | Template.glossaryPage.events({ 2 | 3 | }); 4 | -------------------------------------------------------------------------------- /client/workflow/static/privacyPage.js: -------------------------------------------------------------------------------- 1 | Template.privacyPage.events({ 2 | 3 | }); 4 | -------------------------------------------------------------------------------- /packages/clinical-ui-modals/clinical-ui-modals.js: -------------------------------------------------------------------------------- 1 | // Write your package code here! 2 | -------------------------------------------------------------------------------- /private/Data-List.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/private/Data-List.png -------------------------------------------------------------------------------- /private/Forms-List.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/private/Forms-List.png -------------------------------------------------------------------------------- /private/HomePage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/private/HomePage.png -------------------------------------------------------------------------------- /packages/clinical-ui-modals/modals/keybindings.less: -------------------------------------------------------------------------------- 1 | #keybindingsModal .modal{ 2 | z-index: 100000; 3 | } 4 | -------------------------------------------------------------------------------- /private/LandingPage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/private/LandingPage.png -------------------------------------------------------------------------------- /private/FormBuilder-New.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/private/FormBuilder-New.png -------------------------------------------------------------------------------- /private/HomePage-Empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/private/HomePage-Empty.png -------------------------------------------------------------------------------- /private/Sponsors-Create.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/private/Sponsors-Create.png -------------------------------------------------------------------------------- /private/Sponsors-List.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/private/Sponsors-List.png -------------------------------------------------------------------------------- /public/images/home/audit.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/home/audit.jpg -------------------------------------------------------------------------------- /public/images/home/forms.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/home/forms.jpg -------------------------------------------------------------------------------- /public/images/home/users.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/home/users.jpeg -------------------------------------------------------------------------------- /public/images/home/users.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/home/users.jpg -------------------------------------------------------------------------------- /private/Data-Response-View.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/private/Data-Response-View.png -------------------------------------------------------------------------------- /private/Forms-Manage-Publish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/private/Forms-Manage-Publish.png -------------------------------------------------------------------------------- /private/ResearchStudy-Create.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/private/ResearchStudy-Create.png -------------------------------------------------------------------------------- /public/images/errors/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/errors/loading.gif -------------------------------------------------------------------------------- /public/images/home/comments.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/home/comments.jpg -------------------------------------------------------------------------------- /public/images/home/sponsors.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/home/sponsors.jpg -------------------------------------------------------------------------------- /public/images/home/subjects.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/home/subjects.jpg -------------------------------------------------------------------------------- /public/images/home/wordcloud.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/home/wordcloud.jpg -------------------------------------------------------------------------------- /public/images/landing/vials.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/vials.jpg -------------------------------------------------------------------------------- /public/images/wireframes/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/wireframes/1.png -------------------------------------------------------------------------------- /public/images/wireframes/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/wireframes/2.png -------------------------------------------------------------------------------- /public/images/wireframes/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/wireframes/3.png -------------------------------------------------------------------------------- /public/images/wireframes/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/wireframes/4.png -------------------------------------------------------------------------------- /public/images/wireframes/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/wireframes/5.png -------------------------------------------------------------------------------- /shared/methods/hooks.methods.js: -------------------------------------------------------------------------------- 1 | Meteor.methods({ 2 | eventsOnHooksInit:function(){ 3 | return true; 4 | } 5 | }) 6 | -------------------------------------------------------------------------------- /private/Data-Response-Approved.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/private/Data-Response-Approved.png -------------------------------------------------------------------------------- /private/Data-Response-Comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/private/Data-Response-Comment.png -------------------------------------------------------------------------------- /public/images/errors/notFound.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/errors/notFound.jpg -------------------------------------------------------------------------------- /public/images/home/formbuilder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/home/formbuilder.png -------------------------------------------------------------------------------- /public/images/landing/devices.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/devices.png -------------------------------------------------------------------------------- /public/images/landing/feature1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/feature1.png -------------------------------------------------------------------------------- /public/images/landing/feature2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/feature2.png -------------------------------------------------------------------------------- /public/images/landing/feature3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/feature3.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | 3 | screenshots 4 | screenshots/* 5 | logs 6 | logs/* 7 | reports 8 | reports/* 9 | 10 | settings.json 11 | -------------------------------------------------------------------------------- /client/workflow/static/.landingPage.less: -------------------------------------------------------------------------------- 1 | #landingPage{ 2 | .fa{ 3 | padding-right: 10px; 4 | color: green; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /private/FormBuilder-ManyQuestions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/private/FormBuilder-ManyQuestions.png -------------------------------------------------------------------------------- /private/FormBuilder-Question-Add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/private/FormBuilder-Question-Add.png -------------------------------------------------------------------------------- /private/FormBuilder-Question-Edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/private/FormBuilder-Question-Edit.png -------------------------------------------------------------------------------- /private/FormBuilder-Question-Save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/private/FormBuilder-Question-Save.png -------------------------------------------------------------------------------- /private/Forms-Manage-CollectData.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/private/Forms-Manage-CollectData.png -------------------------------------------------------------------------------- /private/ResearchSubjects-Create.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/private/ResearchSubjects-Create.png -------------------------------------------------------------------------------- /private/ResearchSubjects-List-Few.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/private/ResearchSubjects-List-Few.png -------------------------------------------------------------------------------- /public/images/home/forms-square.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/home/forms-square.jpg -------------------------------------------------------------------------------- /public/images/icons/Default_User.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/icons/Default_User.png -------------------------------------------------------------------------------- /public/images/landing/description.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/description.png -------------------------------------------------------------------------------- /public/images/landing/slider-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/slider-bg.png -------------------------------------------------------------------------------- /public/images/placeholder-240x240.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/placeholder-240x240.gif -------------------------------------------------------------------------------- /private/Data-Response-MoreComments.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/private/Data-Response-MoreComments.png -------------------------------------------------------------------------------- /private/HomePage-Study-SelectVisit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/private/HomePage-Study-SelectVisit.png -------------------------------------------------------------------------------- /private/ResearchSubjects-List-More.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/private/ResearchSubjects-List-More.png -------------------------------------------------------------------------------- /public/images/home/clinical-studies.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/home/clinical-studies.jpg -------------------------------------------------------------------------------- /public/images/icons/Default_Male_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/icons/Default_Male_1.png -------------------------------------------------------------------------------- /public/images/icons/Default_Male_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/icons/Default_Male_2.png -------------------------------------------------------------------------------- /public/images/landing/child-vaccine.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/child-vaccine.jpg -------------------------------------------------------------------------------- /public/images/landing/hero/flu-shot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/hero/flu-shot.jpg -------------------------------------------------------------------------------- /public/images/landing/slider/slide1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/slider/slide1.png -------------------------------------------------------------------------------- /public/images/landing/slider/slide2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/slider/slide2.png -------------------------------------------------------------------------------- /public/images/landing/slider/slide3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/slider/slide3.png -------------------------------------------------------------------------------- /public/images/landing/slider/slide4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/slider/slide4.png -------------------------------------------------------------------------------- /public/images/landing/slider/slide5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/slider/slide5.png -------------------------------------------------------------------------------- /private/Data-Response-CommentsResolved.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/private/Data-Response-CommentsResolved.png -------------------------------------------------------------------------------- /private/FormBuilder-SecondQuestion-Add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/private/FormBuilder-SecondQuestion-Add.png -------------------------------------------------------------------------------- /private/HomePage-Study-SelectSubject.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/private/HomePage-Study-SelectSubject.png -------------------------------------------------------------------------------- /private/ResearchSubjects-Create-Empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/private/ResearchSubjects-Create-Empty.png -------------------------------------------------------------------------------- /public/images/icons/Default_Female_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/icons/Default_Female_1.png -------------------------------------------------------------------------------- /public/images/icons/Default_Female_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/icons/Default_Female_2.png -------------------------------------------------------------------------------- /public/images/landing/clinicaltrials.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/clinicaltrials.jpg -------------------------------------------------------------------------------- /public/images/landing/injection-trial.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/injection-trial.jpeg -------------------------------------------------------------------------------- /private/FormBuilder-SecondQuestion-Save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/private/FormBuilder-SecondQuestion-Save.png -------------------------------------------------------------------------------- /public/images/errors/browserNotSupported.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/errors/browserNotSupported.png -------------------------------------------------------------------------------- /public/images/landing/icons/Default_User.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/icons/Default_User.png -------------------------------------------------------------------------------- /public/images/landing/slider/slide-left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/slider/slide-left.png -------------------------------------------------------------------------------- /public/images/landing/slider/slide-right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/slider/slide-right.png -------------------------------------------------------------------------------- /client/modals/tutorialModal.less: -------------------------------------------------------------------------------- 1 | #tutorialModal .modal{ 2 | z-index: 100000; 3 | } 4 | .instructions{ 5 | font-size: 150%; 6 | color: white; 7 | } 8 | -------------------------------------------------------------------------------- /client/workflow/errors/loadingPage.js: -------------------------------------------------------------------------------- 1 | Template.loadingPage.events({ 2 | 'click #notFoundErrorMessage':function(){ 3 | Router.go('/'); 4 | } 5 | }) 6 | -------------------------------------------------------------------------------- /public/images/landing/devices/device-ipad-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/devices/device-ipad-2.png -------------------------------------------------------------------------------- /public/images/landing/devices/device-ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/devices/device-ipad.png -------------------------------------------------------------------------------- /public/images/landing/devices/device-multi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/devices/device-multi.png -------------------------------------------------------------------------------- /public/images/landing/icons/Default_Male_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/icons/Default_Male_1.png -------------------------------------------------------------------------------- /public/images/landing/icons/Default_Male_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/icons/Default_Male_2.png -------------------------------------------------------------------------------- /public/images/landing/molecular_structures.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/molecular_structures.jpg -------------------------------------------------------------------------------- /public/images/landing/structural-genomics.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/structural-genomics.jpg -------------------------------------------------------------------------------- /public/images/landing/support-forum-on-ipad.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/support-forum-on-ipad.jpg -------------------------------------------------------------------------------- /public/images/landing/testimonials/abigail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/testimonials/abigail.jpg -------------------------------------------------------------------------------- /public/images/landing/devices/device-macbook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/devices/device-macbook.png -------------------------------------------------------------------------------- /public/images/landing/devices/device-multi-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/devices/device-multi-2.png -------------------------------------------------------------------------------- /public/images/landing/icons/Default_Female_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/icons/Default_Female_1.png -------------------------------------------------------------------------------- /public/images/landing/icons/Default_Female_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/icons/Default_Female_2.png -------------------------------------------------------------------------------- /client/workflow/errors/loadingPage.less: -------------------------------------------------------------------------------- 1 | #notFoundPage{ 2 | #notFoundImage{ 3 | padding-top: 20%; 4 | border-bottom: 1px solid lightgray; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /public/images/home/DataScientistJobDescriptions.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/home/DataScientistJobDescriptions.jpg -------------------------------------------------------------------------------- /public/images/landing/devices/hipaa-log-closeup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/devices/hipaa-log-closeup.png -------------------------------------------------------------------------------- /public/images/landing/devices/validation-testing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/devices/validation-testing.png -------------------------------------------------------------------------------- /public/images/landing/molecular_structures_hires.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/molecular_structures_hires.jpg -------------------------------------------------------------------------------- /client/workflow/.accounts/entryError/entryError.js: -------------------------------------------------------------------------------- 1 | 2 | Template.entryError.helpers({ 3 | error: function() { 4 | return Session.get('entryError'); 5 | } 6 | }); 7 | -------------------------------------------------------------------------------- /public/images/landing/devices/device-thunderbolt-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/devices/device-thunderbolt-2.png -------------------------------------------------------------------------------- /client/modals/studySearchModal.less: -------------------------------------------------------------------------------- 1 | #studySearch{ 2 | .list-group-item{ 3 | cursor: pointer; 4 | } 5 | .form-control{ 6 | margin-bottom: 10px; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /public/images/landing/devices/device-ipad-hipaa-log.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/devices/device-ipad-hipaa-log.png -------------------------------------------------------------------------------- /public/images/landing/devices/pixelmator.device-ipad.pxm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/devices/pixelmator.device-ipad.pxm -------------------------------------------------------------------------------- /public/images/landing/devices/pixelmator.device-multi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/devices/pixelmator.device-multi.png -------------------------------------------------------------------------------- /public/images/landing/devices/pixelmator.device-multi.pxm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/devices/pixelmator.device-multi.pxm -------------------------------------------------------------------------------- /public/images/landing/devices/pixelmator.device-macbook.pxm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/devices/pixelmator.device-macbook.pxm -------------------------------------------------------------------------------- /server/app.environment.js: -------------------------------------------------------------------------------- 1 | Meteor.methods({ 2 | getEnvironmentRoot: function(){ 3 | console.log(process.env.ROOT_URL); 4 | return process.env.ROOT_URL; 5 | } 6 | }); 7 | -------------------------------------------------------------------------------- /public/images/landing/devices/device-macbook-formbuilder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/devices/device-macbook-formbuilder.png -------------------------------------------------------------------------------- /public/images/landing/support-forum-on-thunderbold-monitor.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/support-forum-on-thunderbold-monitor.jpg -------------------------------------------------------------------------------- /public/images/landing/devices/pixelmator.device-thunderbolt.pxm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-on-fhir/clinical-trials/HEAD/public/images/landing/devices/pixelmator.device-thunderbolt.pxm -------------------------------------------------------------------------------- /packages/clinical-ui-modals/clinical-ui-modals-tests.js: -------------------------------------------------------------------------------- 1 | // Write your tests here! 2 | // Here is an example. 3 | Tinytest.add('example', function (test) { 4 | test.equal(true, true); 5 | }); 6 | -------------------------------------------------------------------------------- /client/workflow/errors/browserNotSupportedPage.less: -------------------------------------------------------------------------------- 1 | #browserNotSupportedPage{ 2 | #browserNotSupportedImage{ 3 | width: 100%; 4 | border-bottom: 1px solid lightgray; 5 | padding-top: 20% 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /client/workflow/comments/commentsEditPage.less: -------------------------------------------------------------------------------- 1 | #commentsEditPage{ 2 | .danger-striped .individualFormRow:hover{ 3 | cursor: pointer; 4 | background-color: #d9534f !important; 5 | color: white; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /client/workflow/subjects/subjectsEditPage.less: -------------------------------------------------------------------------------- 1 | #subjectsEditPage{ 2 | .danger-striped .individualFormRow:hover{ 3 | cursor: pointer; 4 | background-color: #d9534f !important; 5 | color: white; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /client/app/app.layout.html: -------------------------------------------------------------------------------- 1 | 2 | ClinicalTrials 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /packages/clinical-ui-modals/modals/confirm.js: -------------------------------------------------------------------------------- 1 | Template.confirmModal.events({ 2 | 'click #modalSaveButton':function(){ 3 | Session.set('inPageAlertType', 'success'); 4 | Session.set('inPageAlertText', 'success'); 5 | } 6 | }); 7 | -------------------------------------------------------------------------------- /server/studies.methods.js: -------------------------------------------------------------------------------- 1 | Meteor.methods({ 2 | removeVisitFromStudy: function(payload){ 3 | console.log(payload); 4 | return Studies.update({_id: payload.studyId}, {$pull:{ 5 | visits: payload.label 6 | }}); 7 | } 8 | }) 9 | -------------------------------------------------------------------------------- /client/modals/formSearch.less: -------------------------------------------------------------------------------- 1 | #formSearchModal{ 2 | .list-group-item{ 3 | cursor: pointer; 4 | } 5 | .list-group-item:hover{ 6 | background-color: #eeeeee; 7 | } 8 | ul{ 9 | margin-top: 20px !important; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /client/workflow/errors/app.errors.less: -------------------------------------------------------------------------------- 1 | #notFoundErrorMessage{ 2 | cursor: pointer; 3 | } 4 | .notFoundError{ 5 | font-size: 36px; 6 | color: #CCCCCC; 7 | } 8 | .notFoundErrorInstructions{ 9 | font-size: 18px; 10 | color: #aaaaaa; 11 | } -------------------------------------------------------------------------------- /client/modals/sponsorSearch.less: -------------------------------------------------------------------------------- 1 | #sponsorSearchModal{ 2 | .list-group-item{ 3 | cursor: pointer; 4 | } 5 | .list-group-item:hover{ 6 | background-color: #eeeeee; 7 | } 8 | ul{ 9 | margin-top: 20px !important; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /client/modals/subjectSearch.less: -------------------------------------------------------------------------------- 1 | #subjectSearchModal{ 2 | .list-group-item{ 3 | cursor: pointer; 4 | } 5 | .list-group-item:hover{ 6 | background-color: #eeeeee; 7 | } 8 | ul{ 9 | margin-top: 20px !important; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /client/workflow/.accounts/entryError/entryError.html: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /packages/clinical-ui-modals/modals/selectRole.less: -------------------------------------------------------------------------------- 1 | #selectRoleModal{ 2 | .list-group-item{ 3 | cursor: pointer; 4 | } 5 | .list-group-item:hover{ 6 | background-color: #eeeeee; 7 | } 8 | ul{ 9 | margin-top: 20px !important; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /client/workflow/data/dataBlockPreview.less: -------------------------------------------------------------------------------- 1 | .item{ 2 | cursor: pointer; 3 | border-bottom: 1px solid lightgray; 4 | } 5 | 6 | #dataBlockPreview{ 7 | .data-value{ 8 | margin-left: 11px; 9 | } 10 | } 11 | // .item{ 12 | // border-top: 1px solid #eeeeee; 13 | // } 14 | -------------------------------------------------------------------------------- /shared/objects/SimpleRationalRanks.js: -------------------------------------------------------------------------------- 1 | SimpleRationalRanks = { 2 | beforeFirst: function (firstRank) { return firstRank - 1; }, 3 | between: function (beforeRank, afterRank) { return (beforeRank + afterRank) / 2; }, 4 | afterLast: function (lastRank) { return lastRank + 1; } 5 | }; 6 | -------------------------------------------------------------------------------- /client/workflow/alerts/inPageAlert.html: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /client/app/app.startup.js: -------------------------------------------------------------------------------- 1 | Session.setDefault('resize', null); 2 | 3 | Meteor.startup(function(){ 4 | Session.set("glassOpacity", 1); 5 | 6 | $(window).resize(function(evt) { 7 | Session.set("resize", new Date()); 8 | }); 9 | 10 | bowser = BrowserObserver.init(); 11 | }); 12 | -------------------------------------------------------------------------------- /client/workflow/alerts/inPageAlert.less: -------------------------------------------------------------------------------- 1 | // .hidden{ 2 | // visibility: hidden; 3 | // } 4 | // .visible{ 5 | // visibility: visible; 6 | // } 7 | // #inPageAlert{ 8 | // cursor: pointer; 9 | // } 10 | // .horizontally-padded{ 11 | // padding-left: 10px; 12 | // padding-right: 10px; 13 | // } 14 | -------------------------------------------------------------------------------- /client/clinical.ui.syntax.less: -------------------------------------------------------------------------------- 1 | .padded{ 2 | padding: 10px; 3 | } 4 | .fullwidth{ 5 | width: 100%; 6 | } 7 | li{ 8 | cursor: pointer; 9 | } 10 | .with-right-margin{ 11 | margin-right: 20px; 12 | } 13 | .page{ 14 | padding-bottom: 80px; 15 | } 16 | 17 | .panel-heading{ 18 | padding: 10px 15px !important; 19 | } -------------------------------------------------------------------------------- /client/workflow/subjects/subjectsListPage.less: -------------------------------------------------------------------------------- 1 | /* CSS declarations go here */ 2 | #subjectsListPage, #usersListPage{ 3 | .customerRow:hover{ 4 | background-color: #fcdfdf !important; 5 | cursor: pointer; 6 | } 7 | 8 | #tableOfStudyForms{ 9 | tr{ 10 | cursor: pointer; 11 | } 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /.meteor/.id: -------------------------------------------------------------------------------- 1 | # This file contains a token that is unique to your project. 2 | # Check it into your repository along with the rest of this directory. 3 | # It can be used for purposes such as: 4 | # - ensuring you don't accidentally deploy one app on top of another 5 | # - providing package authors with aggregated statistics 6 | 7 | 1pv9idtw4o7v3imfkh6 8 | -------------------------------------------------------------------------------- /client/app/app.subscriptions.js: -------------------------------------------------------------------------------- 1 | Deps.autorun(function(){ 2 | Meteor.subscribe('items'); 3 | Meteor.subscribe('forms'); 4 | Meteor.subscribe('data'); 5 | Meteor.subscribe('studies'); 6 | Meteor.subscribe('sponsors'); 7 | Meteor.subscribe('subjects'); 8 | Meteor.subscribe('comments'); 9 | Meteor.subscribe('usersDirectory'); 10 | }); 11 | -------------------------------------------------------------------------------- /packages/.gitignore: -------------------------------------------------------------------------------- 1 | /bootstrap-3 2 | /iron-router 3 | /blaze-layout 4 | /event-hooks 5 | /browser-detection 6 | /auto-nprogress 7 | /nprogress 8 | /mousetrap 9 | /bowser 10 | /font-awesome 11 | /session-extended-api 12 | /roles 13 | /selenium-nightwatch 14 | /moment 15 | /iron-layout 16 | /iron-core 17 | /iron-dynamic-template 18 | /clinical-ui-hipaa-log 19 | -------------------------------------------------------------------------------- /client/workflow/studies/studiesEditPage.less: -------------------------------------------------------------------------------- 1 | #studiesEditPage{ 2 | .danger-striped .individualFormRow:hover{ 3 | cursor: pointer; 4 | background-color: #d9534f !important; 5 | color: white; 6 | } 7 | .danger-striped .visitLabel:hover{ 8 | cursor: pointer; 9 | background-color: #d9534f !important; 10 | color: white; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /client/app/panels/westPanel.less: -------------------------------------------------------------------------------- 1 | #westPanel{ 2 | .with-bottom-margin{ 3 | margin-bottom: 10px; 4 | } 5 | .list-group-item{ 6 | .form-control{ 7 | margin-bottom: 10px; 8 | } 9 | } 10 | .multiselectInput{ 11 | display: inline; 12 | margin-right: 10px !important; 13 | max-width: 180px; 14 | } 15 | .multiselectRemove{ 16 | top: -1px; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /client/workflow/.accounts/accountButtons/accountButtons.js: -------------------------------------------------------------------------------- 1 | 2 | Template.entryAccountButtons.helpers({ 3 | profileUrl: function() { 4 | if (AccountsEntry.settings.profileRoute) { 5 | return AccountsEntry.settings.profileRoute; 6 | }else{ 7 | return false; 8 | } 9 | }, 10 | wrapLinks: function() { 11 | return AccountsEntry.settings.wrapLinks; 12 | } 13 | }); 14 | -------------------------------------------------------------------------------- /client/app/app.entry.js: -------------------------------------------------------------------------------- 1 | Accounts.ui.config({ 2 | passwordSignupFields: 'USERNAME_AND_OPTIONAL_EMAIL' 3 | }); 4 | 5 | Meteor.startup(function() { 6 | // return AccountsEntry.config({ 7 | // privacyUrl: '/privacy-policy', 8 | // termsUrl: '/terms-of-use', 9 | // homeRoute: '/', 10 | // dashboardRoute: '/', 11 | // profileRoute: 'profile', 12 | // showSignupCode: true 13 | // }); 14 | }); 15 | -------------------------------------------------------------------------------- /client/workflow/sponsors/sponsorsPage.less: -------------------------------------------------------------------------------- 1 | #visitorsPage { 2 | 3 | } 4 | 5 | // tablet landscape orientation 6 | @media only screen and (min-width: 768px) { 7 | #visitorsPage { 8 | 9 | } 10 | } 11 | 12 | // tablet portrait orientation 13 | @media only screen and (max-width: 768px) { 14 | #visitorsPage { 15 | 16 | } 17 | } 18 | 19 | // phone/watch 20 | @media only screen and (max-width: 480px) { 21 | #visitorsPage { 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /client/ActiveEntry.js: -------------------------------------------------------------------------------- 1 | Meteor.startup(function (){ 2 | ActiveEntry.configure({ 3 | passwordSignupFields: 'EMAIL_ONLY', 4 | logo: { 5 | url: "appIcon-transparent-medium-teal.png", 6 | displayed: false 7 | }, 8 | signIn: { 9 | displayFullName: true, 10 | destination: "/" 11 | }, 12 | signUp: { 13 | destination: "/" 14 | }, 15 | themeColors: { 16 | primary: "" 17 | } 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /shared/objects/ClinicalTrials.js: -------------------------------------------------------------------------------- 1 | ClinicalTrials = { 2 | isAdminedBy: function(userId){ 3 | var user = Meteor.users.findOne(userId); 4 | // we need to use == instead of === because we're comparing a String to an array value 5 | if((user.profile.roles[0] == "Admin") || (user.profile.roles[0] == "SysAdmin")){ 6 | return true; 7 | }else{ 8 | return false; 9 | } 10 | }, 11 | checkForHexCode: new RegExp("^[0-9a-fA-F]{24}$") 12 | }; 13 | -------------------------------------------------------------------------------- /client/workflow/.accounts/entrySocial/entrySocial.html: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /client/app/navbars/navbarFooter.less: -------------------------------------------------------------------------------- 1 | 2 | #navbarFooter{ 3 | .navbar{ 4 | margin-bottom: 0px; 5 | } 6 | } 7 | 8 | 9 | 10 | // landscape orientation 11 | @media only screen and (min-width: 768px) { 12 | #navbarFooter{ 13 | 14 | 15 | } 16 | } 17 | 18 | // portrait orientation 19 | @media only screen and (max-width: 768px) { 20 | #navbarFooter{ 21 | 22 | 23 | } 24 | } 25 | @media only screen and (max-width: 480px) { 26 | #navbarFooter{ 27 | 28 | 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /client/workflow/.accounts/entryError/entryError.less: -------------------------------------------------------------------------------- 1 | // default desktop view 2 | #entryError{ 3 | 4 | } 5 | 6 | // landscape orientation view for tablets 7 | @media only screen and (min-width: 768px) { 8 | #entryError{ 9 | 10 | } 11 | } 12 | 13 | // portrait orientation view for tablets 14 | @media only screen and (max-width: 768px) { 15 | #entryError{ 16 | 17 | } 18 | } 19 | // phone view 20 | @media only screen and (max-width: 480px) { 21 | #entryError{ 22 | 23 | } 24 | } -------------------------------------------------------------------------------- /client/workflow/.accounts/entrySocial/entrySocial.less: -------------------------------------------------------------------------------- 1 | // default desktop view 2 | #entrySocial{ 3 | 4 | } 5 | 6 | // landscape orientation view for tablets 7 | @media only screen and (min-width: 768px) { 8 | #entrySocial{ 9 | 10 | } 11 | } 12 | 13 | // portrait orientation view for tablets 14 | @media only screen and (max-width: 768px) { 15 | #entrySocial{ 16 | 17 | } 18 | } 19 | // phone view 20 | @media only screen and (max-width: 480px) { 21 | #entrySocial{ 22 | 23 | } 24 | } -------------------------------------------------------------------------------- /client/workflow/home/homePage.less: -------------------------------------------------------------------------------- 1 | #homePage{ 2 | margin-top: 40px; 3 | 4 | .panel{ 5 | cursor: pointer; 6 | label{ 7 | cursor: pointer; 8 | } 9 | } 10 | #activeStudiesTile{ 11 | min-height: 200px; 12 | } 13 | } 14 | 15 | 16 | #zoomInstructions{ 17 | bottom: 0px; 18 | left: 0px; 19 | position: absolute; 20 | text-align: center; 21 | width: 100%; 22 | font-size: 18px; 23 | padding-bottom: 60px; 24 | cursor: pointer; 25 | z-index: -1; 26 | } 27 | -------------------------------------------------------------------------------- /client/workflow/.accounts/resetPassword/resetPassword.less: -------------------------------------------------------------------------------- 1 | // default desktop view 2 | #resetPassword{ 3 | 4 | } 5 | 6 | // landscape orientation view for tablets 7 | @media only screen and (min-width: 768px) { 8 | #resetPassword{ 9 | 10 | } 11 | } 12 | 13 | // portrait orientation view for tablets 14 | @media only screen and (max-width: 768px) { 15 | #resetPassword{ 16 | 17 | } 18 | } 19 | // phone view 20 | @media only screen and (max-width: 480px) { 21 | #resetPassword{ 22 | 23 | } 24 | } -------------------------------------------------------------------------------- /client/workflow/.accounts/forgotPassword/forgotPassword.less: -------------------------------------------------------------------------------- 1 | // default desktop view 2 | #forgotPassword{ 3 | 4 | } 5 | 6 | // landscape orientation view for tablets 7 | @media only screen and (min-width: 768px) { 8 | #forgotPassword{ 9 | 10 | } 11 | } 12 | 13 | // portrait orientation view for tablets 14 | @media only screen and (max-width: 768px) { 15 | #forgotPassword{ 16 | 17 | } 18 | } 19 | // phone view 20 | @media only screen and (max-width: 480px) { 21 | #forgotPassword{ 22 | 23 | } 24 | } -------------------------------------------------------------------------------- /client/workflow/.accounts/entrySignUp/entrySignUpPage.less: -------------------------------------------------------------------------------- 1 | // default desktop view 2 | #entrySignUpPage{ 3 | 4 | } 5 | 6 | // landscape orientation view for tablets 7 | @media only screen and (min-width: 768px) { 8 | #entrySignUpPage{ 9 | 10 | } 11 | } 12 | 13 | // portrait orientation view for tablets 14 | @media only screen and (max-width: 768px) { 15 | #entrySignUpPage{ 16 | 17 | } 18 | } 19 | // phone view 20 | @media only screen and (max-width: 480px) { 21 | #entrySignUpPage{ 22 | 23 | } 24 | } -------------------------------------------------------------------------------- /client/app/navbars/navbarHeader.less: -------------------------------------------------------------------------------- 1 | 2 | #navbarHeader{ 3 | #navbarBrandLink{ 4 | cursor: pointer; 5 | min-width: 130px; 6 | } 7 | } 8 | 9 | 10 | 11 | // landscape orientation 12 | @media only screen and (min-width: 768px) { 13 | #navbarHeader{ 14 | 15 | 16 | } 17 | } 18 | 19 | // portrait orientation 20 | @media only screen and (max-width: 768px) { 21 | #navbarHeader{ 22 | 23 | 24 | } 25 | } 26 | @media only screen and (max-width: 480px) { 27 | #navbarHeader{ 28 | 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /client/workflow/.accounts/accountButtons/accountButtons.less: -------------------------------------------------------------------------------- 1 | // default desktop view 2 | #accountButtons{ 3 | 4 | } 5 | 6 | // landscape orientation view for tablets 7 | @media only screen and (min-width: 768px) { 8 | #accountButtons{ 9 | 10 | } 11 | } 12 | 13 | // portrait orientation view for tablets 14 | @media only screen and (max-width: 768px) { 15 | #accountButtons{ 16 | 17 | } 18 | } 19 | // phone view 20 | @media only screen and (max-width: 480px) { 21 | #accountButtons{ 22 | 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /client/app/app.events.js: -------------------------------------------------------------------------------- 1 | Meteor.startup(function(){ 2 | Hooks.init(); 3 | 4 | Hooks.onLoggedIn = function(){ 5 | Session.set('defaultUserProfileCard', 'basicInfoCard'); 6 | // removeWallpaper(); 7 | }; 8 | Hooks.onLoggedOut = function(userId){ 9 | }; 10 | Hooks.onCreateUser = function(userId){ 11 | 12 | }; 13 | Hooks.onDeleteUser = function(userId){ 14 | 15 | }; 16 | Hooks.onLoseFocus = function(userId){ 17 | 18 | }; 19 | Hooks.onGainFocus = function(userId){ 20 | 21 | }; 22 | Hooks.onCloseSession = function(userId){ 23 | 24 | }; 25 | }); 26 | -------------------------------------------------------------------------------- /.meteor/.finished-upgraders: -------------------------------------------------------------------------------- 1 | # This file contains information which helps Meteor properly upgrade your 2 | # app when you run 'meteor update'. You should check it into version control 3 | # with your project. 4 | 5 | notices-for-0.9.0 6 | notices-for-0.9.1 7 | 0.9.4-platform-file 8 | notices-for-facebook-graph-api-2 9 | 1.2.0-standard-minifiers-package 10 | 1.2.0-meteor-platform-split 11 | 1.2.0-cordova-changes 12 | 1.2.0-breaking-changes 13 | 1.3.0-split-minifiers-package 14 | 1.4.0-remove-old-dev-bundle-link 15 | 1.4.1-add-shell-server-package 16 | 1.4.3-split-account-service-packages 17 | -------------------------------------------------------------------------------- /client/workflow/data/dataListPage.less: -------------------------------------------------------------------------------- 1 | /* CSS declarations go here */ 2 | #dataListPage{ 3 | .dataRow:hover{ 4 | background-color: #fcdfdf !important; 5 | cursor: pointer; 6 | } 7 | 8 | 9 | .hidden{ 10 | visibility: hidden; 11 | } 12 | .visible{ 13 | visibility: visible; 14 | } 15 | .fullwidth{ 16 | width: 100%; 17 | } 18 | .centered{ 19 | text-align: center; 20 | } 21 | 22 | .tablesorter-headerRow{ 23 | cursor: pointer; 24 | } 25 | 26 | .getTheCode{ 27 | position: relative; 28 | top: 30px !important; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /client/Theme.js: -------------------------------------------------------------------------------- 1 | Meteor.startup(function (){ 2 | Theme.configure({ 3 | appTitle: "Checklist Manifesto", 4 | background: { 5 | color: "gradient" 6 | }, 7 | page: { 8 | background: "#ffffff" 9 | }, 10 | palette: { 11 | colorA: "#01b9af", 12 | colorB: "#00938b", 13 | colorC: "#f3f3f3", 14 | colorD: "#52565f", 15 | colorE: "#e7e7e7" 16 | }, 17 | brand: { 18 | primary: "#01b9af", 19 | success: "#00938b", 20 | info: "#f3f3f3", 21 | warning: "#52565f", 22 | danger: "#40434E" 23 | } 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /packages/clinical-ui-modals/modals/removeUser.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | Template.removeUserModal.events({ 4 | 'click #confirmRemoveUserButton':function(){ 5 | console.log('removing user ', Session.get('selectedUser')); 6 | var user = Meteor.users.findOne({_id: Session.get('selectedUser')}) 7 | if($('#removeUserModalInput').val() === user.username){ 8 | Meteor.call('removeUser', Session.get('selectedUser'), function(error, result){ 9 | if(result){ 10 | Session.set('selectedUser', null); 11 | Router.go('/users'); 12 | } 13 | }) 14 | } 15 | } 16 | }); 17 | -------------------------------------------------------------------------------- /client/workflow/builder/builderPage.html: -------------------------------------------------------------------------------- 1 | 19 | -------------------------------------------------------------------------------- /client/workflow/errors/noEmployerSetErrorPage.html: -------------------------------------------------------------------------------- 1 | 17 | -------------------------------------------------------------------------------- /client/workflow/alerts/inPageAlert.js: -------------------------------------------------------------------------------- 1 | 2 | //------------------------------------------------------- 3 | 4 | Template.inPageAlert.inPageAlertType = function(){ 5 | return "success"; 6 | }; 7 | Template.inPageAlert.inPageAlertText = function(){ 8 | return Session.get('inPageAlertText'); 9 | }; 10 | Session.setDefault('inPageAlertType', false); 11 | Session.setDefault('inPageAlertText', "Success!"); 12 | Template.inPageAlert.inPageAlertVisibility = function(){ 13 | if(Session.get('inPageAlertType')){ 14 | return 'visible'; 15 | }else{ 16 | return "hidden"; 17 | } 18 | }; 19 | Template.inPageAlert.events({ 20 | 'click #inPageAlert':function(){ 21 | Session.set('inPageAlertType', false); 22 | } 23 | }); 24 | -------------------------------------------------------------------------------- /client/workflow/errors/loadingPage.html: -------------------------------------------------------------------------------- 1 | 18 | -------------------------------------------------------------------------------- /tests/app.layout.js: -------------------------------------------------------------------------------- 1 | // add tests to this file using the Nightwatch.js API 2 | // http://nightwatchjs.org/api 3 | 4 | module.exports = { 5 | "App Layout" : function (client) { 6 | client 7 | .url("http://localhost:3000") 8 | .waitForElementVisible("body", 1000) 9 | 10 | .verify.elementPresent('#navbarHeader') 11 | .verify.elementPresent('#navbarHeaderNav') 12 | .verify.elementPresent('#navbarBrandLink') 13 | 14 | .verify.elementPresent('#westPanel') 15 | .verify.elementPresent('#appLayout') 16 | .verify.elementPresent('#mainPanel') 17 | .verify.elementPresent('#navbarHeader') 18 | 19 | .verify.elementPresent('#navbarFooter') 20 | 21 | .end(); 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /packages/clinical-ui-modals/modals/selectRole.js: -------------------------------------------------------------------------------- 1 | Session.setDefault('selectRoleFilter', ''); 2 | Session.setDefault('selectedRole', null); 3 | 4 | 5 | 6 | Template.selectRoleModal.events({ 7 | 'click .list-group-item':function(){ 8 | Session.set('selectedRole', this); 9 | }, 10 | 'keyup #selectRoleModalInput':function(){ 11 | Session.set('selectRoleFilter', $('#selectRoleModalInput').val()); 12 | } 13 | }); 14 | 15 | Template.selectRoleModal.helpers({ 16 | rolesList: function() { 17 | return Meteor.roles.find({name: { 18 | $regex: Session.get('selectRoleFilter'), 19 | $options: 'i' 20 | }}); 21 | }, 22 | getSearchTerm: function(){ 23 | return Session.get('selectRoleFilter'); 24 | } 25 | }); -------------------------------------------------------------------------------- /client/workflow/.accounts/entry.js: -------------------------------------------------------------------------------- 1 | 2 | AccountsEntry = { 3 | settings: { 4 | wrapLinks: true, 5 | homeRoute: '/home', 6 | dashboardRoute: '/dashboard' 7 | }, 8 | config: function(appConfig) { 9 | this.settings = _.extend(this.settings, appConfig); 10 | // if (appConfig.signUpTemplate) { 11 | // Router.routes = _.reject(Router.routes, function(e, i) { 12 | // return e.name === 'entrySignUpPage'; 13 | // }); 14 | // return Router.map(function() { 15 | // return this.route('signUp', { 16 | // path: 'sign-up', 17 | // template: appConfig.signUpTemplate 18 | // }); 19 | // }); 20 | // } 21 | } 22 | }; 23 | 24 | this.AccountsEntry = AccountsEntry; 25 | -------------------------------------------------------------------------------- /client/workflow/forms/formPreviewPage.html: -------------------------------------------------------------------------------- 1 | 24 | -------------------------------------------------------------------------------- /client/workflow/users/userEditPage/userPreferencesCard.html: -------------------------------------------------------------------------------- 1 | 19 | -------------------------------------------------------------------------------- /client/workflow/landing/landingPage.less: -------------------------------------------------------------------------------- 1 | 2 | 3 | #landingPage{ 4 | .browsers{ 5 | padding-top: 150px; 6 | } 7 | 8 | .userCounter{ 9 | font-size: 40px; 10 | width: 100%; 11 | } 12 | .userCounterBox{ 13 | //border: 1px solid red; 14 | } 15 | .userCounterCenter{ 16 | border: 1px solid orange; 17 | } 18 | .fa-users{ 19 | position: absolute; 20 | font-size: 26px; 21 | margin-top: 10px; 22 | margin-left: 20px; 23 | } 24 | .screenshot-tile{ 25 | cursor: pointer; 26 | } 27 | .screenshot-fullsize{ 28 | width: 100%; 29 | } 30 | .userCountText{ 31 | font-size: 26px; 32 | position: relative; 33 | top: -5px !important; 34 | margin-left: 20px; 35 | } 36 | 37 | padding-bottom: 50px; 38 | } 39 | -------------------------------------------------------------------------------- /client/workflow/.accounts/entrySignIn/entrySignInPage.less: -------------------------------------------------------------------------------- 1 | // default desktop view 2 | #entrySignInPage{ 3 | .totalInteractionsLabel{ 4 | padding-top: 20px; 5 | padding-left: 20px; 6 | color: gray; 7 | 8 | } 9 | .entry-background{ 10 | position: fixed; 11 | bottom: -20%; 12 | left: -5%; 13 | width: 110%; 14 | z-index: -1; 15 | opacity: 0.1; 16 | } 17 | } 18 | 19 | // landscape orientation view for tablets 20 | @media only screen and (min-width: 768px) { 21 | #entrySignInPage{ 22 | 23 | } 24 | } 25 | 26 | // portrait orientation view for tablets 27 | @media only screen and (max-width: 768px) { 28 | #entrySignInPage{ 29 | 30 | } 31 | } 32 | // phone view 33 | @media only screen and (max-width: 480px) { 34 | #entrySignInPage{ 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/clinical-ui-modals/modals/prompt.html: -------------------------------------------------------------------------------- 1 | 2 | 21 | -------------------------------------------------------------------------------- /client/modals/subjectSearch.js: -------------------------------------------------------------------------------- 1 | Session.setDefault('subjectSearchFilter', ''); 2 | Session.setDefault('selectedSubject', null); 3 | 4 | 5 | Template.subjectSearchModal.events({ 6 | 'click .list-group-item':function(){ 7 | Session.set('selectedSubject', { 8 | _id: this._id, 9 | name: this.name 10 | }); 11 | }, 12 | 'keyup #subjectSearchModalInput':function(){ 13 | Session.set('subjectSearchFilter', $('#subjectSearchModalInput').val()); 14 | } 15 | }); 16 | 17 | Template.subjectSearchModal.helpers({ 18 | subjectList: function() { 19 | return Subjects.find({name: { 20 | $regex: Session.get('subjectSearchFilter'), 21 | $options: 'i', 22 | $ne: 'Default Subject' 23 | }}); 24 | }, 25 | getSearchTerm: function(){ 26 | return Session.get('subjectSearchFilter'); 27 | } 28 | }); -------------------------------------------------------------------------------- /client/workflow/.accounts/resetPassword/resetPassword.js: -------------------------------------------------------------------------------- 1 | 2 | Template.entryResetPassword.helpers({ 3 | error: function() { 4 | return Session.get('entryError'); 5 | }, 6 | logo: function() { 7 | return Meteor.call('entryLogo'); 8 | } 9 | }); 10 | 11 | Template.entryResetPassword.events({ 12 | 'submit #resetPassword': function(event) { 13 | var password; 14 | event.preventDefault(); 15 | password = $('input[type="password"]').val(); 16 | return Accounts.resetPassword(Session.get('resetToken'), password, function(error) { 17 | if (error) { 18 | return Session.set('entryError', error.reason || "Unknown error"); 19 | } else { 20 | Session.set('resetToken', null); 21 | return Router.go(AccountsEntry.settings.dashboardRoute); 22 | } 23 | }); 24 | } 25 | }); 26 | -------------------------------------------------------------------------------- /client/modals/sponsorSearch.js: -------------------------------------------------------------------------------- 1 | Session.setDefault('sponsorSearchFilter', ''); 2 | Session.setDefault('selectedSponsor', null); 3 | 4 | 5 | Template.sponsorSearchModal.events({ 6 | 'click .list-group-item':function(){ 7 | Session.set('selectedSponsor', { 8 | _id: this._id, 9 | name: this.name 10 | }); 11 | }, 12 | 'keyup #sponsorSearchModalInput':function(){ 13 | Session.set('sponsorSearchFilter', $('#sponsorSearchModalInput').val()); 14 | } 15 | }); 16 | 17 | 18 | Template.sponsorSearchModal.helpers({ 19 | sponsorList: function() { 20 | return Sponsors.find({name: { 21 | $regex: Session.get('sponsorSearchFilter'), 22 | $options: 'i', 23 | $ne: 'Default Sponsor' 24 | }}); 25 | }, 26 | getSearchTerm: function(){ 27 | return Session.get('sponsorSearchFilter'); 28 | } 29 | }); -------------------------------------------------------------------------------- /client/workflow/comments/commentsRecordPage.html: -------------------------------------------------------------------------------- 1 | 29 | -------------------------------------------------------------------------------- /client/workflow/errors/browserNotSupportedPage.html: -------------------------------------------------------------------------------- 1 | 18 | -------------------------------------------------------------------------------- /client/workflow/subjects/subjectsRecordPage.html: -------------------------------------------------------------------------------- 1 | 30 | -------------------------------------------------------------------------------- /client/workflow/subjects/subjectsRecordPage.js: -------------------------------------------------------------------------------- 1 | 2 | Router.map(function(){ 3 | this.route('subjectsRecordPage', { 4 | path: '/subjects/:id', 5 | template: 'subjectsRecordPage', 6 | onWait: function(){ 7 | return Meteor.subscribe('subjects'); 8 | }, 9 | data: function () { 10 | Session.set('currentForm', this.params.id); 11 | return Subjects.findOne({_id: this.params.id}); 12 | }, 13 | }); 14 | }); 15 | Template.subjectsRecordPage.events({ 16 | 'click #editSubjectButton':function(){ 17 | Router.go('/edit/subject/' + this._id); 18 | }, 19 | 'click #subjectDeleteButton':function(){ 20 | if(confirm('Are you sure you want to delete ' + this._id + "?")){ 21 | Subjects.remove({_id: this._id}); 22 | Router.go('/'); 23 | } 24 | } 25 | }); 26 | 27 | Template.subjectsRecordPage.helpers({ 28 | 29 | }); 30 | -------------------------------------------------------------------------------- /server/app.publications.js: -------------------------------------------------------------------------------- 1 | // Meteor.publish('items', function(){ 2 | // return Items.find(); 3 | // }); 4 | Meteor.publish('forms', function(){ 5 | return Forms.find(); 6 | }); 7 | Meteor.publish('data', function(){ 8 | return Data.find(); 9 | }); 10 | 11 | Meteor.publish('studies', function(){ 12 | return Studies.find(); 13 | }); 14 | Meteor.publish('sponsors', function(){ 15 | return Sponsors.find(); 16 | }); 17 | Meteor.publish('subjects', function(){ 18 | return Subjects.find(); 19 | }); 20 | Meteor.publish('comments', function(){ 21 | return Comments.find(); 22 | }); 23 | Meteor.publish('usersDirectory', function(){ 24 | return Meteor.users.find(); 25 | }); 26 | Meteor.publish('userProfile', function(userId){ 27 | return Meteor.users.find({_id: userId}); 28 | }); 29 | 30 | 31 | Meteor.publish(null, function (){ 32 | return Meteor.roles.find(); 33 | }); 34 | -------------------------------------------------------------------------------- /client/workflow/.accounts/forgotPassword/forgotPassword.js: -------------------------------------------------------------------------------- 1 | 2 | Template.entryForgotPassword.helpers({ 3 | error: function() { 4 | return Session.get('entryError'); 5 | }, 6 | logo: function() { 7 | return Meteor.call('entryLogo'); 8 | } 9 | }); 10 | 11 | Template.entryForgotPassword.events({ 12 | 'submit #forgotPassword': function(event) { 13 | event.preventDefault(); 14 | Session.set('email', $('input[type="email"]').val()); 15 | if (Session.get('email').length === 0) { 16 | Session.set('entryError', 'Email is required'); 17 | return; 18 | } 19 | return Accounts.forgotPassword({ 20 | email: Session.get('email') 21 | }, function(error) { 22 | if (error) { 23 | return Session.set('entryError', error.reason); 24 | } else { 25 | return Router.go(AccountsEntry.settings.homeRoute); 26 | } 27 | }); 28 | } 29 | }); 30 | -------------------------------------------------------------------------------- /client/modals/studySearchModal.js: -------------------------------------------------------------------------------- 1 | Session.setDefault('campaignSearchFilter', ''); 2 | Session.setDefault('selectedCampaign', null); 3 | 4 | Template.studySearchModal.helpers({ 5 | studysList: function(){ 6 | return Campaigns.find({name: { 7 | $regex: Session.get('studySearchFilter'), 8 | $options: 'i', 9 | $ne: "Default Deployment" 10 | }}); 11 | }, 12 | getCampaignCount: function(){ 13 | return Campaigns.find().count(); 14 | }, 15 | getSearchTerm: function(){ 16 | return Session.get('studySearchFilter'); 17 | } 18 | }); 19 | 20 | 21 | Template.studySearchModal.events({ 22 | 'click .list-group-item':function(){ 23 | Session.set('selectedCampaign', { 24 | _id: this._id, 25 | name: this.name 26 | }); 27 | }, 28 | 'keyup #studySearchModalInput':function(){ 29 | Session.set('studySearchFilter', $('#studySearchModalInput').val()); 30 | } 31 | }); 32 | -------------------------------------------------------------------------------- /client/app/app.dragdrop.js: -------------------------------------------------------------------------------- 1 | Session.setDefault('movedElementId', null); 2 | Session.setDefault('mouseMoveElementId', 'Hello Dropzones!'); 3 | Session.setDefault('mouseMoveX', 0); 4 | Session.setDefault('mouseMoveY', 0); 5 | 6 | Template.appLayout.rendered = function(){ 7 | $(document).mousemove(function (e) { 8 | Session.set('movedElementId', e.target.id); 9 | Session.set('mouseMoveX', e.clientX); 10 | Session.set('mouseMoveY', e.clientY); 11 | //Session.set('mouseMoveElementId', document.elementFromPoint(e.clientX,e.clientY)); 12 | }); 13 | 14 | $('.dragDropBlock').draggable({ 15 | revert: true, 16 | revertDuration: 5, 17 | stop: function(event, ui){ 18 | //console.log(document.querySelectorAll( ":hover" )); 19 | console.log(document.elementFromPoint(Session.get('mouseMoveX'),Session.get('mouseMoveY')).id) 20 | } 21 | //grid: [ 10, 10 ], 22 | //opacity: 0.35 23 | }); 24 | }; 25 | -------------------------------------------------------------------------------- /packages/clinical-ui-modals/modals/confirm.html: -------------------------------------------------------------------------------- 1 | 2 | 22 | -------------------------------------------------------------------------------- /client/workflow/comments/commentsRecordPage.js: -------------------------------------------------------------------------------- 1 | 2 | Router.map(function(){ 3 | this.route('commentsRecordPage', { 4 | path: '/comments/:id', 5 | template: 'commentsRecordPage', 6 | onWait: function(){ 7 | return Meteor.subscribe('comments'); 8 | }, 9 | data: function () { 10 | Session.set('currentForm', this.params.id); 11 | return Comments.findOne({_id: this.params.id}); 12 | }, 13 | }); 14 | }); 15 | Template.commentsRecordPage.events({ 16 | 'click #editCommentButton':function(){ 17 | Router.go('/edit/comment/' + this._id); 18 | }, 19 | 'click #subjectDeleteButton':function(){ 20 | if(confirm('Are you sure you want to delete ' + this._id + "?")){ 21 | Comments.remove({_id: this._id}); 22 | Router.go('/'); 23 | } 24 | } 25 | }); 26 | 27 | Template.commentsRecordPage.helpers({ 28 | getTitle:function(){ 29 | if(this.title){ 30 | return this.title; 31 | }else{ 32 | return "---"; 33 | } 34 | } 35 | }); 36 | -------------------------------------------------------------------------------- /client/workflow/.accounts/resetPassword/resetPassword.html: -------------------------------------------------------------------------------- 1 | 27 | -------------------------------------------------------------------------------- /client/workflow/.accounts/forgotPassword/forgotPassword.html: -------------------------------------------------------------------------------- 1 | 27 | -------------------------------------------------------------------------------- /client/workflow/home/imagePanel.less: -------------------------------------------------------------------------------- 1 | @import url("http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css"); 2 | .panel-image { 3 | position: relative; 4 | } 5 | .panel-image img.panel-image-preview { 6 | width: 100%; 7 | border-radius: 4px 4px 0px 0px; 8 | } 9 | 10 | .panel-image label { 11 | display: block; 12 | position: absolute; 13 | top: 0px; 14 | left: 0px; 15 | height: 100%; 16 | width: 100%; 17 | } 18 | 19 | .panel-heading ~ .panel-image img.panel-image-preview { 20 | border-radius: 0px; 21 | } 22 | 23 | .panel-body { 24 | overflow: hidden; 25 | } 26 | 27 | .panel-image ~ input[type=checkbox] { 28 | position:absolute; 29 | top:- 30px; 30 | z-index: -1; 31 | } 32 | 33 | .panel-image ~ input[type=checkbox] ~ .panel-body { 34 | height: 0px; 35 | padding: 0px; 36 | } 37 | 38 | .panel-image ~ input[type=checkbox]:checked ~ .panel-body { 39 | height: auto; 40 | padding: 15px; 41 | } 42 | 43 | .panel-image ~ .panel-footer a { 44 | padding: 0px 10px; 45 | font-size: 1.3em; 46 | color: rgb(100, 100, 100); 47 | } 48 | -------------------------------------------------------------------------------- /client/modals/studySearchModal.html: -------------------------------------------------------------------------------- 1 | 2 | 24 | 25 | 30 | -------------------------------------------------------------------------------- /client/workflow/home/homePage.js: -------------------------------------------------------------------------------- 1 | Template.homePage.events({ 2 | 'click #formBuilderTile':function(){ 3 | Router.go('/builder'); 4 | }, 5 | 'click #savedFormsTile':function(){ 6 | Router.go('/forms'); 7 | }, 8 | 'click #collectedDataTile':function(){ 9 | Router.go('/data'); 10 | }, 11 | 'click #sponsorsTile':function(){ 12 | Router.go('/sponsors'); 13 | }, 14 | 'click #usersTile':function(){ 15 | Router.go('/users'); 16 | }, 17 | 'click #subjectsTile':function(){ 18 | Router.go('/subjects'); 19 | }, 20 | 'click #commentsTile':function(){ 21 | Router.go('/comments'); 22 | }, 23 | 'click #studiesTile':function(){ 24 | Router.go('/studies'); 25 | }, 26 | 'click #auditTile':function(){ 27 | Router.go('/audit'); 28 | }, 29 | // 'click #auditTile':function(){ 30 | // Router.go('/audit'); 31 | // }, 32 | 33 | 'click .activeStudy':function(){ 34 | Session.set('selectedSubject', false); 35 | } 36 | }); 37 | 38 | 39 | 40 | Template.homePage.helpers({ 41 | studiesList: function(){ 42 | return Studies.find(); 43 | }, 44 | }); 45 | -------------------------------------------------------------------------------- /client/modals/formSearch.html: -------------------------------------------------------------------------------- 1 | 2 | 24 | 25 | 30 | -------------------------------------------------------------------------------- /client/workflow/comments/commentsEditPage.html: -------------------------------------------------------------------------------- 1 | 30 | -------------------------------------------------------------------------------- /client/modals/subjectSearch.html: -------------------------------------------------------------------------------- 1 | 2 | 24 | 25 | 30 | -------------------------------------------------------------------------------- /client/workflow/users/myProfilePage/myProfilePage.js: -------------------------------------------------------------------------------- 1 | Session.setDefault('isAlertVisible', false); 2 | 3 | 4 | //============================================================================== 5 | // ROUTER 6 | 7 | Router.map(function(){ 8 | this.route('myProfileRoute', { 9 | path: '/myprofile', 10 | template: 'myProfilePage', 11 | onAfterAction: function() { 12 | Session.set('isOnListPage', false); 13 | } 14 | }); 15 | }); 16 | 17 | 18 | 19 | //============================================================================== 20 | // TEMPLATE INPUTS 21 | 22 | Template.myProfilePage.events({ 23 | 'click #editProfileButton':function(){ 24 | Router.go('/user/edit/' + Meteor.userId()); 25 | } 26 | }); 27 | 28 | 29 | 30 | //============================================================================== 31 | // TEMPLATE OUTPUTS 32 | 33 | Template.myProfilePage.helpers({ 34 | isAlertVisible: function(){ 35 | return Session.get('isAlertVisible'); 36 | }, 37 | user: function(){ 38 | if(Meteor.user()){ 39 | return Meteor.user(); 40 | }else{ 41 | return {}; 42 | } 43 | } 44 | }); 45 | -------------------------------------------------------------------------------- /packages/clinical-ui-modals/modals/removeUser.html: -------------------------------------------------------------------------------- 1 | 2 | 24 | -------------------------------------------------------------------------------- /packages/clinical-ui-modals/modals/keybindings.html: -------------------------------------------------------------------------------- 1 | 2 | 27 | -------------------------------------------------------------------------------- /client/workflow/subjects/subjectsEditPage.html: -------------------------------------------------------------------------------- 1 | 30 | -------------------------------------------------------------------------------- /client/workflow/.accounts/ui.helpers.js: -------------------------------------------------------------------------------- 1 | 2 | if (typeof UI !== "undefined") { 3 | UI.registerHelper("signedInAs", function(date) { 4 | if (Meteor.user().username) { 5 | return Meteor.user().username; 6 | } else if (Meteor.user().profile.name) { 7 | return Meteor.user().profile.name; 8 | } else if (Meteor.user().emails && Meteor.user().emails[0]) { 9 | return Meteor.user().emails[0].address; 10 | } else { 11 | return "Signed In"; 12 | } 13 | }); 14 | } 15 | 16 | UI.registerHelper('accountButtons', function() { 17 | return new UI.SafeString(Template.entryAccountButtons()); 18 | }); 19 | 20 | UI.registerHelper('capitalize', function(str) { 21 | return str.charAt(0).toUpperCase() + str.slice(1); 22 | }); 23 | 24 | UI.registerHelper('signupClass', function() { 25 | if (Accounts.oauth && Accounts.oauth.serviceNames().length > 0) { 26 | return "collapse"; 27 | } 28 | }); 29 | 30 | UI.registerHelper('otherLoginServices', function() { 31 | return Accounts.oauth && Accounts.oauth.serviceNames().length > 0; 32 | }); 33 | 34 | UI.registerHelper('loginServices', function() { 35 | return Accounts.oauth.serviceNames(); 36 | }); 37 | -------------------------------------------------------------------------------- /packages/clinical-ui-modals/modals/selectRole.html: -------------------------------------------------------------------------------- 1 | 2 | 24 | 25 | 30 | -------------------------------------------------------------------------------- /client/workflow/sponsors/sponsorsEditPage.html: -------------------------------------------------------------------------------- 1 | 32 | -------------------------------------------------------------------------------- /client/modals/sponsorSearch.html: -------------------------------------------------------------------------------- 1 | 2 | 24 | 25 | 30 | -------------------------------------------------------------------------------- /client/workflow/builder/builderPage.less: -------------------------------------------------------------------------------- 1 | #builderPage{ 2 | #formTitleInput{ 3 | margin-bottom: 20px; 4 | } 5 | 6 | // sortable list 7 | .item{ 8 | cursor: move; 9 | //border: 2px solid #eeeeee; 10 | border: 2px solid white; 11 | margin-top: 5px; 12 | //margin: 10px; 13 | // .padded{ 14 | // padding-left: 25px; 15 | // } 16 | .close:hover{ 17 | color: #a52323; 18 | } 19 | label{ 20 | padding-left: 10px; 21 | } 22 | } 23 | .item-text{ 24 | padding: 10px !important; 25 | } 26 | .ui-sortable-helper{ 27 | background-color: #eeeeee; 28 | } 29 | .ui-sortable-placeholder{ 30 | margin: 10px !important; 31 | padding: 20px !important; 32 | } 33 | #sortableDropZone{ 34 | min-height: 200px; 35 | border: 2px dashed coral; 36 | margin: 10px; 37 | padding-top: 60px; 38 | color: coral; 39 | visibility: hidden; 40 | } 41 | #sortableDropZone:hover{ 42 | border: 2px dashed green !important; 43 | } 44 | .blockLabel{ 45 | padding-left: 5px; 46 | } 47 | 48 | 49 | .visible{ 50 | visibility: visible !important; 51 | } 52 | .selected{ 53 | border: 2px dashed #7a929c; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /client/modals/tutorialModal.html: -------------------------------------------------------------------------------- 1 | 2 | 30 | -------------------------------------------------------------------------------- /client/workflow/sponsors/sponsorsRecordPage.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | Router.map(function(){ 4 | this.route('sponsorRecordRoute', { 5 | path: '/sponsor/:id', 6 | template: 'sponsorsRecordPage', 7 | waitOn: function(){ 8 | Meteor.subscribe('settings'); 9 | return Meteor.subscribe('sponsors'); 10 | }, 11 | data: function () { 12 | return Sponsors.findOne({_id: this.params.id}); 13 | } 14 | }); 15 | }); 16 | 17 | 18 | 19 | 20 | 21 | Template.sponsorsRecordPage.events({ 22 | 'click #editSponsorButton':function(){ 23 | Router.go('/editsponsor/' + this._id._str); 24 | }, 25 | 'click #deleteSponsorButton':function(){ 26 | var userIsSure = confirm("Are you sure you want to delete sponsor #" + this._id._str); 27 | if(userIsSure){ 28 | Sponsors.remove({_id: this._id}); 29 | Router.go('/sponsors/'); 30 | } 31 | }, 32 | getSponsorName: function(){ 33 | return this.name; 34 | }, 35 | sponsorRecord: function(){ 36 | if(this){ 37 | return Sponsors.findOne(this._id); 38 | }else{ 39 | return { 40 | name: "---", 41 | description: "---", 42 | url: "---", 43 | owner: "---", 44 | owner_id: "---" 45 | }; 46 | } 47 | } 48 | }); 49 | -------------------------------------------------------------------------------- /client/ActiveLayout.js: -------------------------------------------------------------------------------- 1 | Meteor.startup(function (){ 2 | ActiveLayout.configure({ 3 | help: { 4 | link: "/menu", 5 | text: "", 6 | display: false 7 | }, 8 | classes: { 9 | header: "", 10 | title: "", 11 | links: "" 12 | }, 13 | text: { 14 | title: "Default Config", 15 | logout: "Logout" 16 | }, 17 | fence: { 18 | north: 50, 19 | south: 0, 20 | east: 270, 21 | west: 270, 22 | maxPageWidth: 2048 23 | }, 24 | defaults: { 25 | appSurfaceOffset: false, 26 | fullscreenNavbarsOverride: false, 27 | fullscreenNavbars: false, 28 | fullscreenOverride: true, 29 | fullscreen: true, 30 | hasPagePadding: false, 31 | hasPageVerticalPadding: false, 32 | mainPanelIsCard: false, 33 | navIsFullscreen: true, 34 | pageWhite: true, 35 | secondPanelEnabled: false, 36 | showNavbars: true, 37 | showSidebar: true, 38 | showSearchbar: false, 39 | symmatricalPadding: false, 40 | useHorizontalFences: false, 41 | useVerticalFences: true, 42 | useHierarchicalLayout: false, 43 | useCardLayout: false, 44 | useEastFence: false, 45 | wideCard: true 46 | } 47 | }); 48 | }); 49 | -------------------------------------------------------------------------------- /client/workflow/users/newUserPage.scss: -------------------------------------------------------------------------------- 1 | // #newUserPage{ 2 | // .new-user { 3 | // .form-wrapper { 4 | // .with-sidebar { 5 | // border-right: 1px solid #edeef1; 6 | // box-shadow: 4px 0px 3px -1px rgba(226, 226, 226, 0.1); 7 | // } 8 | // } 9 | // 10 | // /* form sidebar*/ 11 | // .form-sidebar { 12 | // .alert { 13 | // margin: 10px 0px 30px 0px; 14 | // i { 15 | // margin-bottom: 30px; 16 | // } 17 | // } 18 | // h6 { 19 | // font-weight: 600; 20 | // text-transform: uppercase; 21 | // } 22 | // p { 23 | // color: #777e86; 24 | // } 25 | // ul { 26 | // margin: 0; 27 | // padding: 0; 28 | // list-style: none; 29 | // a { 30 | // text-decoration: underline; 31 | // } 32 | // } 33 | // } 34 | // } 35 | // 36 | // /* responsive */ 37 | // 38 | // @media (max-width: 991px) { 39 | // .new-user { 40 | // .form-wrapper { 41 | // .with-sidebar { 42 | // border-right: 0 none; 43 | // box-shadow: none; 44 | // } 45 | // } 46 | // .form-sidebar { 47 | // margin-top: 40px; 48 | // } 49 | // } 50 | // } 51 | // 52 | // } 53 | -------------------------------------------------------------------------------- /client/workflow/.accounts/accountButtons/accountButtons.html: -------------------------------------------------------------------------------- 1 | 44 | -------------------------------------------------------------------------------- /client/workflow/forms/formsListPage.less: -------------------------------------------------------------------------------- 1 | /* CSS declarations go here */ 2 | #formsListPage{ 3 | tr{ 4 | cursor: pointer; 5 | } 6 | .customerRow:hover{ 7 | background-color: #fcdfdf !important; 8 | cursor: pointer; 9 | } 10 | 11 | .dataTables_filter{ 12 | input{ 13 | display: block; 14 | width: 100%; 15 | height: 34px; 16 | padding: 6px 12px; 17 | font-size: 14px; 18 | line-height: 1.42857143; 19 | color: #555; 20 | background-color: #fff; 21 | background-image: none; 22 | border: 1px solid #ccc; 23 | border-radius: 4px; 24 | -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); 25 | box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); 26 | -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; 27 | transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; 28 | } 29 | } 30 | .hidden{ 31 | visibility: hidden; 32 | } 33 | .visible{ 34 | visibility: visible; 35 | } 36 | .fullwidth{ 37 | width: 100%; 38 | } 39 | .centered{ 40 | text-align: center; 41 | } 42 | 43 | .tablesorter-headerRow{ 44 | cursor: pointer; 45 | } 46 | 47 | .getTheCode{ 48 | position: relative; 49 | top: 30px !important; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /client/workflow/landing/landingPage.theme.cta.less: -------------------------------------------------------------------------------- 1 | #landingPage{ 2 | 3 | #cta { 4 | margin-top: 90px; 5 | -webkit-font-smoothing: antialiased; } 6 | @media (max-width: 991px) { 7 | #cta { 8 | margin-top: 65px; } } 9 | #cta .form-wrapper { 10 | background: #F7F8FB; 11 | border: 1px solid #EAEDF7; 12 | border-radius: 8px; 13 | box-shadow: inset rgba(100, 100, 100, 0.25) 0 1px 1px; 14 | padding: 20px 30px 30px 30px; 15 | margin: 0 auto; } 16 | #cta h4 { 17 | font-size: 19px; 18 | color: #5F6E7C; 19 | font-weight: 400; 20 | text-shadow: 1px 1px 1px rgba(255, 255, 255, 0.5); } 21 | #cta form { 22 | margin-top: 30px; } 23 | #cta form .form-group { 24 | margin-right: 25px; } 25 | @media (max-width: 991px) { 26 | #cta form .form-group { 27 | margin-right: 20px; } } 28 | #cta form .form-group .form-control { 29 | width: 195px; } 30 | @media (max-width: 767px) { 31 | #cta form .form-group .form-control { 32 | width: 100%; } } 33 | #cta form .button { 34 | margin-left: 25px; } 35 | @media (max-width: 991px) { 36 | #cta form .button { 37 | margin-top: 25px; 38 | margin-left: 0px; } } 39 | } 40 | -------------------------------------------------------------------------------- /client/workflow/data/dataPreviewPage.less: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | //------------------------------------ 5 | // Form Preview Page 6 | 7 | #dataPreviewPage{ 8 | padding-top: 60px; 9 | 10 | .fa-2x{ 11 | margin-top: 7px; 12 | margin-right: 7px; 13 | } 14 | .fa-check{ 15 | color: green; 16 | } 17 | .fa-inbox{ 18 | color: coral; 19 | } 20 | .panel{ 21 | margin-bottom: 60px; 22 | } 23 | } 24 | 25 | a{ 26 | cursor: pointer; 27 | } 28 | .fa-trash-o, .fa-lock{ 29 | cursor: pointer; 30 | } 31 | 32 | 33 | 34 | //------------------------------------ 35 | // Form - Text Inputs 36 | .dataset-menu{ 37 | height: 100px; 38 | width: 100px; 39 | border: 2px solid darkgray; 40 | cursor: pointer; 41 | } 42 | 43 | .dataset-menu:hover{ 44 | border: 2px solid orangered; 45 | } 46 | 47 | .menu-item{ 48 | padding-bottom: 20px; 49 | height: 140px; 50 | } 51 | .menu-label{ 52 | padding-left: 20px; 53 | font-weight: 24px; 54 | } 55 | .menu-synopsis{ 56 | position: relative; 57 | top: -100px; 58 | left: 120px; 59 | } 60 | 61 | 62 | // mobile phone layout 63 | @media only screen and (max-width: 480px) { 64 | 65 | } 66 | 67 | // portrait orientation 68 | @media only screen and (max-width: 768px) { 69 | 70 | } 71 | 72 | // landscape orientation 73 | @media only screen and (min-width: 768px) { 74 | 75 | } 76 | -------------------------------------------------------------------------------- /client/workflow/comments/commentsListPage.less: -------------------------------------------------------------------------------- 1 | /* CSS declarations go here */ 2 | #commentsListPage{ 3 | .customerRow:hover{ 4 | background-color: #fcdfdf !important; 5 | cursor: pointer; 6 | } 7 | 8 | .dataTables_filter{ 9 | input{ 10 | display: block; 11 | width: 100%; 12 | height: 34px; 13 | padding: 6px 12px; 14 | font-size: 14px; 15 | line-height: 1.42857143; 16 | color: #555; 17 | background-color: #fff; 18 | background-image: none; 19 | border: 1px solid #ccc; 20 | border-radius: 4px; 21 | -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); 22 | box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); 23 | -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; 24 | transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; 25 | } 26 | } 27 | .hidden{ 28 | visibility: hidden; 29 | } 30 | .visible{ 31 | visibility: visible; 32 | } 33 | .fullwidth{ 34 | width: 100%; 35 | } 36 | .centered{ 37 | text-align: center; 38 | } 39 | 40 | .tablesorter-headerRow{ 41 | cursor: pointer; 42 | } 43 | 44 | .getTheCode{ 45 | position: relative; 46 | top: 30px !important; 47 | } 48 | 49 | #tableOfStudyForms{ 50 | tr{ 51 | cursor: pointer; 52 | } 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /client/workflow/studies/studiesListPage.less: -------------------------------------------------------------------------------- 1 | /* CSS declarations go here */ 2 | #studiesListPage{ 3 | .customerRow:hover{ 4 | background-color: #fcdfdf !important; 5 | cursor: pointer; 6 | } 7 | 8 | .dataTables_filter{ 9 | input{ 10 | display: block; 11 | width: 100%; 12 | height: 34px; 13 | padding: 6px 12px; 14 | font-size: 14px; 15 | line-height: 1.42857143; 16 | color: #555; 17 | background-color: #fff; 18 | background-image: none; 19 | border: 1px solid #ccc; 20 | border-radius: 4px; 21 | -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); 22 | box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); 23 | -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; 24 | transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; 25 | } 26 | } 27 | .hidden{ 28 | visibility: hidden; 29 | } 30 | .visible{ 31 | visibility: visible; 32 | } 33 | .fullwidth{ 34 | width: 100%; 35 | } 36 | .centered{ 37 | text-align: center; 38 | } 39 | 40 | .tablesorter-headerRow{ 41 | cursor: pointer; 42 | } 43 | 44 | .getTheCode{ 45 | position: relative; 46 | top: 30px !important; 47 | } 48 | 49 | #tableOfStudyForms{ 50 | tr{ 51 | cursor: pointer; 52 | } 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /client/modals/formSearch.js: -------------------------------------------------------------------------------- 1 | Session.setDefault('formSearchFilter', ''); 2 | Session.setDefault('selectedFormId', null); 3 | Session.setDefault('showFormSearch', false); 4 | 5 | 6 | Template.formSearchModal.helpers({ 7 | showFormSearch: function(){ 8 | if(Session.get('showFormSearch')){ 9 | Overlay.show(); 10 | return "opacity: 1; display: visible;"; 11 | } else { 12 | Overlay.hide(); 13 | return "opacity: 0; display: none;"; 14 | } 15 | }, 16 | formList: function(){ 17 | return Forms.find(); 18 | }, 19 | // getFormCount: function(){ 20 | // return Forms.find().count(); 21 | // }, 22 | getSearchTerm: function(){ 23 | return Session.get('formSearchFilter'); 24 | } 25 | }); 26 | 27 | 28 | 29 | Template.formSearchModal.events({ 30 | 'click .list-group-item':function(){ 31 | // Session.set('selectedForm', { 32 | // _id: this._id, 33 | // name: this.formName 34 | // }); 35 | Session.set('selectedFormId', this._id); 36 | }, 37 | 'keyup #formSearchModalInput':function(){ 38 | Session.set('formSearchFilter', $('#formSearchModalInput').val()); 39 | }, 40 | 'click #modalOkButton': function(){ 41 | Session.set('showFormSearch', false); 42 | Studies.update({_id: Session.get('selectedStudyId')}, {$addToSet:{ 43 | forms: Session.get('selectedFormId') 44 | }}); 45 | } 46 | }); 47 | -------------------------------------------------------------------------------- /client/workflow/comments/commentsListPage.html: -------------------------------------------------------------------------------- 1 | 35 | 36 | 37 | 46 | -------------------------------------------------------------------------------- /client/app/app.layout.less: -------------------------------------------------------------------------------- 1 | #appLayout{ 2 | .with-navbar-offset{ 3 | padding-top: 50px !important; 4 | } 5 | .page{ 6 | padding-top: 60px; 7 | } 8 | } 9 | 10 | .sectionTitle{ 11 | border-top: 1px solid lightgray; 12 | } 13 | 14 | 15 | .content{ 16 | padding-top: 20px; 17 | } 18 | 19 | 20 | #navbarHeader{ 21 | z-index: 100; 22 | } 23 | 24 | 25 | .topAnchored{ 26 | position: absolute; 27 | margin-top: 51px; 28 | top: 0px; 29 | } 30 | 31 | #mainPanel{ 32 | bakground-color: red !important; 33 | } 34 | 35 | #mainLayout{ 36 | //padding-left: 250px; 37 | transition: all 0.4s ease 0s; 38 | } 39 | 40 | #fullScreenToggleLink{ 41 | padding-right: 20px !important; 42 | } 43 | 44 | #mainPanel{ 45 | 46 | } 47 | .panel-heading{ 48 | padding: 10px 15px !important; 49 | } 50 | 51 | // landscape orientation 52 | @media only screen and (min-width: 1700px) { 53 | // #eastPanel{ 54 | // display: block; 55 | // } 56 | // #westPanel{ 57 | // display: block; 58 | // } 59 | } 60 | 61 | // portrait orientation 62 | @media only screen and (max-width: 1700px) { 63 | // #eastPanel{ 64 | // display: none; 65 | // } 66 | // #westPanel{ 67 | // display: none; 68 | // } 69 | } 70 | @media only screen and (max-width: 480px) { 71 | // #eastPanel{ 72 | // display: none; 73 | // } 74 | // #westPanel{ 75 | // display: none; 76 | // } 77 | } 78 | -------------------------------------------------------------------------------- /packages/clinical-ui-modals/modals/prompt.js: -------------------------------------------------------------------------------- 1 | Session.setDefault('promptTitle', 'Hello Modal!'); 2 | Session.setDefault('pomptMessage', 'Asprin is made from willow bark.'); 3 | 4 | Template.promptModal.helpers({ 5 | getPromptTitle: function(){ 6 | return Session.get('promptTitle'); 7 | }, 8 | getPromptMessage: function(){ 9 | return Session.get('promptMessage'); 10 | }, 11 | rendered: function(){ 12 | $("#promptModal").modal({ // wire up the actual modal functionality and show the dialog 13 | "backdrop" : "static", 14 | "keyboard" : true, 15 | "show" : false // ensure the modal is shown immediately 16 | }); 17 | 18 | $("#promptModal").on("show", function() { // wire up the OK button to dismiss the modal when shown 19 | $("#promptModal #modalOkButton").on("click", function(e) { 20 | console.log("button pressed"); // just as an example... 21 | $("#promptModal").modal('hide'); // dismiss the dialog 22 | }); 23 | }); 24 | 25 | $("#promptModal").on("hide", function() { // remove the event listeners when the dialog is dismissed 26 | $("#promptModal a.btn").off("click"); 27 | }); 28 | 29 | $("#promptModal").on("hidden", function() { // remove the actual elements from the DOM when fully hidden 30 | $("#promptModal").remove(); 31 | }); 32 | } 33 | }); 34 | -------------------------------------------------------------------------------- /.meteor/packages: -------------------------------------------------------------------------------- 1 | # Meteor packages used by this project, one per line. 2 | # 3 | # 'meteor add' and 'meteor remove' will edit this file for you, 4 | # but you can also edit it by hand. 5 | 6 | 7 | 8 | standard-app-packages 9 | less@2.7.9 10 | email@1.2.0 11 | ui 12 | session 13 | 14 | accounts-base@1.2.16 15 | accounts-password@1.3.5 16 | accounts-ui@1.1.9 17 | 18 | mrt:nprogress 19 | momentjs:moment 20 | benjaminrh:event-hooks 21 | 22 | clinical:roles 23 | clinical:keybindings 24 | clinical:extended-api 25 | clinical:fonts 26 | clinical:router 27 | 28 | clinical:ui-semantics 29 | clinical:hipaa-audit-log 30 | #clinical:template-helpers 31 | clinical:ui-modals 32 | 33 | awatson1978:bowser 34 | awatson1978:mousetrap 35 | 36 | #clinical:sidebars 37 | clinical:theming-ui 38 | clinical:theming@0.4.9 39 | clinical:active-layout 40 | clinical:active-layout-reset 41 | clinical:error-pages 42 | clinical:active-entry 43 | clinical:form-builder 44 | #clinical:active-users 45 | clinical:users-picklist 46 | clinical:modals 47 | 48 | clinical:hl7-resource-questionnaire 49 | clinical:hl7-resource-questionnaire-response 50 | clinical:hl7-resource-research-subject 51 | clinical:hl7-resource-research-study 52 | 53 | nemo64:bootstrap 54 | meteor-base 55 | mobile-experience 56 | mongo 57 | blaze-html-templates 58 | jquery 59 | tracker 60 | logging 61 | reload 62 | random 63 | ejson 64 | spacebars 65 | check 66 | standard-minifier-css 67 | standard-minifier-js 68 | shell-server 69 | -------------------------------------------------------------------------------- /packages/clinical-ui-modals/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | summary: "Modal dialogs for ClinicalFramework based apps", 3 | version: "0.1.3", 4 | name: "clinical:ui-modals", 5 | git: "http://github.com/awatson1978/clinical-ui-modals.git" 6 | }); 7 | 8 | 9 | 10 | Package.onUse(function(api) { 11 | api.versionsFrom('METEOR@0.9.3.1'); 12 | api.use('mrt:bootstrap-3'); 13 | api.use('templating'); 14 | api.use('session'); 15 | api.use('grove:less@0.1.1'); 16 | 17 | // api.addFiles('modals/confirm.html', "client"); 18 | // api.addFiles('modals/confirm.js', "client"); 19 | // api.addFiles('modals/confirm.less', "client"); 20 | 21 | // api.addFiles('modals/keybindings.html', "client"); 22 | // api.addFiles('modals/keybindings.js', "client"); 23 | // api.addFiles('modals/keybindings.less', "client"); 24 | 25 | // api.addFiles('modals/prompt.html', "client"); 26 | // api.addFiles('modals/prompt.js', "client"); 27 | // api.addFiles('modals/prompt.less', "client"); 28 | 29 | api.addFiles('modals/removeUser.html', "client"); 30 | api.addFiles('modals/removeUser.js', "client"); 31 | api.addFiles('modals/removeUser.less', "client"); 32 | 33 | api.addFiles('modals/selectRole.html', "client"); 34 | api.addFiles('modals/selectRole.js', "client"); 35 | api.addFiles('modals/selectRole.less', "client"); 36 | }); 37 | 38 | 39 | 40 | Package.onTest(function(api) { 41 | api.use('tinytest'); 42 | api.addFiles('clinical-ui-modals-tests.js'); 43 | }); 44 | -------------------------------------------------------------------------------- /client/app/navbars/navbarHeader.js: -------------------------------------------------------------------------------- 1 | Session.setDefault('selectedSubject', false); 2 | 3 | // --------------------------------------------------------------- 4 | // template events 5 | 6 | Template.navbarHeader.events({ 7 | 'click #selectedSubjectLink':function(){ 8 | $('#subjectSearchModal').modal("show"); 9 | $('#subjectSearchModal').on('hidden.bs.modal', function (e) { 10 | Session.set('selectedSubject', Session.get('selectedUser')); 11 | }); 12 | }, 13 | 'click #navbarBrandLink':function(){ 14 | Router.go('/'); 15 | }, 16 | 'click #logOutLink':function(){ 17 | Router.go('/sign-out'); 18 | } 19 | }); 20 | 21 | 22 | 23 | // --------------------------------------------------------------- 24 | // template helpers 25 | 26 | Template.navbarHeader.helpers({ 27 | getSelectedBlock: function(){ 28 | return Session.get('selectedBlockItem'); 29 | }, 30 | getSelectedSubject: function(){ 31 | if(Session.get('selectedSubject')){ 32 | return Session.get('selectedSubject').name; 33 | }else{ 34 | return "No subject selected."; 35 | } 36 | }, 37 | getUserName: function(){ 38 | if(Meteor.userId()){ 39 | if(Meteor.user()){ 40 | if(Meteor.user().profile && Meteor.user().profile.name){ 41 | return Meteor.user().profile.name; 42 | }else{ 43 | return Meteor.user().username; 44 | } 45 | }else{ 46 | return "---"; 47 | } 48 | }else{ 49 | return "Sign In"; 50 | } 51 | } 52 | }); 53 | -------------------------------------------------------------------------------- /packages/clinical-ui-modals/versions.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": [ 3 | [ 4 | "base64", 5 | "1.0.0" 6 | ], 7 | [ 8 | "blaze", 9 | "2.0.1" 10 | ], 11 | [ 12 | "deps", 13 | "1.0.4" 14 | ], 15 | [ 16 | "ejson", 17 | "1.0.3" 18 | ], 19 | [ 20 | "geojson-utils", 21 | "1.0.0" 22 | ], 23 | [ 24 | "htmljs", 25 | "1.0.1" 26 | ], 27 | [ 28 | "id-map", 29 | "1.0.0" 30 | ], 31 | [ 32 | "jquery", 33 | "1.0.0" 34 | ], 35 | [ 36 | "json", 37 | "1.0.0" 38 | ], 39 | [ 40 | "meteor", 41 | "1.1.1" 42 | ], 43 | [ 44 | "minimongo", 45 | "1.0.3" 46 | ], 47 | [ 48 | "mrt:bootstrap-3", 49 | "0.3.8" 50 | ], 51 | [ 52 | "observe-sequence", 53 | "1.0.2" 54 | ], 55 | [ 56 | "ordered-dict", 57 | "1.0.0" 58 | ], 59 | [ 60 | "random", 61 | "1.0.0" 62 | ], 63 | [ 64 | "reactive-dict", 65 | "1.0.3" 66 | ], 67 | [ 68 | "reactive-var", 69 | "1.0.2" 70 | ], 71 | [ 72 | "session", 73 | "1.0.2" 74 | ], 75 | [ 76 | "templating", 77 | "1.0.7" 78 | ], 79 | [ 80 | "tracker", 81 | "1.0.2" 82 | ], 83 | [ 84 | "underscore", 85 | "1.0.0" 86 | ] 87 | ], 88 | "pluginDependencies": [], 89 | "toolVersion": "meteor-tool@1.0.33", 90 | "format": "1.0" 91 | } -------------------------------------------------------------------------------- /tests/accounts.entry.js: -------------------------------------------------------------------------------- 1 | // add tests to this file using the Nightwatch.js API 2 | // http://nightwatchjs.org/api 3 | 4 | module.exports = { 5 | "Sign In Page" : function (client) { 6 | client 7 | .url("http://localhost:3000") 8 | 9 | //======================================================================== 10 | // LANDING PAGE 11 | 12 | .waitForElementVisible("body", 1000) 13 | .verify.elementPresent('#landingPage') 14 | .verify.elementPresent('#signInLink') 15 | 16 | .click("#signInLink").pause(200) 17 | .pause(1000) 18 | 19 | .click("#signInLink") 20 | 21 | //======================================================================== 22 | // SIGN IN PAGE 23 | 24 | .waitForElementVisible("#entrySignInPage", 1000) 25 | .waitForElementVisible("#emailInput", 1000) 26 | .waitForElementVisible("#passwordInput", 1000) 27 | .waitForElementVisible("#entrySignInButton", 1000) 28 | 29 | .verify.elementPresent('#entrySignInPage') 30 | //.verify.elementPresent('#thinaireSignInLogo') 31 | .verify.elementPresent('#emailInput') 32 | .verify.elementPresent('#passwordInput') 33 | .verify.elementPresent('#signInLabel') 34 | .verify.elementPresent('#forgotPasswordLink') 35 | .verify.elementPresent('#entrySignInButton') 36 | 37 | .setValue("#emailInput", "sysadmin") 38 | .setValue("#passwordInput", "sysadmin321$") 39 | 40 | .click("#entrySignInButton") 41 | .pause(1000) 42 | 43 | .waitForElementVisible("#homePage", 1000) 44 | .end(); 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /client/workflow/.accounts/entrySignIn/entrySignInPage.js: -------------------------------------------------------------------------------- 1 | 2 | Template.entrySignInPage.helpers({ 3 | emailInputType: function() { 4 | if (Accounts.ui._options.passwordSignupFields === 'EMAIL_ONLY') { 5 | return 'email'; 6 | } else { 7 | return 'string'; 8 | } 9 | }, 10 | emailPlaceholder: function() { 11 | var fields; 12 | fields = Accounts.ui._options.passwordSignupFields; 13 | if (_.contains(['USERNAME_AND_EMAIL', 'USERNAME_AND_OPTIONAL_EMAIL'], fields)) { 14 | return 'Username or email'; 15 | } 16 | return 'Email'; 17 | }, 18 | logo: function() { 19 | return AccountsEntry.settings.logo; 20 | }, 21 | getTotalInteractions: function(){ 22 | // console.log(InteractionsCount.findOne().count); 23 | // if(InteractionsCount.findOne()){ 24 | // return InteractionsCount.findOne().count; 25 | // }else{ 26 | // return 0; 27 | // } 28 | return 0; 29 | } 30 | }); 31 | 32 | Template.entrySignInPage.events({ 33 | 'click #entrySignInButton': function() { 34 | Session.set('email', $('#emailInput').val()); 35 | Session.set('password', $('#passwordInput').val()); 36 | 37 | return Meteor.loginWithPassword(Session.get('email'), Session.get('password'), function(error) { 38 | if (error) { 39 | return Session.set('entryError', error.reason); 40 | }else{ 41 | return Router.go(AccountsEntry.settings.dashboardRoute); 42 | } 43 | }); 44 | }, 45 | 'keydown #entrySignInPage': function(evt,tmpl){ 46 | if(evt.keyCode == 13) { 47 | $('#entrySignInButton').click(); 48 | evt.preventDefault(); 49 | } 50 | } 51 | }); 52 | -------------------------------------------------------------------------------- /client/workflow/.accounts/entrySocial/entrySocial.js: -------------------------------------------------------------------------------- 1 | Template.entrySocial.helpers({ 2 | buttonText: function() { 3 | return Session.get('buttonText'); 4 | }, 5 | google: function() { 6 | if (this[0] === 'g' && this[1] === 'o') { 7 | return true; 8 | } 9 | } 10 | }); 11 | 12 | Template.entrySocial.events({ 13 | 'click .btn': function(event) { 14 | var callback, loginWithService, options, serviceName; 15 | serviceName = $(event.target).attr('id').split('-')[1]; 16 | callback = function(err) { 17 | if (!err) { 18 | return Router.go(AccountsEntry.settings.dashboardRoute); 19 | } else if (err instanceof Accounts.LoginCancelledError) { 20 | // do nothing 21 | } else if (err instanceof ServiceConfiguration.ConfigError) { 22 | return loginButtonsSession.configureService(serviceName); 23 | } else { 24 | return loginButtonsSession.errorMessage(err.reason || "Unknown error"); 25 | } 26 | }; 27 | loginWithService = Meteor["loginWith" + capitalize(serviceName)]; 28 | options = {}; 29 | if (Accounts.ui._options.requestPermissions[serviceName]) { 30 | options.requestPermissions = Accounts.ui._options.requestPermissions[serviceName]; 31 | } 32 | if (Accounts.ui._options.requestOfflineToken[serviceName]) { 33 | options.requestOfflineToken = Accounts.ui._options.requestOfflineToken[serviceName]; 34 | } 35 | loginWithService(options, callback); 36 | return Router.go(AccountsEntry.settings.dashboardRoute); 37 | } 38 | }); 39 | 40 | capitalize = function(str) { 41 | return str.charAt(0).toUpperCase() + str.slice(1); 42 | }; 43 | -------------------------------------------------------------------------------- /client/workflow/users/userEditPage/userEditPage.html: -------------------------------------------------------------------------------- 1 | 39 | 40 | 45 | -------------------------------------------------------------------------------- /client/workflow/builder/formBlock.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Template.formBlock.helpers({ 6 | isSelected: function(){ 7 | if(Session.get('selectedBlockItem') === this._id){ 8 | return "selected" 9 | } 10 | }, 11 | isInput: function(){ 12 | if(this.elementType === "input"){ 13 | return true; 14 | }else{ 15 | return false; 16 | } 17 | }, 18 | getLabelText: function(){ 19 | var resultString = ""; 20 | if(this.labelText){ 21 | return resultString + this.labelText; 22 | }else{ 23 | return resultString; 24 | } 25 | }, 26 | getInputType: function(){ 27 | return this.inputType; 28 | }, 29 | getInputPlaceholder: function(){ 30 | if(this.inputPlaceholder){ 31 | return this.inputPlaceholder; 32 | }else{ 33 | return "..."; 34 | } 35 | }, 36 | getInputValue: function(){ 37 | return this.inputValue; 38 | }, 39 | 40 | getValue1: function(){ 41 | if(this.defaultValue1){ 42 | return this.defaultValue1; 43 | }else{ 44 | return "1"; 45 | } 46 | }, 47 | getValue2: function(){ 48 | if(this.defaultValue2){ 49 | return this.defaultValue2; 50 | }else{ 51 | return "2"; 52 | } 53 | }, 54 | getValue3: function(){ 55 | if(this.defaultValue3){ 56 | return this.defaultValue3; 57 | }else{ 58 | return "3"; 59 | } 60 | }, 61 | getValue4: function(){ 62 | if(this.defaultValue4){ 63 | return this.defaultValue4; 64 | }else{ 65 | return "4"; 66 | } 67 | }, 68 | getValue5: function(){ 69 | if(this.defaultValue5){ 70 | return this.defaultValue5; 71 | }else{ 72 | return "5"; 73 | } 74 | } 75 | 76 | }); 77 | -------------------------------------------------------------------------------- /client/workflow/landing/landingPage.js: -------------------------------------------------------------------------------- 1 | Template.landingPage.getUserCount = function(){ 2 | var count = Meteor.users.find().count(); 3 | return count; 4 | }; 5 | 6 | Template.landingPage.events({ 7 | 'click #screenshotTileBlue, tap #screenshotTileBlue':function(){ 8 | 9 | Session.set('overlay_image_path', $('#screenshotBlue').attr('src')); 10 | Session.set('show_reactive_overlay', true); 11 | Session.set('show_overlay_image', true); 12 | 13 | } 14 | }); 15 | 16 | Session.setDefault('screenshotIndex', 0); 17 | Meteor.startup(function () { 18 | var displayedScreenshotIndex = 0; 19 | Meteor.setInterval(function () { 20 | if(displayedScreenshotIndex === 1){ 21 | displayedScreenshotIndex = 0; 22 | }else{ 23 | displayedScreenshotIndex = displayedScreenshotIndex + 1; 24 | } 25 | Session.set('screenshotIndex', displayedScreenshotIndex); 26 | }, 3000); 27 | }); 28 | 29 | // Template.landingPage.getScreenshotPath = function(){ 30 | // switch(Session.get('screenshotIndex')){ 31 | // case 0: 32 | // return "/Dermatomes_Female_Double_Medium.png"; 33 | // break; 34 | // case 1: 35 | // return "/Dermatomes_Male_Double_Medium.png"; 36 | // break; 37 | // case 2: 38 | // return "/Dermatomes_Female_Double_Medium.png"; 39 | // break; 40 | // } 41 | // }; 42 | // 43 | // Template.landingPage.firstImageTransition = function(){ 44 | // if(Session.get('screenshotIndex') === 0){ 45 | // return 'in'; 46 | // }else{ 47 | // return 'out'; 48 | // } 49 | // } 50 | // Template.landingPage.secondImageTransition = function(){ 51 | // if(Session.get('screenshotIndex') === 1){ 52 | // return 'in'; 53 | // }else{ 54 | // return 'out'; 55 | // } 56 | // } 57 | -------------------------------------------------------------------------------- /shared/methods/accounts.methods.js: -------------------------------------------------------------------------------- 1 | Meteor.methods({ 2 | createNewUser: function(input){ 3 | console.log('creating new user...'); 4 | console.log(input); 5 | 6 | var result = Accounts.createUser({ 7 | username: input.username, 8 | email: input.address, 9 | password: input.password 10 | }); 11 | 12 | Meteor.users.update({_id: result}, {$set:{ 13 | profile: input.profile 14 | }}) 15 | 16 | console.log(result); 17 | return result; 18 | }, 19 | 20 | updateUser: function(input){ 21 | console.log('updating user...') 22 | console.log(input); 23 | 24 | return result = Meteor.users.update(input._id,{$set:{ 25 | 'profile.name': input.profile.name, 26 | 'profile.title': input.profile.title, 27 | 28 | 'profile.sponsor': input.profile.sponsor, 29 | 'profile.sponsor_id': input.profile.sponsor_id, 30 | 31 | 'profile.roles': input.profile.roles, 32 | 33 | 'profile.avatar': input.profile.avatar, 34 | 'profile.phone': input.profile.phone, 35 | 'profile.website': input.profile.website, 36 | 'profile.address': input.profile.address, 37 | 'profile.city': input.profile.city, 38 | 'profile.state': input.profile.state, 39 | 'profile.zip': input.profile.zip 40 | }}); 41 | }, 42 | 43 | removeUser: function(userId){ 44 | console.log('removing user...' + userId); 45 | 46 | var result = Meteor.users.remove({_id: userId }); 47 | 48 | console.log(result); 49 | return result; 50 | 51 | }, 52 | setUserRole:function(userId, role){ 53 | console.log('setUserRole', userId, role); 54 | var result = Meteor.users.update(userId,{$set:{ 55 | 'profile.roles': role 56 | }}); 57 | return result; 58 | } 59 | }); 60 | -------------------------------------------------------------------------------- /client/workflow/users/users.responsive.less: -------------------------------------------------------------------------------- 1 | #usersListPage{ 2 | 3 | 4 | } 5 | 6 | // tablet landscape orientation 7 | @media only screen and (min-width: 768px) { 8 | #usersListPage{ 9 | 10 | } 11 | } 12 | 13 | // tablet portrait orientation 14 | @media only screen and (max-width: 768px) { 15 | #usersListPage{ 16 | 17 | } 18 | } 19 | 20 | // phone/watch 21 | @media only screen and (max-width: 480px) { 22 | #usersListPage{ 23 | 24 | } 25 | } 26 | 27 | @media (max-width: 480px) { 28 | } 29 | 30 | @media (max-width: 768px) { 31 | .settings-wrapper { 32 | #pad-wrapper{ 33 | padding: 0px 20px; 34 | } 35 | .avatar-box{ 36 | text-align: center; 37 | } 38 | .personal-info { 39 | border:0 none; 40 | box-shadow: none; 41 | margin-top: 40px; 42 | h5.personal-title { 43 | margin-left: 0; 44 | } 45 | .ui-select { 46 | width: 90%; 47 | } 48 | label { 49 | width: 100%; 50 | } 51 | .actions { 52 | text-align: center; 53 | } 54 | form { 55 | margin-left: 0; 56 | padding: 0px 10px 0px 10px; 57 | } 58 | } 59 | } 60 | } 61 | 62 | @media (min-width: 768px) and (max-width: 979px) { 63 | .settings-wrapper .personal-info .ui-select{ 64 | width: 77%; 65 | } 66 | .avatar-box { 67 | text-align: center; 68 | margin-bottom: 20px; 69 | } 70 | .settings-wrapper .personal-info { 71 | border-left: 0px; 72 | box-shadow: none; 73 | } 74 | } 75 | @media (min-width: 768px){ 76 | .settings-wrapper .personal-info .alert { 77 | margin-left: 50px; 78 | } 79 | } 80 | @media (min-width: 980px) { 81 | 82 | } 83 | 84 | @media (max-width: 979px) { 85 | } 86 | 87 | @media (min-width: 1200px) { 88 | } 89 | -------------------------------------------------------------------------------- /client/stylesheets/custom.bootstrap.json: -------------------------------------------------------------------------------- 1 | { 2 | "modules" : { 3 | "normalize" : true, 4 | "print" : false, 5 | "glyphicons" : false, 6 | 7 | "scaffolding" : true, 8 | "type" : false, 9 | "code" : false, 10 | "grid" : true, 11 | "tables" : false, 12 | "forms" : false, 13 | "buttons" : false, 14 | 15 | "component-animations" : false, 16 | "dropdowns" : false, 17 | "button-groups" : false, 18 | "input-groups" : false, 19 | "navs" : false, 20 | "navbar" : false, 21 | "breadcrumbs" : false, 22 | "pagination" : false, 23 | "pager" : false, 24 | "labels" : false, 25 | 26 | "badges" : false, 27 | "jumbotron" : false, 28 | "thumbnails" : false, 29 | "alerts" : false, 30 | "progress-bars" : false, 31 | "media" : false, 32 | "list-group" : true, 33 | "panels" : false, 34 | "responsive-embed" : false, 35 | "wells" : false, 36 | "close" : false, 37 | 38 | "modals" : false, 39 | "tooltip" : false, 40 | "popovers" : false, 41 | "carousel" : false, 42 | 43 | "affix" : false, 44 | "alert" : false, 45 | "button" : false, 46 | "collapse" : false, 47 | "scrollspy" : false, 48 | "tab" : false, 49 | "transition" : false, 50 | 51 | "utilities" : false, 52 | "responsive-utilities" : false 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /server/accounts.initialize.js: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------- 2 | // USER ACCOUNTS 3 | 4 | if (Meteor.users.find().count() === 0) { 5 | console.log("Running on localhost and no users found. Lets create some."); 6 | 7 | var users = [{ 8 | email: "sysadmin@clinical-trials.meteor.com", 9 | username: "sysadmin", 10 | name: "System Administrator", 11 | password: "sysadmin321$", 12 | roles: ["SysAdmin"], 13 | sponsor: "clinical-trials.meteor.com" 14 | // roles: ["employee", "sysadmin", "coordinator", "reviewer", "builder"] 15 | }, { 16 | email: "janedoe@acme.com", 17 | username: "janedoe", 18 | name: "Jane Doe", 19 | password: "janedoe123", 20 | roles: ["Data Entry"], 21 | sponsor: "ACME Pharmaceuticals" 22 | },{ 23 | email: "johndoe@acme.com", 24 | username: "johndoe", 25 | name: "John Doe", 26 | password: "johndoe123", 27 | roles: ["Reviewer"], 28 | sponsor: "ACME Pharmaceuticals" 29 | } 30 | ]; 31 | 32 | users.forEach(function(user){ 33 | console.log('----------------------------') 34 | console.log('newUser: ', user); 35 | var id = Accounts.createUser({ 36 | email: user.email, 37 | password: user.password, 38 | profile: { 39 | name: user.name, 40 | roles: [user.roles], 41 | sponsor: user.sponsor 42 | }, 43 | username: user.username 44 | }); 45 | 46 | if(user.roles.length > 0){ 47 | Roles.addUsersToRoles(id, user.roles); 48 | } 49 | 50 | console.log('createdUser: ', Meteor.users.findOne({_id: id})); 51 | }); 52 | 53 | console.log("Users created: " + Meteor.users.find().count()); 54 | } 55 | 56 | 57 | //------------------------------------------------------------------------- 58 | // SPONSORS 59 | -------------------------------------------------------------------------------- /client/workflow/.accounts/entrySignIn/entrySignInPage.html: -------------------------------------------------------------------------------- 1 | 42 | -------------------------------------------------------------------------------- /client/app/sidebar/sidebar.html: -------------------------------------------------------------------------------- 1 | 48 | -------------------------------------------------------------------------------- /client/workflow/forms/formsListPage.html: -------------------------------------------------------------------------------- 1 | 40 | 41 | 42 | 45 | 46 | 47 | 58 | -------------------------------------------------------------------------------- /client/workflow/subjects/subjectsListPage.html: -------------------------------------------------------------------------------- 1 | 42 | 43 | 46 | 47 | 59 | -------------------------------------------------------------------------------- /client/workflow/users/userEditPage/userSecurityCard.html: -------------------------------------------------------------------------------- 1 | 46 | -------------------------------------------------------------------------------- /client/app/app.syntax.less: -------------------------------------------------------------------------------- 1 | a{ 2 | color: #7a929c; 3 | } 4 | a:hover{ 5 | color: #7a929c; 6 | } 7 | 8 | .btn-info { 9 | color: #fff; 10 | background-color: #7a929c; 11 | border-color: #576b71; 12 | } 13 | .btn-info:active, .btn-info:focus, .btn-info:hover, .btn-info:visited{ 14 | background-color: #7a929c !important; 15 | border-color: #576b71 !important; 16 | } 17 | 18 | 19 | .strikethrough{ 20 | text-decoration: line-through; 21 | } 22 | 23 | .tile { 24 | background-color: #fff; 25 | border-radius: 6px 6px 6px 6px; 26 | border: 0px; 27 | position: relative; 28 | box-shadow: 4px 2px 6px 2px rgba(81, 81, 81, 0.5); 29 | -moz-box-shadow: 4px 2px 6px 2px rgba(81, 81, 81, 0.5); 30 | -webkit-box-shadow: 4px 2px 6px 2px rgba(81, 81, 81, 0.5); 31 | } 32 | 33 | .padded{ 34 | padding: 10px; 35 | } 36 | .fullwidth{ 37 | width: 100%; 38 | } 39 | li{ 40 | cursor: pointer; 41 | } 42 | .unselectable{ 43 | -moz-user-select: -moz-none; 44 | -khtml-user-select: none; 45 | -webkit-user-select: none; 46 | -ms-user-select: none; 47 | user-select: none; 48 | } 49 | .centered{ 50 | text-align: center; 51 | } 52 | .block{ 53 | cursor: move; 54 | height: 200px; 55 | } 56 | 57 | .dragdropzone{ 58 | //min-height: 800px; 59 | background-color: #eeeeee; 60 | z-index: 10; 61 | } 62 | 63 | .draggable{ 64 | z-index: 100; 65 | } 66 | 67 | 68 | //------------------------------------------------------------------------------ 69 | // SYNTAX COLOR 70 | 71 | .primary-color{ 72 | color: #7a929c; 73 | } 74 | .btn-primary { 75 | color: #fff; 76 | background-color: #7a929c; 77 | border-color: #576b71; 78 | } 79 | .panel-primary{ 80 | border-color: #7a929c; 81 | .panel-heading{ 82 | background-color: #7a929c; 83 | color: #fff; 84 | } 85 | } 86 | .panel-image-primary{ 87 | background-color: #f5f5f5; 88 | border-bottom: 1px solid #ddd; 89 | } 90 | .heading-primary{ 91 | background-color: #7a929c; 92 | color: #fff; 93 | } 94 | -------------------------------------------------------------------------------- /client/workflow/studies/studiesListPage.html: -------------------------------------------------------------------------------- 1 | 43 | 44 | 47 | 48 | 61 | -------------------------------------------------------------------------------- /client/workflow/sponsors/sponsorsListPage.html: -------------------------------------------------------------------------------- 1 | 50 | 51 | 52 | 53 | 54 | 77 | -------------------------------------------------------------------------------- /client/workflow/static/glossaryPage.html: -------------------------------------------------------------------------------- 1 | 36 | -------------------------------------------------------------------------------- /client/workflow/static/aboutPage.html: -------------------------------------------------------------------------------- 1 | 23 | -------------------------------------------------------------------------------- /client/workflow/data/dataPreviewPage.html: -------------------------------------------------------------------------------- 1 | 56 | -------------------------------------------------------------------------------- /client/app/Router.js: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------- 2 | // Routing Layouts 3 | 4 | Session.setDefault('fullscreenOverride', true); 5 | 6 | Router.configure({ 7 | // we use the appLayout template to define the layout for the entire app 8 | layoutTemplate: 'appLayout', 9 | 10 | // the pageNotFound template is used for unknown routes and missing lists 11 | notFoundTemplate: 'pageNotFound', 12 | 13 | // show the appLoading template whilst the subscriptions below load their data 14 | loadingTemplate: 'appLoading', 15 | 16 | yieldTemplates: { 17 | 'sidebar': { 18 | to: 'westPanel' 19 | }, 20 | 'navbarHeader': { 21 | to: 'header' 22 | }, 23 | 'navbarFooter': { 24 | to: 'footer' 25 | }, 26 | 'reactiveOverlaysTemplate': { 27 | to: 'overlays' 28 | }, 29 | 'globalSearchBar': { 30 | to: 'globalInput' 31 | }, 32 | 'tutorialModal': { 33 | to: 'modalA' 34 | }, 35 | 'sponsorSearchModal': { 36 | to: 'modalB' 37 | }, 38 | 'formSearchModal': { 39 | to: 'modalC' 40 | }, 41 | 'subjectSearchModal': { 42 | to: 'modalD' 43 | }, 44 | 'selectRoleModal': { 45 | to: 'modalE' 46 | }, 47 | 'removeUserModal': { 48 | to: 'modalF' 49 | }, 50 | 'sponsorSearchModal': { 51 | to: 'modalG' 52 | } 53 | } 54 | }); 55 | 56 | 57 | Router.onBeforeAction(function() { 58 | if (!Meteor.loggingIn() && !Meteor.user()) { 59 | this.redirect('/sign-in'); 60 | } 61 | this.next(); 62 | }, { 63 | except: [ 64 | 'homePage', 65 | 'landingRoute', 66 | 'eulaRoute', 67 | 'privacyRoute', 68 | 'aboutRoute', 69 | 'glossaryRoute', 70 | 'browserNotSupportedRoute', 71 | 'entrySignUp', 72 | 'entrySignIn', 73 | 'forgotPassword', 74 | 'entrySignOutRoute', 75 | 'resetPassword', 76 | 'pageNotFound' 77 | ] 78 | }); 79 | Router.onBeforeAction(function() { 80 | //hideWestPanel(); 81 | this.next(); 82 | }, {except: ['builderPage']}); 83 | 84 | // Router.onBeforeAction(function() { 85 | // if(!bowser.webkit){ 86 | // this.render('browserNotSupportedPage'); 87 | // this.pause(); 88 | // } 89 | // }); 90 | -------------------------------------------------------------------------------- /tests/app.static.js: -------------------------------------------------------------------------------- 1 | // add tests to this file using the Nightwatch.js API 2 | // http://nightwatchjs.org/api 3 | 4 | module.exports = { 5 | "Static Pages" : function (client) { 6 | client 7 | .url("http://localhost:3000") 8 | 9 | .waitForElementVisible("body", 1000) 10 | .verify.elementPresent('#landingPage') 11 | .verify.elementPresent('#signInLink') 12 | 13 | .click("#signInLink").pause(200) 14 | .pause(1000) 15 | 16 | .waitForElementVisible("#entrySignInPage", 1000) 17 | .verify.elementPresent("#emailInput") 18 | .verify.elementPresent("#passwordInput") 19 | .verify.elementPresent("#entrySignInButton") 20 | 21 | .setValue("#emailInput", "sysadmin") 22 | .setValue("#passwordInput", "sysadmin321$") 23 | 24 | .click("#entrySignInButton") 25 | .pause(1000) 26 | 27 | .waitForElementVisible("#homePage", 1000) 28 | 29 | 30 | // studies 31 | .click("#studiesTile").pause(500) 32 | .verify.elementPresent("#studiesListPage") 33 | .click('#navbarBrandLink').pause(500) 34 | 35 | // forms 36 | .click("#savedFormsTile").pause(500) 37 | .verify.elementPresent("#formsListPage") 38 | .click('#navbarBrandLink').pause(500) 39 | 40 | // data 41 | .click("#collectedDataTile").pause(500) 42 | .verify.elementPresent("#dataListPage") 43 | .click('#navbarBrandLink').pause(500) 44 | 45 | // design 46 | .click("#formBuilderTile").pause(500) 47 | .verify.elementPresent("#builderPage") 48 | .click('#navbarBrandLink').pause(500) 49 | 50 | // clients 51 | .click("#sponsorsTile").pause(500) 52 | .verify.elementPresent("#sponsorsListPage") 53 | .click('#navbarBrandLink').pause(500) 54 | 55 | // users 56 | .click("#usersTile").pause(500) 57 | .verify.elementPresent("#usersListPage") 58 | .click('#navbarBrandLink').pause(500) 59 | 60 | // click glossary 61 | .click("#northeastDropDownLink") 62 | .pause(500) 63 | .verify.elementPresent("#northeastDropDownMenu") 64 | .click("#signOutLink") 65 | .pause(2000) 66 | .waitForElementVisible("#landingPage", 1000) 67 | .end(); 68 | } 69 | }; 70 | -------------------------------------------------------------------------------- /client/app/sidebar/sidebar.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | // Template.sidebar.rendered = function() { 5 | // this.find('#sidebarMenuContents a')._uihooks = { 6 | // insertElement: function(node, next) { 7 | // $(node) 8 | // .hide() 9 | // .insertBefore(next) 10 | // .fadeIn(); 11 | // }, 12 | // removeElement: function(node) { 13 | // $(node).fadeOut(function() { 14 | // this.remove(); 15 | // }); 16 | // } 17 | // }; 18 | // }; 19 | 20 | 21 | Template.sidebar.events({ 22 | 'click #homeLink': function(){ 23 | Router.go('/'); 24 | }, 25 | "click #usernameLink": function(){ 26 | if (!Meteor.user()) { 27 | Router.go('/entrySignIn'); 28 | } 29 | }, 30 | "click #protocolLibraryLink": function (){ 31 | Router.go('/protocols'); 32 | }, 33 | 'click #logoutButton': function() { 34 | Meteor.logout(function(){ 35 | // if we are on a private list, we'll need to go to a public one 36 | var current = Router.current(); 37 | if (current.route.name === 'checklistPage' && current.data().userId) { 38 | Router.go('checklistPage', Lists.findOne({userId: {$exists: false}})); 39 | } else { 40 | Router.go('/entrySignIn') 41 | } 42 | }); 43 | 44 | if (Session.get("appWidth") < 1024) { 45 | Session.set('useHorizontalFences', false) 46 | } 47 | 48 | }, 49 | 'click #newListButton': function() { 50 | Router.go('checklistPage', Lists.createNew()); 51 | } 52 | }); 53 | 54 | Template.sidebar.helpers({ 55 | getUsername: function () { 56 | if (Meteor.user()) { 57 | if (Meteor.user().emails[0]) { 58 | return Meteor.user().emails[0].address; 59 | } else { 60 | return "---"; 61 | } 62 | } else { 63 | return "Sign In"; 64 | } 65 | }, 66 | getConnectionStatus: function () { 67 | return Meteor.status().status; 68 | }, 69 | email: function() { 70 | return Meteor.user().emails[0].address; 71 | }, 72 | lists: function() { 73 | return Lists.find({userId: Meteor.userId()}); 74 | }, 75 | activeListClass: function() { 76 | var current = Router.current(); 77 | if (current.route.name === 'checklistPage' && current.params._id === this._id) { 78 | return 'active'; 79 | } 80 | } 81 | }); 82 | -------------------------------------------------------------------------------- /client/app/app.uservoice.js: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Meteor.startup(function(){ 4 | // 5 | // // Include the UserVoice JavaScript SDK (only needed once on a page) 6 | // UserVoice=window.UserVoice||[];(function(){var uv=document.createElement('script');uv.type='text/javascript';uv.async=true;uv.src='//widget.uservoice.com/8MBs2ieVimHLtFL6swWQ.js';var s=document.getElementsByTagName('script')[0];s.parentNode.insertBefore(uv,s)})(); 7 | // 8 | // // 9 | // // UserVoice Javascript SDK developer documentation: 10 | // // https://www.uservoice.com/o/javascript-sdk 11 | // // 12 | // 13 | // // Set colors 14 | // UserVoice.push(['set', { 15 | // accent_color: '#448dd6', 16 | // trigger_color: 'white', 17 | // trigger_background_color: 'rgba(46, 49, 51, 0.6)' 18 | // }]); 19 | // 20 | // // Identify the user and pass traits 21 | // // To enable, replace sample data with actual user traits and uncomment the line 22 | // UserVoice.push(['identify', { 23 | // //email: 'john.doe@example.com', // User’s email address 24 | // //name: 'John Doe', // User’s real name 25 | // //created_at: 1364406966, // Unix timestamp for the date the user signed up 26 | // //id: 123, // Optional: Unique id of the user (if set, this should not change) 27 | // //type: 'Owner', // Optional: segment your users by type 28 | // //account: { 29 | // // id: 123, // Optional: associate multiple users with a single account 30 | // // name: 'Acme, Co.', // Account name 31 | // // created_at: 1364406966, // Unix timestamp for the date the account was created 32 | // // monthly_rate: 9.99, // Decimal; monthly rate of the account 33 | // // ltv: 1495.00, // Decimal; lifetime value of the account 34 | // // plan: 'Enhanced' // Plan name for the account 35 | // //} 36 | // }]); 37 | // 38 | // // Add default trigger to the bottom-right corner of the window: 39 | // //UserVoice.push(['addTrigger', { mode: 'contact', trigger_position: 'bottom-right' }]); 40 | // 41 | // // Or, use your own custom trigger: 42 | // UserVoice.push(['addTrigger', '#helpLink', { mode: 'contact' }]); 43 | // 44 | // // Autoprompt for Satisfaction and SmartVote (only displayed under certain conditions) 45 | // UserVoice.push(['autoprompt', {}]); 46 | // 47 | // }); 48 | -------------------------------------------------------------------------------- /client/workflow/static/privacyPage.html: -------------------------------------------------------------------------------- 1 | 24 | -------------------------------------------------------------------------------- /shared/methods/items.methods.js: -------------------------------------------------------------------------------- 1 | // Meteor.methods({ 2 | // updateItem: function(data){ 3 | // console.log('updating item ' + data.id); 4 | // console.log(data); 5 | 6 | // var result = Items.update({_id: data.id }, {$set:{ 7 | // labelText: data.labelText, 8 | // inputValue: data.inputValue 9 | // }}); 10 | // console.log('result: ' + result); 11 | // return result; 12 | // }, 13 | // dropForm: function(){ 14 | // console.log('dropping Items collection to clear Form Builder...'); 15 | // Items.find().forEach(function(record){ 16 | // Items.remove({_id: record._id}); 17 | // }); 18 | // }, 19 | 20 | // deleteDataRecord: function(recordId){ 21 | // console.log('toggling deleted status on record', recordId); 22 | // var record = Data.findOne({_id: recordId}); 23 | // if(record){ 24 | // if(!record.active ){ 25 | // return Data.update({_id: recordId},{$set:{ 26 | // active: true 27 | // }}); 28 | // }else{ 29 | // return Data.update({_id: recordId},{$set:{ 30 | // active: false 31 | // }}); 32 | // } 33 | // }else{ 34 | // return 'Update failed.'; 35 | // } 36 | // }, 37 | 38 | // lockDataRecord: function(recordId){ 39 | // console.log('toggling locked status on record', recordId); 40 | // var record = Data.findOne({_id: recordId}); 41 | // if(record){ 42 | // if(record.locked){ 43 | // return Data.update({_id: recordId},{$set:{ 44 | // locked: false 45 | // }}); 46 | // }else{ 47 | // return Data.update({_id: recordId},{$set:{ 48 | // locked: true 49 | // }}); 50 | // } 51 | // }else{ 52 | // return 'Update failed.'; 53 | // } 54 | // }, 55 | 56 | // approveDataRecord: function(recordId){ 57 | // console.log('toggling approved status on record', recordId); 58 | // var record = Data.findOne({_id: recordId}); 59 | // if(record){ 60 | // if(record.approved){ 61 | // return Data.update({_id: recordId},{$set:{ 62 | // approved: false 63 | // }}); 64 | // }else{ 65 | // return Data.update({_id: recordId},{$set:{ 66 | // approved: true 67 | // }}); 68 | // } 69 | // }else{ 70 | // return 'Update failed.'; 71 | // } 72 | // } 73 | // }); 74 | -------------------------------------------------------------------------------- /client/workflow/static/eulaPage.html: -------------------------------------------------------------------------------- 1 | 27 | -------------------------------------------------------------------------------- /client/workflow/data/dataListPage.html: -------------------------------------------------------------------------------- 1 | 48 | 49 | 52 | 53 | 66 | -------------------------------------------------------------------------------- /client/workflow/studies/studiesRecordPage.html: -------------------------------------------------------------------------------- 1 | 81 | -------------------------------------------------------------------------------- /server/accounts.entry.js: -------------------------------------------------------------------------------- 1 | AccountsEntry = { 2 | settings: {}, 3 | config: function(appConfig) { 4 | this.settings = _.extend(this.settings, appConfig); 5 | return this.settings; 6 | } 7 | }; 8 | 9 | Meteor.startup(function() { 10 | AccountsEntry.config({ 11 | signupCode: 'penicillin' 12 | }); 13 | }); 14 | Accounts.config({ 15 | forbidClientAccountCreation: false 16 | }); 17 | 18 | 19 | Accounts.urls.resetPassword = function(token) { 20 | return Meteor.absoluteUrl('reset-password/' + token); 21 | }; 22 | 23 | Meteor.methods({ 24 | entryValidateSignupCode: function(signupCode) { 25 | console.log('received: ' + signupCode); 26 | console.log('should be: ' + AccountsEntry.settings.signupCode); 27 | 28 | //check(signupCode, String); 29 | 30 | return signupCode === AccountsEntry.settings.signupCode; 31 | }, 32 | accountsCreateUser: function(username, email, password, profile) { 33 | if (username) { 34 | return Accounts.createUser({ 35 | username: username, 36 | email: email, 37 | password: password, 38 | profile: profile 39 | //profile: AccountsEntry.settings.defaultProfile || {} 40 | }); 41 | } else { 42 | return Accounts.createUser({ 43 | email: email, 44 | password: password, 45 | profile: profile 46 | //profile: AccountsEntry.settings.defaultProfile || {} 47 | }); 48 | } 49 | } 50 | }); 51 | 52 | 53 | 54 | Meteor.startup(function(){ 55 | 56 | var dataCursor = Meteor.users.find(); 57 | 58 | var initFinished = false; 59 | var handle = dataCursor.observeChanges({ 60 | added: function (id, record) { 61 | if(initFinished){ 62 | console.log("Received a new user! " + id); 63 | console.log(record); 64 | 65 | //if(record.emails[0].verified === false){ 66 | Accounts.emailTemplates.siteName = "ClinicalTrials"; 67 | Accounts.emailTemplates.from = "ClinicalTrials Admin "; 68 | Accounts.emailTemplates.enrollAccount.subject = function (user) { 69 | return "Welcome to ClinicalTrials, " + user.profile.name; 70 | }; 71 | Accounts.emailTemplates.enrollAccount.text = function (user, url) { 72 | return "You have been selected to participate in building a better future!" 73 | + " To activate your account, simply click the link below:\n\n" + url; 74 | }; 75 | 76 | Accounts.sendVerificationEmail(id); 77 | //} 78 | } 79 | } 80 | }); 81 | initFinished = true; 82 | 83 | }); 84 | -------------------------------------------------------------------------------- /client/workflow/forms/formPreviewPage.js: -------------------------------------------------------------------------------- 1 | 2 | Router.map(function(){ 3 | this.route('formPreviewPage', { 4 | path: '/form/:id', 5 | template: 'formPreviewPage', 6 | data: function () { 7 | Session.set('currentForm', this.params.id); 8 | console.log('routing to: ', this.params.id); 9 | return Forms.findOne({_id: this.params.id}); 10 | }, 11 | }); 12 | }); 13 | Template.formPreviewPage.events({ 14 | 'click #formEditButton':function(){ 15 | Router.go('/builder/' + this._id); 16 | }, 17 | 'click #formDeleteButton':function(){ 18 | if(confirm('Are you sure you want to delete ' + this._id + "?")){ 19 | Forms.remove({_id: this._id}); 20 | Router.go('/'); 21 | } 22 | }, 23 | 'click #formPublishButton':function(){ 24 | if(this.stared){ 25 | Forms.update({_id: this._id},{$set:{ 26 | stared: false 27 | }}); 28 | }else{ 29 | Forms.update({_id: this._id},{$set:{ 30 | stared: true 31 | }}); 32 | } 33 | } 34 | // 'click #formCollectButton':function(){ 35 | // console.log('collecting data...'); 36 | // 37 | // var record = Forms.findOne({_id: Session.get('currentForm')}); 38 | // console.log('currentForm', record); 39 | // 40 | // var newDataRecord = { 41 | // createdAt: new Date(), 42 | // schema_id: this._id, 43 | // formName: this.formName, 44 | // data: {} 45 | // } 46 | // record.schema.forEach(function(block){ 47 | // if(Session.get('item-' + block._id + '-yesno')){ 48 | // newDataRecord.data[block._id] = Session.get('item-' + block._id + '-yesno'); 49 | // }else{ 50 | // newDataRecord.data[block._id] = $("#input-" + block._id).val(); 51 | // } 52 | // }); 53 | // Data.insert(newDataRecord); 54 | // } 55 | }); 56 | 57 | Template.formPreviewPage.helpers({ 58 | formSchema: function(){ 59 | console.log('form.schema', Session.get('currentForm')); 60 | 61 | var form = Forms.findOne(Session.get('currentForm')); 62 | console.log('form', form); 63 | if(form){ 64 | return form.schema; 65 | }else{ 66 | return []; 67 | } 68 | }, 69 | getStar:function(){ 70 | if(this.stared){ 71 | return 'fa-star'; 72 | }else{ 73 | return 'fa-star-o'; 74 | } 75 | }, 76 | getPublishText:function(){ 77 | if(this.stared){ 78 | return 'Unpublish Form'; 79 | }else{ 80 | return 'Publish Form'; 81 | } 82 | }, 83 | isPublished: function(){ 84 | if(this.stared){ 85 | return true; 86 | }else{ 87 | return false; 88 | } 89 | } 90 | }); 91 | -------------------------------------------------------------------------------- /client/workflow/static/.landingPage.html: -------------------------------------------------------------------------------- 1 | 64 | -------------------------------------------------------------------------------- /client/app/sidebar/sidebar.less: -------------------------------------------------------------------------------- 1 | 2 | #sidebar { 3 | overflow-y: auto; 4 | -webkit-overflow-scrolling: touch; 5 | 6 | 7 | .fa-plus{ 8 | left: 10px; 9 | top: 15px; 10 | position: absolute; 11 | } 12 | .sidebarMenuItem{ 13 | box-shadow: rgba(255, 255, 255, 0.15) 0 1px 0 0; 14 | display: block; 15 | line-height: 1.5em; 16 | padding: .75em 2em; 17 | position: relative; 18 | color: white; 19 | transition: all 200ms ease-in; 20 | cursor: pointer; 21 | text-decoration: none; 22 | } 23 | .sidebarMenuItem:hover{ 24 | cursor: pointer; 25 | text-decoration: underline; 26 | } 27 | 28 | hr{ 29 | margin-top: 5px; 30 | margin-bottom: 5px; 31 | } 32 | 33 | .sidebarMenuContents { 34 | a { 35 | color: white; 36 | box-shadow: rgba(255,255,255,.15) 0 1px 0 0; 37 | display: block; 38 | line-height: 1.5em; 39 | padding: .75em 2em; 40 | position: relative; 41 | } 42 | 43 | .count-list { 44 | background: rgba(255,255,255,.1); 45 | border-radius: 1em; 46 | float: right; 47 | font-size: .7rem; 48 | line-height: 1; 49 | margin-top: .25rem; 50 | margin-right: -1.5em; 51 | padding: .3em .5em; 52 | } 53 | 54 | // .listItem { 55 | // &:hover, 56 | // &:active, 57 | // &.active { 58 | // .count-list { background: #831d2c } 59 | // } 60 | // } 61 | } 62 | } 63 | 64 | 65 | 66 | 67 | // desktop 68 | @media only screen and (min-width: 960px) { 69 | 70 | } 71 | 72 | // landscape orientation 73 | @media only screen and (min-width: 960px) { 74 | #sidebar{ 75 | 76 | padding-right: 10px; 77 | padding-top: 50px; 78 | 79 | .panel{ 80 | margin-bottom: 20px; 81 | background-color: #fff; 82 | border: 1px solid transparent; 83 | border-radius: 4px; 84 | -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05); 85 | box-shadow: 0 1px 1px rgba(0, 0, 0, .05); 86 | } 87 | .panel-default{ 88 | border-color: #ddd; 89 | } 90 | 91 | } 92 | } 93 | 94 | // portrait orientation 95 | @media only screen and (max-width: 960px) { 96 | #sidebar{ 97 | .panel{ 98 | margin-bottom: 20px; 99 | background-color: inherit; 100 | border: 1px solid transparent; 101 | border-radius: 4px; 102 | -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05); 103 | 104 | a{ 105 | color: white; 106 | } 107 | } 108 | 109 | .panel-default{ 110 | border-color: none; 111 | } 112 | 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /client/workflow/sponsors/sponsorsEditPage.js: -------------------------------------------------------------------------------- 1 | Session.setDefault('selectedSponsorId', false); 2 | 3 | 4 | Router.map(function(){ 5 | this.route('newSponsorRoute', { 6 | path: '/newsponsor', 7 | template: 'sponsorsEditPage' 8 | }); 9 | 10 | 11 | this.route('sponsorsEditRoute', { 12 | path: '/editsponsor/:id', 13 | template: 'sponsorsEditPage', 14 | waitOn: function(){ 15 | return Meteor.subscribe('sponsors'); 16 | }, 17 | data: function () { 18 | return Sponsors.findOne({_id: this.params.id }); 19 | } 20 | }); 21 | }); 22 | 23 | 24 | //------------------------------------------------ 25 | // DATA LAYER 26 | 27 | Template.sponsorsEditPage.selectedSponsor = function(){ 28 | console.log(Session.get('selectedSponsorId')); 29 | if(Session.get('selectedSponsorId')._id){ 30 | return Sponsors.findOne({_id: Session.get('selectedSponsorId')._id }); 31 | }else{ 32 | return {}; 33 | } 34 | }; 35 | 36 | //------------------------------------------------ 37 | // EVENTS 38 | 39 | Template.sponsorsEditPage.events({ 40 | 'click #saveSponsorButton':function(){ 41 | console.count('click #saveSponsorButton'); 42 | if(this._id){ 43 | console.count('this._id: ' + this._id); 44 | 45 | var formObject = { 46 | _id: this._id, 47 | name: $('#sponsorNameInput').val(), 48 | description: $('#sponsorDescriptionInput').val(), 49 | url: $('#sponsorUrlInput').val(), 50 | createdAt: new Date(), 51 | owner: Meteor.user().profile.name, 52 | owner_id: Meteor.userId() 53 | }; 54 | 55 | console.log('Sponsors updated. Now trying to rename other collections.') 56 | Meteor.call('renameSponsor', formObject, function(error, result){ 57 | if(error){ 58 | console.error(error); 59 | } 60 | if(result){ 61 | console.log(result); 62 | } 63 | }); 64 | 65 | }else{ 66 | var recordId = Sponsors.insert({ 67 | name: $('#sponsorNameInput').val(), 68 | description: $('#sponsorDescriptionInput').val(), 69 | url: $('#sponsorUrlInput').val(), 70 | invite_code: $('#sponsorInviteCodeInput').val(), 71 | owner: Meteor.user().profile.name, 72 | owner_id: Meteor.userId(), 73 | creator: Meteor.user().profile.name, 74 | creator_id: Meteor.userId(), 75 | timestamp: new Date() 76 | }); 77 | console.log(recordId); 78 | 79 | 80 | } 81 | Router.go('/sponsors/'); 82 | } 83 | }); 84 | 85 | Template.sponsorsEditPage.getSponsorName = function(){ 86 | if(this.name){ 87 | return this.name; 88 | }else{ 89 | return "New Sponsor"; 90 | } 91 | }; 92 | -------------------------------------------------------------------------------- /client/workflow/landing/landingPage.theme.team.less: -------------------------------------------------------------------------------- 1 | 2 | #teamBiographies { 3 | margin-top: 80px; 4 | -webkit-font-smoothing: antialiased; 5 | } 6 | #teamBiographies .header { 7 | text-align: center; 8 | } 9 | #teamBiographies .header h3 { 10 | font-size: 23px; 11 | color: #555; 12 | line-height: 25px; 13 | font-weight: 300; 14 | margin-bottom: 40px; 15 | } 16 | #teamBiographies .testimonial { 17 | width: 90%; 18 | } 19 | 20 | @media (max-width: 767px) { 21 | #teamBiographies .testimonial { 22 | float: none !important; 23 | margin: 0 auto; 24 | margin-bottom: 45px; } 25 | } 26 | 27 | #teamBiographies .testimonial .quote { 28 | font-size: 13px; 29 | color: #3D3D3D; 30 | line-height: 24px; 31 | border: 1px solid #E2E2E2; 32 | padding: 12px 22px; 33 | border-radius: 6px; 34 | width: 90%; 35 | position: relative; 36 | } 37 | 38 | 39 | @media (max-width: 767px) { 40 | #teamBiographies .testimonial .quote { 41 | margin: 0 auto; 42 | } 43 | } 44 | 45 | #teamBiographies .testimonial .quote .arrow-down { 46 | position: absolute; 47 | bottom: 3px; 48 | left: 30px; 49 | } 50 | 51 | #teamBiographies .testimonial .quote .arrow-down .arrow, #teamBiographies .testimonial .quote .arrow-down .arrow-border { 52 | border-color: #fff transparent transparent; 53 | border-style: solid; 54 | border-width: 11px; 55 | cursor: pointer; 56 | position: absolute; 57 | top: 3px; 58 | z-index: 1002; 59 | } 60 | #teamBiographies .testimonial .quote .arrow-down .arrow-border { 61 | border-color: #E2E2E2 transparent transparent; 62 | border-width: 12px; 63 | top: 3px; 64 | z-index: 1001; 65 | left: -1px; 66 | } 67 | 68 | 69 | #teamBiographies .testimonial .author { 70 | margin-top: 40px; 71 | margin-left: 10px; 72 | } 73 | 74 | @media (max-width: 767px) { 75 | #teamBiographies .testimonial .author { 76 | margin-left: 6%; 77 | } 78 | } 79 | 80 | #teamBiographies .testimonial .author .pic { 81 | width: 71px; 82 | height: 71px; 83 | border-radius: 50px; 84 | float: left; 85 | position: relative; 86 | top: -12px; 87 | margin-right: 18px; 88 | border: 1px solid #ccc; 89 | } 90 | #teamBiographies .testimonial .author .name { 91 | color: #7a929c; 92 | line-height: 23px; 93 | font-weight: 500; 94 | } 95 | #teamBiographies .testimonial .author .company { 96 | font-size: 14px; 97 | color: #909090; 98 | line-height: 23px; 99 | font-weight: 400; 100 | } 101 | -------------------------------------------------------------------------------- /shared/collections.js: -------------------------------------------------------------------------------- 1 | Data = new Meteor.Collection("TrialsData"); 2 | Data.allow({ 3 | insert: function(){ 4 | return true; 5 | }, 6 | update: function () { 7 | return true; 8 | }, 9 | remove: function(){ 10 | return true; 11 | } 12 | }); 13 | 14 | // Forms = new Meteor.Collection("TrialsForms"); 15 | // Forms.allow({ 16 | // insert: function(){ 17 | // return true; 18 | // }, 19 | // update: function () { 20 | // return true; 21 | // }, 22 | // remove: function(){ 23 | // return true; 24 | // } 25 | // }); 26 | 27 | 28 | Studies = new Meteor.Collection("TrialsStudies"); 29 | Studies.allow({ 30 | insert: function(){ 31 | return true; 32 | }, 33 | update: function () { 34 | return true; 35 | }, 36 | remove: function(){ 37 | return true; 38 | } 39 | }); 40 | 41 | Sponsors = new Meteor.Collection("TrialsSponsors"); 42 | Sponsors.allow({ 43 | insert: function(){ 44 | return true; 45 | }, 46 | update: function () { 47 | return true; 48 | }, 49 | remove: function(){ 50 | return true; 51 | } 52 | }); 53 | 54 | Subjects = new Meteor.Collection("TrialsSubjects"); 55 | Subjects.allow({ 56 | insert: function(){ 57 | return true; 58 | }, 59 | update: function () { 60 | return true; 61 | }, 62 | remove: function(){ 63 | return true; 64 | } 65 | }); 66 | 67 | Comments = new Meteor.Collection("TrialsComments"); 68 | Comments.allow({ 69 | insert: function(){ 70 | return true; 71 | }, 72 | update: function () { 73 | return true; 74 | }, 75 | remove: function(){ 76 | return true; 77 | } 78 | }); 79 | 80 | 81 | // // TODO: refactor Items to FormItems 82 | // Items = new Meteor.Collection("TrialsItems"); 83 | // Items.allow({ 84 | // update: function(){ 85 | // return true; 86 | // }, 87 | // insert: function(){ 88 | // return true; 89 | // }, 90 | // remove: function(){ 91 | // return true; 92 | // } 93 | // }) 94 | 95 | 96 | 97 | 98 | if (Meteor.isServer) { 99 | if (Items.find().count() === 0) { 100 | _.each( 101 | ["penecillin", "vitamin d", "tetracycline", "epinephrine", "peptol bismol", "claritin", "dihydrogen monoxide", "asprin"], 102 | function (text, index) { 103 | Items.insert({ 104 | text: text, 105 | rank: index, 106 | labelText: text, 107 | inputValue: "", 108 | inputType: "text", 109 | inputPlaceholder: "...", 110 | elementType: 'input' 111 | }); 112 | }); 113 | } 114 | if(Sponsors.find().count() === 0){ 115 | Sponsors.insert({ 116 | name: "ACME Pharmaceuticals", 117 | createdAt: new Date() 118 | }); 119 | Sponsors.insert({ 120 | name: "Big Pharma, Inc", 121 | createdAt: new Date() 122 | }); 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /client/workflow/users/usersListPage/usersListPage.html: -------------------------------------------------------------------------------- 1 | 62 | 63 | 64 | 65 | 97 | -------------------------------------------------------------------------------- /client/app/navbars/navbarFooter.html: -------------------------------------------------------------------------------- 1 | 71 | -------------------------------------------------------------------------------- /client/workflow/studies/studiesRecordPage.js: -------------------------------------------------------------------------------- 1 | 2 | Router.map(function(){ 3 | this.route('studiesRecordPage', { 4 | path: '/studies/:id', 5 | template: 'studiesRecordPage', 6 | data: function () { 7 | Session.set('currentForm', this.params.id); 8 | console.log('routing to: ', this.params.id); 9 | return Studies.findOne({_id: this.params.id}); 10 | }, 11 | }); 12 | }); 13 | Template.studiesRecordPage.events({ 14 | 'click .individualFormRow':function(event){ 15 | Router.go('/form/' + this._id); 16 | event.preventDefault(); 17 | }, 18 | 'click #editStudyButton':function(){ 19 | Router.go('/edit/study/' + this._id); 20 | }, 21 | 'click #studyDeleteButton':function(){ 22 | if(confirm('Are you sure you want to delete ' + this._id + "?")){ 23 | Studies.remove({_id: this._id}); 24 | Router.go('/'); 25 | } 26 | }, 27 | 'click #studyPublishButton':function(){ 28 | if(this.stared){ 29 | Studies.update({_id: this._id},{$set:{ 30 | stared: false 31 | }}); 32 | }else{ 33 | Studies.update({_id: this._id},{$set:{ 34 | stared: true 35 | }}); 36 | } 37 | } 38 | // 'click #studyCollectButton':function(){ 39 | // console.log('collecting data...'); 40 | // 41 | // var record = Studies.findOne({_id: Session.get('currentForm')}); 42 | // console.log('currentForm', record); 43 | // 44 | // var newDataRecord = { 45 | // createdAt: new Date(), 46 | // schema_id: this._id, 47 | // studyName: this.studyName, 48 | // data: {} 49 | // } 50 | // record.schema.forEach(function(block){ 51 | // if(Session.get('item-' + block._id + '-yesno')){ 52 | // newDataRecord.data[block._id] = Session.get('item-' + block._id + '-yesno'); 53 | // }else{ 54 | // newDataRecord.data[block._id] = $("#input-" + block._id).val(); 55 | // } 56 | // }); 57 | // Data.insert(newDataRecord); 58 | // } 59 | }); 60 | 61 | Template.studiesRecordPage.helpers({ 62 | formsList: function(){ 63 | var study = Studies.findOne({_id: this._id}); 64 | if(study){ 65 | return Forms.find({ _id: {$in: study.forms }}); 66 | }else{ 67 | return []; 68 | } 69 | }, 70 | studySchema: function(){ 71 | console.log('study.schema', this.schema); 72 | var study = Studies.findOne(Session.get('currentForm')); 73 | if(study){ 74 | return study.schema; 75 | }else{ 76 | return []; 77 | } 78 | }, 79 | getStar:function(){ 80 | if(this.stared){ 81 | return 'fa-star'; 82 | }else{ 83 | return 'fa-star-o'; 84 | } 85 | }, 86 | getPublishText:function(){ 87 | if(this.stared){ 88 | return 'Unpublish Form'; 89 | }else{ 90 | return 'Publish Form'; 91 | } 92 | }, 93 | isPublished: function(){ 94 | if(this.stared){ 95 | return true; 96 | }else{ 97 | return false; 98 | } 99 | } 100 | }); 101 | -------------------------------------------------------------------------------- /tests/app.staticPages.js: -------------------------------------------------------------------------------- 1 | // // add tests to this file using the Nightwatch.js API 2 | // // http://nightwatchjs.org/api 3 | // 4 | // module.exports = { 5 | // "Static Pages" : function (client) { 6 | // client 7 | // .url("http://localhost:3000") 8 | // 9 | // .waitForElementVisible("body", 1000) 10 | // .verify.elementPresent('#landingPage') 11 | // .verify.elementPresent('#signInLink') 12 | // 13 | // .click("#signInLink").pause(200) 14 | // .pause(1000) 15 | // 16 | // .waitForElementVisible("#entrySignInPage", 1000) 17 | // .verify.elementPresent("#emailInput") 18 | // .verify.elementPresent("#passwordInput") 19 | // .verify.elementPresent("#entrySignInButton") 20 | // 21 | // .setValue("#emailInput", "sysadmin") 22 | // .setValue("#passwordInput", "sysadmin321$") 23 | // 24 | // .click("#entrySignInButton") 25 | // .pause(1000) 26 | // 27 | // .waitForElementVisible("#homePage", 1000) 28 | // 29 | // // open the menu 30 | // .click("#northeastDropDownLink") 31 | // .pause(100) 32 | // .waitForElementVisible("#northeastDropDownMenu", 100) 33 | // 34 | // .verify.elementPresent('#userProfileLink') 35 | // .verify.containsText("#userProfileLink", "Profile") 36 | // 37 | // .verify.elementPresent('#termsOfServiceLink') 38 | // .verify.containsText("#termsOfServiceLink", "End User License") 39 | // 40 | // .verify.elementPresent('#privacyPolicyLink') 41 | // .verify.containsText("#privacyPolicyLink", "Privacy Page") 42 | // 43 | // .verify.elementPresent('#glossaryLink') 44 | // .verify.containsText("#glossaryLink", "Glossary") 45 | // 46 | // // .verify.elementPresent('#feedbackSupportLink') 47 | // // .verify.containsText("#feedbackSupportLink", "Feedback & Support") 48 | // 49 | // .verify.elementPresent('#signOutLink') 50 | // .verify.containsText("#signOutLink", "Sign-Out") 51 | // 52 | // // click terms of service 53 | // .click("#termsOfServiceLink") 54 | // .pause(200) 55 | // .waitForElementVisible("#eulaPage", 1000) 56 | // 57 | // // click privacy policy 58 | // .click("#northeastDropDownLink") 59 | // .pause(500) 60 | // .verify.elementPresent("#northeastDropDownMenu") 61 | // .click("#privacyPolicyLink") 62 | // .pause(200) 63 | // .waitForElementVisible("#privacyPage", 1000) 64 | // 65 | // // click glossary 66 | // .click("#northeastDropDownLink") 67 | // .pause(500) 68 | // .verify.elementPresent("#northeastDropDownMenu") 69 | // .click("#glossaryLink") 70 | // .pause(200) 71 | // .waitForElementVisible("#glossaryPage", 1000) 72 | // 73 | // // click glossary 74 | // .click("#northeastDropDownLink") 75 | // .pause(500) 76 | // .verify.elementPresent("#northeastDropDownMenu") 77 | // .click("#signOutLink") 78 | // .pause(2000) 79 | // .waitForElementVisible("#landingPage", 1000) 80 | // .end(); 81 | // } 82 | // }; 83 | -------------------------------------------------------------------------------- /client/workflow/.accounts/entrySignUp/entrySignUpPage.html: -------------------------------------------------------------------------------- 1 | 78 | -------------------------------------------------------------------------------- /client/workflow/landing/landingPage.theme.hero.less: -------------------------------------------------------------------------------- 1 | #landingPage{ 2 | #hero { 3 | background: #4B4848; 4 | background-size: cover; 5 | background-image: url("/images/landing/hero/flu-shot.jpg"); 6 | //background-image: url("http://24.media.tumblr.com/899355a7363be380170ecfcbdc9744d7/tumblr_myp93odkni1st5lhmo1_1280.jpg"); 7 | background-position: center center; 8 | height: 650px; 9 | position: relative; 10 | //top: -60px; 11 | padding-top: 115px; 12 | 13 | .container { 14 | position: relative; 15 | z-index: 33; 16 | //top: 400px 17 | } 18 | h1.hero-text { 19 | text-align: center; 20 | font-family: "Roboto"; 21 | font-size: 38px; 22 | font-weight: 300; 23 | color: #fff; 24 | text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5); } 25 | @media (max-width: 767px) { 26 | #hero h1.hero-text { 27 | font-size: 30px; 28 | } 29 | } 30 | .sub-text { 31 | -webkit-font-smoothing: antialiased; 32 | -webkit-animation-delay: 0.6s; 33 | -moz-animation-delay: 0.6s; 34 | -o-animation-delay: 0.6s; 35 | -ms-animation-delay: 0.6s; 36 | animation-delay: 0.6s; 37 | margin: 0 auto; 38 | margin-top: 25px; 39 | text-align: center; 40 | color: #fff; 41 | font-weight: 400; 42 | font-size: 17px; 43 | text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3); 44 | width: 50%; 45 | } 46 | @media (max-width: 991px) { 47 | .sub-text { 48 | width: 70%; 49 | } 50 | } 51 | @media (max-width: 767px) { 52 | .sub-text { 53 | font-size: 15px; 54 | } 55 | } 56 | .cta { 57 | -webkit-animation-delay: 0.6s; 58 | -moz-animation-delay: 0.6s; 59 | -o-animation-delay: 0.6s; 60 | -ms-animation-delay: 0.6s; 61 | animation-delay: 0.6s; 62 | text-align: center; 63 | margin-top: 60px; 64 | a { 65 | margin: 0px 20px; 66 | } 67 | } 68 | @media (max-width: 767px) { 69 | .cta a { 70 | font-size: 14px; 71 | padding: 12px 25px; 72 | margin: 0px 15px 15px 0px; } } 73 | .browsers { 74 | margin-top: 70px; 75 | text-align: center; 76 | img { 77 | margin: 0 auto; 78 | } 79 | } 80 | @media (max-width: 767px) { 81 | .browsers { 82 | margin-top: 65px; 83 | } 84 | } 85 | } 86 | @media (max-width: 991px) { 87 | #hero { 88 | padding-top: 100px; 89 | } 90 | } 91 | @media (max-width: 767px) { 92 | #hero { 93 | height: 550px; 94 | } 95 | } 96 | #hero:before { 97 | position: absolute; 98 | content: ''; 99 | left: 0; 100 | bottom: 0; 101 | width: 100%; 102 | height: 420px; 103 | //background: -webkit-linear-gradient(top, rgba(255, 255, 255, 0) 0%, rgba(0, 0, 0, 0) 1%, rgba(0, 0, 0, 0.05) 26%, rgba(0, 0, 0, 0.55) 71%, black 100%); 104 | } 105 | #hero:after { 106 | position: absolute; 107 | content: ''; 108 | left: 0; 109 | top: 0; 110 | width: 100%; 111 | height: 100%; 112 | background: rgba(6, 13, 32, 0.35); } 113 | } 114 | --------------------------------------------------------------------------------