├── .gitignore ├── .sane-cli ├── README.md ├── aws ├── README.md └── lambda │ ├── CreateThumbnail.js │ └── package.json ├── client ├── .bowerrc ├── .editorconfig ├── .ember-cli ├── .gitignore ├── .jshintrc ├── .travis.yml ├── .watchmanconfig ├── README.md ├── app │ ├── adapters │ │ └── application.js │ ├── app.js │ ├── helpers │ │ ├── .gitkeep │ │ ├── current-date.js │ │ └── trigger-event.js │ ├── index.html │ ├── initializers │ │ ├── file-uploader-service.js │ │ ├── geo-google-service.js │ │ ├── hide-loading-screen.js │ │ └── history-service.js │ ├── instance-initializers │ │ └── hide-loading-screen.js │ ├── mixins │ │ └── scroll-top.js │ ├── pods │ │ ├── 400 │ │ │ ├── controller.js │ │ │ └── template.hbs │ │ ├── admin │ │ │ └── route.js │ │ ├── application │ │ │ ├── controller.js │ │ │ ├── route.js │ │ │ ├── template.hbs │ │ │ └── view.js │ │ ├── company │ │ │ ├── controller.js │ │ │ ├── detail │ │ │ │ ├── controller.js │ │ │ │ ├── model.js │ │ │ │ ├── route.js │ │ │ │ ├── template.hbs │ │ │ │ └── view.js │ │ │ ├── model.js │ │ │ ├── register │ │ │ │ ├── controller.js │ │ │ │ ├── model.js │ │ │ │ ├── route.js │ │ │ │ ├── template.hbs │ │ │ │ └── view.js │ │ │ ├── route.js │ │ │ └── template.hbs │ │ ├── components │ │ │ ├── content-card │ │ │ │ └── template.hbs │ │ │ ├── content-raw │ │ │ │ └── template.hbs │ │ │ ├── file-upload │ │ │ │ ├── component.js │ │ │ │ └── template.hbs │ │ │ ├── files-upload │ │ │ │ ├── component.js │ │ │ │ └── template.hbs │ │ │ ├── icon-repeater │ │ │ │ ├── component.js │ │ │ │ └── template.hbs │ │ │ ├── login-panel │ │ │ │ ├── component.js │ │ │ │ └── template.hbs │ │ │ ├── quill-editor │ │ │ │ ├── component.js │ │ │ │ └── template.hbs │ │ │ ├── select-serializer │ │ │ │ ├── component.js │ │ │ │ └── template.hbs │ │ │ ├── template-footer │ │ │ │ ├── component.js │ │ │ │ └── template.hbs │ │ │ └── template-header │ │ │ │ ├── component.js │ │ │ │ └── template.hbs │ │ ├── index │ │ │ ├── route.js │ │ │ └── template.hbs │ │ ├── login │ │ │ └── template.hbs │ │ ├── logout │ │ │ └── route.js │ │ ├── membership │ │ │ ├── model.js │ │ │ ├── route.js │ │ │ └── template.hbs │ │ ├── page │ │ │ ├── controller.js │ │ │ ├── model.js │ │ │ ├── route.js │ │ │ └── template.hbs │ │ ├── photo │ │ │ ├── model.js │ │ │ ├── route.js │ │ │ └── template.hbs │ │ ├── project │ │ │ └── model.js │ │ ├── protected │ │ │ ├── route.js │ │ │ └── template.hbs │ │ ├── register │ │ │ ├── route.js │ │ │ └── template.hbs │ │ ├── section │ │ │ ├── model.js │ │ │ ├── route.js │ │ │ └── template.hbs │ │ ├── test │ │ │ ├── model.js │ │ │ ├── route.js │ │ │ └── template.hbs │ │ ├── test2 │ │ │ ├── route.js │ │ │ └── template.hbs │ │ ├── translation │ │ │ ├── model.js │ │ │ ├── route.js │ │ │ └── template.hbs │ │ └── user │ │ │ ├── model.js │ │ │ ├── route.js │ │ │ └── template.hbs │ ├── router.js │ ├── serializers │ │ ├── application.js │ │ ├── company.js │ │ └── test.js │ ├── services │ │ ├── admin.js │ │ ├── file-uploader.js │ │ ├── geo-google.js │ │ └── history.js │ ├── styles │ │ ├── INTRODUCTION.md │ │ ├── _color-definitions.scss │ │ ├── _functions.scss │ │ ├── _mixins.scss │ │ ├── _variables.scss │ │ ├── animation │ │ │ ├── _animation.scss │ │ │ ├── demo.css │ │ │ └── demo.html │ │ ├── app.scss │ │ ├── badge │ │ │ ├── README.md │ │ │ ├── _badge.scss │ │ │ └── snippets │ │ │ │ ├── badge-on-icon-icon-demo.html │ │ │ │ ├── badge-on-icon-icon.html │ │ │ │ ├── badge-on-icon-text-demo.html │ │ │ │ ├── badge-on-icon-text.html │ │ │ │ ├── badge-on-text-icon-demo.html │ │ │ │ ├── badge-on-text-icon.html │ │ │ │ ├── badge-on-text-text-demo.html │ │ │ │ └── badge-on-text-text.html │ │ ├── button │ │ │ ├── README.md │ │ │ ├── _button.scss │ │ │ └── snippets │ │ │ │ ├── fab-colored-ripple.html │ │ │ │ ├── fab-colored.html │ │ │ │ ├── fab-disabled.html │ │ │ │ ├── fab-mini-colored.html │ │ │ │ ├── fab-mini.html │ │ │ │ ├── fab-ripple.html │ │ │ │ ├── fab.html │ │ │ │ ├── flat-accent.html │ │ │ │ ├── flat-disabled.html │ │ │ │ ├── flat-primary.html │ │ │ │ ├── flat-ripple.html │ │ │ │ ├── flat.html │ │ │ │ ├── icon-colored.html │ │ │ │ ├── icon.html │ │ │ │ ├── raised-accent.html │ │ │ │ ├── raised-colored.html │ │ │ │ ├── raised-disabled.html │ │ │ │ ├── raised-ripple-accent.html │ │ │ │ ├── raised-ripple.html │ │ │ │ └── raised.html │ │ ├── card │ │ │ ├── README.md │ │ │ ├── _card.scss │ │ │ └── snippets │ │ │ │ ├── event.html │ │ │ │ ├── image.html │ │ │ │ ├── square.html │ │ │ │ └── wide.html │ │ ├── checkbox │ │ │ ├── README.md │ │ │ ├── _checkbox.scss │ │ │ └── snippets │ │ │ │ ├── check-off.html │ │ │ │ └── check-on.html │ │ ├── data-table │ │ │ ├── README.md │ │ │ ├── _data-table.scss │ │ │ └── snippets │ │ │ │ └── data-table.html │ │ ├── demos.css │ │ ├── footer │ │ │ ├── README.md │ │ │ ├── _mega_footer.scss │ │ │ ├── _mini_footer.scss │ │ │ └── snippets │ │ │ │ ├── mega-footer.html │ │ │ │ └── mini-footer.html │ │ ├── grid │ │ │ ├── README.md │ │ │ ├── _grid.scss │ │ │ └── snippets │ │ │ │ ├── codepen-grid.css │ │ │ │ ├── grid-demo.html │ │ │ │ └── grid.html │ │ ├── icon-toggle │ │ │ ├── README.md │ │ │ ├── _icon-toggle.scss │ │ │ └── snippets │ │ │ │ ├── icon-off.html │ │ │ │ └── icon-on.html │ │ ├── images │ │ │ ├── buffer.svg │ │ │ ├── tick-mask.svg │ │ │ └── tick.svg │ │ ├── index.html │ │ ├── layout │ │ │ ├── README.md │ │ │ ├── _layout.scss │ │ │ └── snippets │ │ │ │ ├── fixed-drawer-demo.html │ │ │ │ ├── fixed-drawer.html │ │ │ │ ├── fixed-header-demo.html │ │ │ │ ├── fixed-header-drawer-demo.html │ │ │ │ ├── fixed-header-drawer.html │ │ │ │ ├── fixed-header.html │ │ │ │ ├── fixed-tabs-demo.html │ │ │ │ ├── fixed-tabs.html │ │ │ │ ├── scrollable-tabs-demo.html │ │ │ │ ├── scrollable-tabs.html │ │ │ │ ├── scrolling-header-demo.html │ │ │ │ ├── scrolling-header.html │ │ │ │ ├── transparent-demo.html │ │ │ │ ├── transparent.html │ │ │ │ ├── waterfall-header-demo.html │ │ │ │ └── waterfall-header.html │ │ ├── list │ │ │ ├── _list.scss │ │ │ └── snippets │ │ │ │ ├── action.html │ │ │ │ ├── icon.html │ │ │ │ ├── list-control.html │ │ │ │ ├── list-item.html │ │ │ │ ├── three-line.html │ │ │ │ └── two-line.html │ │ ├── material-design-lite-grid.scss │ │ ├── material-design-lite.scss │ │ ├── menu │ │ │ ├── README.md │ │ │ ├── _menu.scss │ │ │ └── snippets │ │ │ │ ├── codepen-lower-buttons.css │ │ │ │ ├── codepen-top-buttons.css │ │ │ │ ├── lower-left-demo.html │ │ │ │ ├── lower-left.html │ │ │ │ ├── lower-right-demo.html │ │ │ │ ├── lower-right.html │ │ │ │ ├── top-left-demo.html │ │ │ │ ├── top-left.html │ │ │ │ ├── top-right-demo.html │ │ │ │ └── top-right.html │ │ ├── palette │ │ │ ├── _palette.scss │ │ │ ├── demo.css │ │ │ └── demo.html │ │ ├── progress │ │ │ ├── README.md │ │ │ ├── _progress.scss │ │ │ └── snippets │ │ │ │ ├── progress-buffering-demo.html │ │ │ │ ├── progress-buffering.html │ │ │ │ ├── progress-default-demo.html │ │ │ │ ├── progress-default.html │ │ │ │ ├── progress-indeterminate-demo.html │ │ │ │ └── progress-indeterminate.html │ │ ├── radio │ │ │ ├── README.md │ │ │ ├── _radio.scss │ │ │ └── snippets │ │ │ │ ├── radio-off.html │ │ │ │ └── radio-on.html │ │ ├── resets │ │ │ ├── _h5bp.scss │ │ │ ├── _mobile.scss │ │ │ └── _resets.scss │ │ ├── ripple │ │ │ └── _ripple.scss │ │ ├── shadow │ │ │ ├── README.md │ │ │ ├── _shadow.scss │ │ │ ├── demo.css │ │ │ └── demo.html │ │ ├── slider │ │ │ ├── README.md │ │ │ ├── _slider.scss │ │ │ └── snippets │ │ │ │ ├── demo.html │ │ │ │ ├── slider-default-demo.html │ │ │ │ ├── slider-default.html │ │ │ │ ├── slider-starting-value-demo.html │ │ │ │ └── slider-starting-value.html │ │ ├── snackbar │ │ │ ├── README.md │ │ │ ├── _snackbar.scss │ │ │ └── snippets │ │ │ │ ├── snackbar.html │ │ │ │ └── toast.html │ │ ├── spinner │ │ │ ├── README.md │ │ │ ├── _spinner.scss │ │ │ └── snippets │ │ │ │ ├── spinner-default.html │ │ │ │ └── spinner-single-color.html │ │ ├── styleguide.scss │ │ ├── switch │ │ │ ├── README.md │ │ │ ├── _switch.scss │ │ │ └── snippets │ │ │ │ ├── switch-off.html │ │ │ │ └── switch-on.html │ │ ├── tabs │ │ │ ├── README.md │ │ │ ├── _tabs.scss │ │ │ └── snippets │ │ │ │ └── tabs.html │ │ ├── template.scss │ │ ├── textfield │ │ │ ├── README.md │ │ │ ├── _textfield.scss │ │ │ └── snippets │ │ │ │ ├── textfield-expanding-demo.html │ │ │ │ ├── textfield-expanding.html │ │ │ │ ├── textfield-floating-numeric-demo.html │ │ │ │ ├── textfield-floating-numeric.html │ │ │ │ ├── textfield-floating-text-demo.html │ │ │ │ ├── textfield-floating-text.html │ │ │ │ ├── textfield-multi-line-demo.html │ │ │ │ ├── textfield-multi-line.html │ │ │ │ ├── textfield-numeric-demo.html │ │ │ │ ├── textfield-numeric.html │ │ │ │ ├── textfield-text-demo.html │ │ │ │ └── textfield-text.html │ │ ├── tooltip │ │ │ ├── README.md │ │ │ ├── _tooltip.scss │ │ │ └── snippets │ │ │ │ ├── tooltip-large.html │ │ │ │ ├── tooltip-multiline.html │ │ │ │ ├── tooltip-rich.html │ │ │ │ └── tooltip-simple.html │ │ └── typography │ │ │ ├── README.md │ │ │ ├── _typography.scss │ │ │ ├── demo.css │ │ │ └── demo.html │ ├── templates │ │ ├── admin.hbs │ │ ├── admin │ │ │ ├── edit │ │ │ │ ├── page.hbs │ │ │ │ ├── photo.hbs │ │ │ │ └── section.hbs │ │ │ ├── index │ │ │ │ ├── page.hbs │ │ │ │ ├── photo.hbs │ │ │ │ └── section.hbs │ │ │ └── new │ │ │ │ ├── page.hbs │ │ │ │ ├── photo.hbs │ │ │ │ └── section.hbs │ │ └── loading.hbs │ ├── transforms │ │ ├── array.js │ │ └── dateiso.js │ └── utils │ │ └── to-geo-json.js ├── bower.json ├── config │ └── environment.js ├── ember-cli-build.js ├── package.json ├── public │ ├── assets │ │ ├── android-desktop.png │ │ ├── app-icon.png │ │ ├── button_degradation.png │ │ ├── codepen-logo.png │ │ ├── codepen.js │ │ ├── colors.svg │ │ ├── comp_badges.png │ │ ├── comp_buttons.png │ │ ├── comp_cards.png │ │ ├── comp_layout.png │ │ ├── comp_loading.png │ │ ├── comp_menus.png │ │ ├── comp_sliders.png │ │ ├── comp_tables.png │ │ ├── comp_textfields.png │ │ ├── comp_toggles.png │ │ ├── comp_tooltips.png │ │ ├── compindex.png │ │ ├── compindex_2x.png │ │ ├── components.css │ │ ├── components.js │ │ ├── components.png │ │ ├── components.svg │ │ ├── components_2x.png │ │ ├── components_mo.svg │ │ ├── customize.png │ │ ├── customize.svg │ │ ├── customize_2x.png │ │ ├── customize_mo.svg │ │ ├── customizer.css │ │ ├── customizer.js │ │ ├── customizer.png │ │ ├── demos │ │ │ ├── dog.png │ │ │ ├── image_card.jpg │ │ │ ├── transparent.jpg │ │ │ └── welcome_card.jpg │ │ ├── faq │ │ │ └── subscribe-single-issue.png │ │ ├── favicon.png │ │ ├── github_white_24.svg │ │ ├── google-services.png │ │ ├── header.jpg │ │ ├── header_2x.jpg │ │ ├── icons.svg │ │ ├── ie.css │ │ ├── img-1.png │ │ ├── img-2.png │ │ ├── index.js │ │ ├── ios-desktop.png │ │ ├── logo.png │ │ ├── logo.svg │ │ ├── main.css │ │ ├── main.js │ │ ├── mo.svg │ │ ├── prism-bash.min.js │ │ ├── prism-css.min.js │ │ ├── prism-default.css │ │ ├── prism-javascript.min.js │ │ ├── prism-markup.min.js │ │ ├── prism.js │ │ ├── rich-media-gallery.png │ │ ├── shapes.svg │ │ ├── showcase │ │ │ ├── contributor.jpg │ │ │ ├── contributor_2x.jpg │ │ │ ├── developers.jpg │ │ │ ├── developers_2x.jpg │ │ │ ├── rework.jpg │ │ │ ├── rework_2x.jpg │ │ │ ├── sunroof.jpg │ │ │ ├── sunroof_2x.jpg │ │ │ ├── wallet.jpg │ │ │ ├── wallet_2x.jpg │ │ │ ├── work_partners.jpg │ │ │ └── work_partners_2x.jpg │ │ ├── sliders_degradation.png │ │ ├── snippets.js │ │ ├── styles.png │ │ ├── styles.svg │ │ ├── styles_2x.png │ │ ├── styles_mo.svg │ │ ├── table_degradation.png │ │ ├── template-preview.png │ │ ├── templates.png │ │ ├── templates.svg │ │ ├── templates │ │ │ ├── android-dot-com.jpg │ │ │ ├── android-dot-com_2x.jpg │ │ │ ├── article.jpg │ │ │ ├── article_2x.jpg │ │ │ ├── blog.jpg │ │ │ ├── blog_2x.jpg │ │ │ ├── dashboard.jpg │ │ │ ├── dashboard_2x.jpg │ │ │ ├── general.jpg │ │ │ ├── general_2x.jpg │ │ │ ├── product.jpg │ │ │ ├── product_2x.jpg │ │ │ ├── text-only.jpg │ │ │ └── text-only_2x.jpg │ │ ├── templates_2x.png │ │ └── templates_mo.svg │ ├── crossdomain.xml │ └── robots.txt ├── testem.json ├── tests │ ├── .jshintrc │ ├── helpers │ │ ├── destroy-app.js │ │ ├── module-for-acceptance.js │ │ ├── resolver.js │ │ └── start-app.js │ ├── index.html │ ├── integration │ │ ├── .gitkeep │ │ └── pods │ │ │ └── components │ │ │ └── file-upload │ │ │ └── component-test.js │ ├── test-helper.js │ └── unit │ │ ├── .gitkeep │ │ ├── pods │ │ ├── membership │ │ │ ├── model-test.js │ │ │ └── route-test.js │ │ ├── page │ │ │ ├── model-test.js │ │ │ └── route-test.js │ │ ├── photo │ │ │ ├── model-test.js │ │ │ └── route-test.js │ │ ├── protected │ │ │ └── route-test.js │ │ ├── section │ │ │ ├── model-test.js │ │ │ └── route-test.js │ │ ├── test2 │ │ │ └── route-test.js │ │ ├── translation │ │ │ ├── model-test.js │ │ │ └── route-test.js │ │ └── user │ │ │ └── model-test.js │ │ ├── routes │ │ ├── test-test.js │ │ └── test2-test.js │ │ └── test │ │ ├── model-test.js │ │ └── route-test.js └── vendor │ ├── .gitkeep │ ├── ecms-globals.js │ ├── es5-polyfill.js │ └── phantom-polyfill.js ├── fig.yml ├── package.json └── server ├── .editorconfig ├── .gitignore ├── .sailsrc ├── README.md ├── api ├── blueprints │ ├── create.js │ ├── destroy.js │ ├── find.js │ ├── findone.js │ ├── populate.js │ └── update.js ├── controllers │ ├── .gitkeep │ ├── AmazonController.js │ ├── AppController.js │ ├── AuthController.js │ ├── CompanyController.js │ ├── LookupController.js │ ├── MembershipController.js │ ├── PageController.js │ ├── PhotoController.js │ ├── ProjectController.js │ ├── SectionController.js │ ├── TranslationController.js │ └── UserController.js ├── hooks │ └── ecms-hook │ │ └── index.js ├── models │ ├── .gitkeep │ ├── Company.js │ ├── Membership.js │ ├── Page.js │ ├── Photo.js │ ├── Project.js │ ├── Section.js │ ├── Translation.js │ ├── User.js │ └── UserPublic.js ├── policies │ ├── AuditPolicy.js │ ├── CriteriaPolicy.js │ ├── ModelPolicy.js │ ├── OwnerPolicy.js │ ├── PermissionPolicy.js │ ├── RolePolicy.js │ ├── hasToken.js │ ├── injectCompany.js │ ├── isAdmin.js │ ├── isCompanyAdminOrOwner.js │ ├── isCompanyAdminOrOwnerOrID.js │ ├── isCompanyAdminOrOwnerOrNewOrUnknown.js │ ├── isIDsOnly.js │ └── sessionAuth.js ├── responses │ ├── badRequest.js │ ├── forbidden.js │ ├── notFound.js │ ├── ok.js │ └── serverError.js └── services │ ├── .gitkeep │ ├── Email.js │ ├── Ember.js │ ├── PermissionService.js │ ├── Token.js │ ├── Utility.js │ └── passport.js ├── app.js ├── assets ├── favicon.ico ├── fonts │ └── WorkSans-Light.ttf ├── images │ └── .gitkeep ├── index.html ├── js │ └── dependencies │ │ └── sails.io.js ├── public │ ├── inject.js │ └── shortlist.js ├── robots.txt ├── styles │ └── importer.less └── templates │ └── .gitkeep ├── config ├── autoreload.js ├── aws.js ├── blueprint.js ├── blueprints.js ├── bootstrap.js ├── connections.js ├── cors.js ├── csrf.js ├── env │ ├── development.js │ └── production.js ├── globals.js ├── http.js ├── i18n.js ├── installedHooks.js ├── jwt.js ├── locales │ ├── _README.md │ ├── de.json │ ├── en.json │ ├── es.json │ └── fr.json ├── log.js ├── models.js ├── permission.js ├── permissions.js ├── policies.js ├── routes.js ├── sendgrid.js ├── session.js ├── sockets.js └── views.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | tmp/ 2 | dist/ 3 | node_modules/ 4 | bower_components/ 5 | aws/lambda.zip 6 | s/ 7 | -------------------------------------------------------------------------------- /.sane-cli: -------------------------------------------------------------------------------- 1 | { 2 | "apps": [ 3 | "client", 4 | "server" 5 | ], 6 | "disableAnalytics": false, 7 | "database": "mongo", 8 | "docker": false, 9 | "verbose": false, 10 | "skipNpm": false, 11 | "skipBower": false 12 | } -------------------------------------------------------------------------------- /aws/lambda/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "thumb", 3 | "version": "0.0.1", 4 | "description": "thumb", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "", 11 | "dependencies": { 12 | "async": "^1.4.2", 13 | "gm": "^1.18.1", 14 | "lodash": "^3.10.0" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /client/.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "bower_components", 3 | "analytics": false 4 | } 5 | -------------------------------------------------------------------------------- /client/.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | 8 | [*] 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | insert_final_newline = true 13 | indent_style = space 14 | indent_size = 2 15 | 16 | [*.js] 17 | indent_style = space 18 | indent_size = 2 19 | 20 | [*.hbs] 21 | insert_final_newline = false 22 | indent_style = space 23 | indent_size = 2 24 | 25 | [*.css] 26 | indent_style = space 27 | indent_size = 2 28 | 29 | [*.html] 30 | indent_style = space 31 | indent_size = 2 32 | 33 | [*.{diff,md}] 34 | trim_trailing_whitespace = false 35 | -------------------------------------------------------------------------------- /client/.ember-cli: -------------------------------------------------------------------------------- 1 | { 2 | "liveReload" : false, 3 | /** 4 | Ember CLI sends analytics information by default. The data is completely 5 | anonymous, but there are times when you might want to disable this behavior. 6 | "port": 9999, 7 | "host": "0.0.0.0", 8 | "liveReload": false, 9 | "proxy": "http://aqueous-bayou-5108.herokuapp.com/", 10 | "environment": "development" 11 | Setting `disableAnalytics` to true will prevent any data from being sent. 12 | */ 13 | "disableAnalytics": false, 14 | "usePods": true 15 | } 16 | -------------------------------------------------------------------------------- /client/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | 7 | # dependencies 8 | /node_modules 9 | /bower_components 10 | 11 | # misc 12 | /.sass-cache 13 | /connect.lock 14 | /coverage/* 15 | /libpeerconnection.log 16 | npm-debug.log 17 | testem.log 18 | -------------------------------------------------------------------------------- /client/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "predef": [ 3 | "document", 4 | "window", 5 | "-Promise" 6 | ], 7 | "browser": true, 8 | "boss": true, 9 | "curly": true, 10 | "debug": false, 11 | "devel": true, 12 | "eqeqeq": true, 13 | "evil": true, 14 | "forin": false, 15 | "immed": false, 16 | "laxbreak": false, 17 | "newcap": true, 18 | "noarg": true, 19 | "noempty": false, 20 | "nonew": false, 21 | "nomen": false, 22 | "onevar": false, 23 | "plusplus": false, 24 | "regexp": false, 25 | "undef": true, 26 | "sub": true, 27 | "strict": false, 28 | "white": false, 29 | "eqnull": true, 30 | "esnext": true, 31 | "unused": true 32 | } 33 | -------------------------------------------------------------------------------- /client/.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: node_js 3 | node_js: 4 | - "0.12" 5 | 6 | sudo: false 7 | 8 | cache: 9 | directories: 10 | - node_modules 11 | 12 | before_install: 13 | - export PATH=/usr/local/phantomjs-2.0.0/bin:$PATH 14 | - "npm config set spin false" 15 | - "npm install -g npm@^2" 16 | 17 | install: 18 | - npm install -g bower 19 | - npm install 20 | - bower install 21 | 22 | script: 23 | - npm test 24 | -------------------------------------------------------------------------------- /client/.watchmanconfig: -------------------------------------------------------------------------------- 1 | { 2 | "ignore_dirs": ["tmp", "dist"] 3 | } 4 | -------------------------------------------------------------------------------- /client/app/adapters/application.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | export default DS.RESTAdapter.extend({ 4 | coalesceFindRequests: true, 5 | namespace: 'api/v1', 6 | //this is dependent on production/development environment 7 | //It is configured in config/environment.js 8 | //host: ClientENV.hostUrl 9 | //add IP from $DOCKER_HOST if --docker flag is set 10 | //host: 'http://192.168.59.103:1337' 11 | }); -------------------------------------------------------------------------------- /client/app/app.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import Resolver from 'ember/resolver'; 3 | import loadInitializers from 'ember/load-initializers'; 4 | import config from './config/environment'; 5 | 6 | let App; 7 | 8 | Ember.MODEL_FACTORY_INJECTIONS = true; 9 | 10 | App = Ember.Application.extend({ 11 | modulePrefix: config.modulePrefix, 12 | podModulePrefix: config.podModulePrefix, 13 | Resolver 14 | }); 15 | 16 | loadInitializers(App, config.modulePrefix); 17 | 18 | export default App; 19 | -------------------------------------------------------------------------------- /client/app/helpers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/app/helpers/.gitkeep -------------------------------------------------------------------------------- /client/app/helpers/current-date.js: -------------------------------------------------------------------------------- 1 | // app/helpers/current-date.js 2 | import Ember from 'ember'; 3 | 4 | export default Ember.Handlebars.makeBoundHelper(function() { 5 | return moment().format('LL'); // Using moments format 'LL' 6 | }); 7 | -------------------------------------------------------------------------------- /client/app/helpers/trigger-event.js: -------------------------------------------------------------------------------- 1 | // app/helpers/current-date.js 2 | import Ember from 'ember'; 3 | 4 | export default Ember.Handlebars.registerBoundHelper(function(options) { 5 | return moment().format('LL'); // Using moments format 'LL' 6 | }); 7 | -------------------------------------------------------------------------------- /client/app/initializers/file-uploader-service.js: -------------------------------------------------------------------------------- 1 | export function initialize(container, application) { 2 | application.inject('route', 'fileUploader', 'service:file-uploader'); 3 | application.inject('component', 'fileUploader', 'service:file-uploader'); 4 | } 5 | 6 | export default { 7 | name: 'file-uploader-service', 8 | initialize: initialize 9 | }; 10 | -------------------------------------------------------------------------------- /client/app/initializers/geo-google-service.js: -------------------------------------------------------------------------------- 1 | export function initialize(container, application) { 2 | application.inject('route', 'geoGoogleService', 'service:geo-google'); 3 | application.inject('component', 'geoGoogleService', 'service:geo-google'); 4 | application.inject('controller', 'geoGoogleService', 'service:geo-google'); 5 | } 6 | 7 | export default { 8 | name: 'geo-google-service', 9 | initialize: initialize 10 | }; 11 | -------------------------------------------------------------------------------- /client/app/initializers/hide-loading-screen.js: -------------------------------------------------------------------------------- 1 | import hideLoadingScreenInstanceInitializer from '../instance-initializers/hide-loading-screen'; 2 | import Ember from 'ember'; 3 | 4 | const EMBER_VERSION_REGEX = /^([0-9]+)\.([0-9]+)\.([0-9]+)(?:(?:\-(alpha|beta)\.([0-9]+)(?:\.([0-9]+))?)?)?(?:\+(canary))?(?:\.([0-9abcdef]+))?(?:\-([A-Za-z0-9\.\-]+))?(?:\+([A-Za-z0-9\.\-]+))?$/; 5 | 6 | /** 7 | * VERSION_INFO[i] is as follows: 8 | * 9 | * 0 complete version string 10 | * 1 major version 11 | * 2 minor version 12 | * 3 trivial version 13 | * 4 pre-release type (optional: "alpha" or "beta" or undefined for stable releases) 14 | * 5 pre-release version (optional) 15 | * 6 pre-release sub-version (optional) 16 | * 7 canary (optional: "canary", or undefined for stable releases) 17 | * 8 SHA (optional) 18 | */ 19 | const VERSION_INFO = EMBER_VERSION_REGEX.exec(Ember.VERSION); 20 | const isPre111 = parseInt(VERSION_INFO[1], 10) < 2 && parseInt(VERSION_INFO[2], 10) < 12; 21 | 22 | export function initialize() { 23 | if (isPre111) { 24 | let registry = arguments[0]; 25 | let application = arguments[1]; 26 | hideLoadingScreenInstanceInitializer.initialize(registry, application); 27 | } 28 | } 29 | 30 | export default { 31 | name: 'hide-loading-screen', 32 | initialize 33 | }; 34 | -------------------------------------------------------------------------------- /client/app/initializers/history-service.js: -------------------------------------------------------------------------------- 1 | export function initialize(container, application) { 2 | application.inject('route', 'historyService', 'service:history'); 3 | application.inject('component', 'historyService', 'service:history'); 4 | application.inject('controller', 'historyService', 'service:history'); 5 | } 6 | 7 | export default { 8 | name: 'history-service', 9 | initialize: initialize 10 | }; 11 | -------------------------------------------------------------------------------- /client/app/instance-initializers/hide-loading-screen.js: -------------------------------------------------------------------------------- 1 | import config from '../config/environment'; 2 | import Ember from 'ember' 3 | 4 | const userConfig = config['ember-load'] || {}; 5 | 6 | export function initialize() { 7 | const instance = arguments[1] || arguments[0]; 8 | const container = !!arguments[1] ? arguments[0] : instance.container; 9 | 10 | let ApplicationView = container.lookupFactory ? 11 | container.lookupFactory('view:application') : 12 | instance.resolveRegistration('view:application'); 13 | 14 | ApplicationView = ApplicationView.reopen({ 15 | didInsertElement() { 16 | this._super(...arguments); 17 | 18 | var loadingIndicatorClass = userConfig.loadingIndicatorClass || 'ember-load-indicator'; 19 | 20 | Ember.$(`.${loadingIndicatorClass}`).remove(); 21 | } 22 | }); 23 | } 24 | 25 | export default { 26 | name: 'hide-loading-screen-instance', 27 | initialize 28 | }; 29 | -------------------------------------------------------------------------------- /client/app/mixins/scroll-top.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Mixin.create({ 4 | activate: function() { 5 | this._super(); 6 | window.scrollTo(0,0); 7 | } 8 | }); 9 | -------------------------------------------------------------------------------- /client/app/pods/400/controller.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Controller.extend({ 4 | needs: ['application'], 5 | title: "400", 6 | loggedIn: function() { 7 | if (localStorage.getItem('ember_simple_auth:session') === null) 8 | return false; 9 | else 10 | return true; 11 | }.property(), 12 | }); 13 | -------------------------------------------------------------------------------- /client/app/pods/400/template.hbs: -------------------------------------------------------------------------------- 1 |
2 | {{#unless loggedIn}} 3 |

Please log back in...

4 |
5 | Login to continue browsing. 6 |

7 | {{#link-to 'login' tagName='button' class="btn"}}Login{{/link-to}} 8 | {{else}} 9 |

Something went wrong...

10 |
11 | You may need more privileges. If the problem persists, please refresh your browser or contact your administrator. 12 |

13 | {{/unless}} 14 |
15 | -------------------------------------------------------------------------------- /client/app/pods/admin/route.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import EmberAdminRouteAdmin from 'ember-admin/routes/admin'; 3 | 4 | export default EmberAdminRouteAdmin.extend({ 5 | beforeModel: function(transition) { 6 | Ember.$.ajax({ 7 | url: '/isAdmin', 8 | type: 'GET', 9 | //data: null, 10 | contentType: 'application/json' 11 | }).then((response) => { 12 | 13 | },(xhr, status, error) => { 14 | 15 | }); 16 | return this._super(); 17 | } 18 | }); 19 | -------------------------------------------------------------------------------- /client/app/pods/application/template.hbs: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | {{template-header pagename=pagename pages=pages siteheader=siteheader sitename=sitename theme=headertheme}} 5 | {{loading}} 6 |
7 |
8 |
9 | {{outlet}} 10 | {{!-- ember-cli-materialize modal container --}} 11 | {{md-modal-container}} 12 |
13 | 14 |
15 |
16 |
17 | {{template-footer pagename=pagename pages=pages siteheader=siteheader sitename=sitename theme=footertheme class="footer"}} 18 | 19 | -------------------------------------------------------------------------------- /client/app/pods/application/view.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.View.extend({ 4 | classNames: ['app'] 5 | }); 6 | -------------------------------------------------------------------------------- /client/app/pods/company/controller.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Controller.extend({ 4 | years: function() { 5 | return Enumerable.range(new Date().getFullYear()-19, 20).toArray().reverse(); 6 | }.property(), 7 | employees: function(){ 8 | return this.get('model.memberships').sortBy('name'); 9 | }.property('model.memberships.@each.name'), 10 | lookup_employees: function() { 11 | return this.get('model.memberships').sortBy('name').map(function (m) { 12 | return {id : m.get('name'), value: m}; 13 | }); 14 | }.property('model.memberships.@each.name'), 15 | lookup_projects: function() { 16 | return this.get('model.projects').sortBy('name').map(function (m) { 17 | return {id : m.get('name'), value: m}; 18 | }); 19 | }.property('model.memberships.@each.name'), 20 | projects: function(){ 21 | return this.get('model.projects').sortBy('name'); 22 | }.property('model.projects.@each.name'), 23 | selectedMember: Ember.computed.alias('model.selectedMember'), 24 | currentMember: Ember.computed.alias('model.currentMember'), 25 | }); 26 | -------------------------------------------------------------------------------- /client/app/pods/company/detail/controller.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import Company from 'client/pods/company/controller' 3 | export default Company.extend( { 4 | needs : ['application'], 5 | application: Ember.computed.alias("controllers.application"), 6 | shortlisted : function () { 7 | this.get('controllers.company/shortlist').send('refresh'); 8 | }.on('init'), 9 | actions: { 10 | approve: function() { 11 | //Example 12 | var _this = this; 13 | Ember.$.ajax({ 14 | url: '/company/approval/update', 15 | type: 'PUT', 16 | data: JSON.stringify({id: this.get('model.id')}), //TODO 17 | contentType: 'application/json' 18 | }).then((response) => { 19 | _this.Messenger.post({ 20 | message: "Approved", 21 | hideAfter: 10, 22 | hideOnNavigate: true 23 | }); 24 | _this.get('approved').pushObject(this.get('model.id')); 25 | },(xhr, status, error) => { 26 | //Specific Error 27 | }); 28 | 29 | }, 30 | }, 31 | }); 32 | -------------------------------------------------------------------------------- /client/app/pods/company/detail/model.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | export default DS.Model.extend({ 4 | 5 | }); 6 | -------------------------------------------------------------------------------- /client/app/pods/company/detail/route.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Route.extend({ 4 | setupController: function(controller, model) { 5 | var _this = this; 6 | this.store.findRecord('company', model.id).then(function (company) { 7 | controller.set('model', company); 8 | }); 9 | } 10 | }); 11 | -------------------------------------------------------------------------------- /client/app/pods/company/detail/view.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.View.extend({ 4 | 5 | }); 6 | -------------------------------------------------------------------------------- /client/app/pods/company/register/model.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | export default DS.Model.extend({ 4 | 5 | }); 6 | -------------------------------------------------------------------------------- /client/app/pods/company/register/route.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import Company from 'client/pods/company/model' 3 | 4 | export default Ember.Route.extend({ 5 | queryParams: { 6 | cid: { 7 | refreshModel: true, 8 | //replace: true 9 | } 10 | }, 11 | model: function(params, transition) { 12 | var _this = this; 13 | return Ember.$.ajax({ 14 | url: '/company/checkout/' + params.cid, 15 | type: 'GET', 16 | //data: JSON.stringify({id: companyid}), //TODO 17 | contentType: 'application/json' 18 | }).then((response) => { 19 | //this.store.pushPayload('company', {companies: [this.store.normalize('company',response)]}); 20 | this.store.pushPayload('company', this.store.normalize('company',response)); 21 | return response.companies[0].id; 22 | },(xhr, status, error) => { 23 | //Specific Error 24 | }).then((id) => { 25 | return this.store.peekRecord('company',id); 26 | }); 27 | 28 | } 29 | }); 30 | -------------------------------------------------------------------------------- /client/app/pods/company/register/view.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.View.extend({ 4 | 5 | }); 6 | -------------------------------------------------------------------------------- /client/app/pods/company/route.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Route.extend({ 4 | model: function(params, transition) { 5 | if (transition.targetName === "company.index") 6 | this.transitionTo('index'); 7 | } 8 | }); 9 | -------------------------------------------------------------------------------- /client/app/pods/company/template.hbs: -------------------------------------------------------------------------------- 1 | {{outlet}} 2 | -------------------------------------------------------------------------------- /client/app/pods/components/content-card/template.hbs: -------------------------------------------------------------------------------- 1 | {{#md-card title="Card Title" id="basic-card"}} 2 | {{#md-card-content}} 3 | {{{content.html}}} 4 | {{/md-card-content}} 5 | {{#md-card-action}} 6 | {{#link-to content.link}}{{content.linkText}}{{/link-to}} 7 | {{/md-card-action}} 8 | {{/md-card}} 9 | 10 | 11 | -------------------------------------------------------------------------------- /client/app/pods/components/content-raw/template.hbs: -------------------------------------------------------------------------------- 1 | {{{content.description}}} 2 | -------------------------------------------------------------------------------- /client/app/pods/components/file-upload/component.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import EmberUploader from 'ember-uploader'; 3 | 4 | export default EmberUploader.FileField.extend({ 5 | uploadBusy : false, 6 | uploadedUrl : '', 7 | url: '/upload', 8 | filesDidChange: function(files) { 9 | var uploadUrl = this.get('url'); 10 | var _this = this; 11 | _this.set('uploadBusy', true); 12 | var uploader = EmberUploader.S3Uploader.create({ 13 | url: uploadUrl 14 | }); 15 | 16 | uploader.on('didUpload', function(response) { 17 | // S3 will return XML with url 18 | var uploadedUrl = $(response).find('Location')[0].textContent; 19 | uploadedUrl = decodeURIComponent(uploadedUrl); // => http://yourbucket.s3.amazonaws.com/file.png 20 | _this.set('uploadedUrl', uploadedUrl); 21 | _this.set('uploadBusy', false); 22 | }); 23 | 24 | uploader.on('didError', function(jqXHR, textStatus, errorThrown) { 25 | // Handle unsuccessful upload 26 | alert('Failed to upload document'); 27 | _this.set('uploadBusy', false); 28 | }); 29 | 30 | if (!Ember.isEmpty(files)) { 31 | uploader.upload(files[0]); // Uploader will send a sign request then upload to S3 32 | } 33 | } 34 | }); 35 | -------------------------------------------------------------------------------- /client/app/pods/components/file-upload/template.hbs: -------------------------------------------------------------------------------- 1 | {{yield}} 2 | -------------------------------------------------------------------------------- /client/app/pods/components/files-upload/template.hbs: -------------------------------------------------------------------------------- 1 | {{yield}} 2 | -------------------------------------------------------------------------------- /client/app/pods/components/icon-repeater/component.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | 4 | export default Ember.Component.extend({ 5 | repeats: 0, 6 | repeater: [], 7 | _repeater: function () { 8 | var repeater = []; 9 | for(var i = 0; i < this.get('repeats'); i++) 10 | repeater.pushObject(""); 11 | this.set('repeater', repeater); 12 | 13 | }.observes('repeats').on('init') 14 | 15 | }); 16 | -------------------------------------------------------------------------------- /client/app/pods/components/icon-repeater/template.hbs: -------------------------------------------------------------------------------- 1 | {{#each repeater as |x|}} 2 | 3 | {{/each}} 4 | -------------------------------------------------------------------------------- /client/app/pods/components/login-panel/component.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import LoginControllerMixin from 'simple-auth/mixins/login-controller-mixin'; 3 | 4 | export default Ember.Component.extend(LoginControllerMixin, { 5 | authenticator: 'simple-auth-authenticator:oauth2-password-grant', 6 | actions: { 7 | authenticate: function (options) { 8 | var _this = this; 9 | this._super.apply(this,options).then(function (result) { 10 | var token = localStorage.getItem('ember_simple_auth:session'); 11 | 12 | if (typeof token === 'undefined' || !token || token.length < 1) { 13 | console.log("Error logging in. (E_LOGIN1)"); 14 | 15 | } else { 16 | var pt = localStorage.getItem('previousTransition'); 17 | if (pt) { 18 | localStorage.removeItem('previousTransition'); 19 | if (/.*\/400$/.test(pt) || /.*\/login$/ig.test(pt)) 20 | _this.get('container').lookup('controller:application').transitionTo('index'); 21 | else 22 | _this.get('container').lookup('controller:application').transitionTo(pt); 23 | } 24 | else 25 | _this.get('container').lookup('controller:application').transitionTo('index'); 26 | 27 | } 28 | },function (reason) { 29 | debugger; 30 | console.log("Error logging in. (E_LOGIN2)"); 31 | }); 32 | } 33 | } 34 | }); 35 | -------------------------------------------------------------------------------- /client/app/pods/components/login-panel/template.hbs: -------------------------------------------------------------------------------- 1 | {{yield}} 2 | {{! login form; the fields must be named "identification" and "password"; the controller action is "authenticate" }} 3 |
4 |
5 | 6 | {{input id='identification' placeholder='Enter Login' class='form-control' value=identification}} 7 |
8 |
9 | 10 | {{input id='password' placeholder='Enter Password' class='form-control' type='password' value=password}} 11 |
12 | or 13 | {{#link-to 'register'}} Register{{/link-to}} 14 |
15 | {{#if errorMessage}} 16 |
17 | Login failed:{{errorMessage}} 18 |
19 | {{/if}} 20 | -------------------------------------------------------------------------------- /client/app/pods/components/select-serializer/template.hbs: -------------------------------------------------------------------------------- 1 | {{{serialized}}} 2 | -------------------------------------------------------------------------------- /client/app/pods/components/template-footer/component.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Component.extend({ 4 | copyrighttheme: function() { 5 | var originaltheme = this.get('theme') + ' copyright-addendum mdl-mini-footer--social-btn'; 6 | if (!/-[1-9]/.test(originaltheme)) 7 | return originaltheme + " darken-4"; 8 | else if (/-[1-2]/.test(originaltheme)) 9 | return originaltheme.replace(/-[1-2]/,"3"); 10 | else 11 | return originaltheme.replace(/-[3-4]/,"2"); 12 | }.property('theme'), 13 | }); 14 | -------------------------------------------------------------------------------- /client/app/pods/components/template-footer/template.hbs: -------------------------------------------------------------------------------- 1 | 18 | 19 | -------------------------------------------------------------------------------- /client/app/pods/components/template-header/component.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Component.extend({ 4 | _pages: function() { 5 | //admin interface works in separate store so this is never called 6 | }.observes('pages.[]'), 7 | isHome: function() { 8 | var pagename = this.get('pagename'); 9 | if (typeof pagename === 'undefined' || !pagename || pagename.length < 1 || pagename.toLowerCase() === 'home' || pagename.toLowerCase() === 'index') 10 | return true; 11 | return false; 12 | }.property('pagename'), 13 | isAdmin: function() { 14 | return ecms.hasRole('admin'); 15 | }.property(), 16 | isSupplier: function() { 17 | return ecms.hasRole('registrant'); 18 | }.property(), 19 | isClient: function() { 20 | return ecms.hasRole('client'); 21 | }.property(), 22 | 23 | }); 24 | -------------------------------------------------------------------------------- /client/app/pods/index/route.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Route.extend({ 4 | beforeModel: function(transition) { 5 | var home = this.store.peekRecord('page', 'home'); 6 | if (home !== null) { 7 | transition.abort(); 8 | this.transitionTo('page.index', 'home'); 9 | } 10 | } 11 | }); 12 | -------------------------------------------------------------------------------- /client/app/pods/index/template.hbs: -------------------------------------------------------------------------------- 1 | {{outlet}} 2 | 3 | -------------------------------------------------------------------------------- /client/app/pods/login/template.hbs: -------------------------------------------------------------------------------- 1 | {{outlet}} 2 |
3 |

4 | {{login-panel}} 5 |
6 | -------------------------------------------------------------------------------- /client/app/pods/logout/route.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Route.extend({ 4 | beforeModel: function(t) { 5 | this.controllerFor('application').send('invalidateSession') 6 | } 7 | }); 8 | -------------------------------------------------------------------------------- /client/app/pods/membership/model.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | export default DS.Model.extend({ 4 | name : DS.attr('string'), 5 | firstName : DS.attr('string'), 6 | lastName : DS.attr('string'), 7 | email: DS.attr('string'), 8 | description : DS.attr('string'), 9 | isAuthorized : DS.attr('boolean'), 10 | registration : DS.attr('string'), 11 | position : DS.attr('string'), 12 | organizations : DS.attr('array', {defaultValue: []}), 13 | privileges : DS.attr('array', {defaultValue: []}), 14 | projects : DS.hasMany('project',{async:true}), 15 | user: DS.attr('string'), //TODO belongsTo 16 | company: DS.belongsTo('company', {async : true}), 17 | }); 18 | -------------------------------------------------------------------------------- /client/app/pods/membership/route.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Route.extend({ 4 | }); 5 | -------------------------------------------------------------------------------- /client/app/pods/membership/template.hbs: -------------------------------------------------------------------------------- 1 | {{outlet}} 2 | -------------------------------------------------------------------------------- /client/app/pods/page/controller.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Controller.extend({ 4 | 5 | }); 6 | -------------------------------------------------------------------------------- /client/app/pods/page/model.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | export default DS.Model.extend({ 4 | _id: function() { 5 | if (typeof this.get('id') === 'string') 6 | this.set('title', this.get('id')); 7 | }.observes('id').on('init'), 8 | title: DS.attr('string'), 9 | description: DS.attr('string'), 10 | culture: DS.attr('string'), 11 | theme: DS.attr('string'), 12 | metadata: DS.attr('string'), 13 | category: DS.attr('string'), 14 | subcategory: DS.attr('string'), 15 | type: DS.attr('string'), 16 | subtype: DS.attr('string'), 17 | auth: DS.attr('string'), 18 | parent: DS.attr('string'), 19 | position: DS.attr('number'), 20 | hide: DS.attr('boolean'), 21 | publish: DS.attr(), 22 | sections: DS.hasMany('section', {async : true}) 23 | }); 24 | -------------------------------------------------------------------------------- /client/app/pods/page/route.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Route.extend({ 4 | model: function(params, transition) { 5 | var pagename = (params.id.toLowerCase() === 'home') ? "" : params.id; 6 | this.controllerFor('application').set('pagename', pagename); 7 | var page = this.store.peekRecord('page', params.id); 8 | if (!page) 9 | this.transitionTo('/400'); 10 | return this.store.find('section', {page: params.id, hide: false}).then(function (sections) { 11 | sections.map(function (section) { 12 | if (typeof section.get('type') === 'string' && section.get('type') && section.get('type').length > 0 && !/content-/.test(section.get('type'))) 13 | section.set('type', "content-" + section.get('type')); 14 | else 15 | section.set('type', "content-raw"); 16 | }); 17 | return sections; 18 | }); 19 | } 20 | }); 21 | -------------------------------------------------------------------------------- /client/app/pods/page/template.hbs: -------------------------------------------------------------------------------- 1 | {{outlet}} 2 | {{#each model as |section|}} 3 | {{component section.type content=section}} 4 | {{/each}} 5 | -------------------------------------------------------------------------------- /client/app/pods/photo/model.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | export default DS.Model.extend({ 4 | url: DS.attr('string'), 5 | _url: function() { 6 | if (typeof this.get('url') === 'string') { 7 | this.set('thumb', this.get('url').replace(/(^.+\/\/)([a-zA-Z0-9]+)(\..*\/)(.*)/, '$1$2resized$3resized-$4')); 8 | } 9 | }.observes('url'), 10 | thumb: DS.attr('string'), 11 | title: DS.attr('string'), 12 | description: DS.attr('string'), 13 | culture: DS.attr('string'), 14 | category: DS.attr('string'), 15 | tags: DS.attr('string'), 16 | auth: DS.attr('string'), 17 | reference: DS.attr('string') 18 | }); 19 | -------------------------------------------------------------------------------- /client/app/pods/photo/route.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Route.extend({ 4 | }); 5 | -------------------------------------------------------------------------------- /client/app/pods/photo/template.hbs: -------------------------------------------------------------------------------- 1 | {{outlet}} 2 | -------------------------------------------------------------------------------- /client/app/pods/protected/route.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Route.extend({ 4 | }); 5 | -------------------------------------------------------------------------------- /client/app/pods/protected/template.hbs: -------------------------------------------------------------------------------- 1 | {{outlet}} 2 | -------------------------------------------------------------------------------- /client/app/pods/register/route.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Route.extend({ 4 | model: function() { 5 | return Ember.Object.create(); 6 | }, 7 | actions: { 8 | createUser: function(model) { 9 | debugger; 10 | var _this = this; 11 | Ember.$.ajax({ 12 | url: '/signup', 13 | type: 'POST', 14 | data: JSON.stringify({ 15 | action: 'register', 16 | user: { 17 | password: model.get('password'), 18 | email: model.get('email'), 19 | username: model.get('username'), 20 | } 21 | }), 22 | contentType: 'application/json' 23 | }).then(function(/*response*/) { 24 | _this.transitionTo('login'); 25 | 26 | }, function(xhr, status, error) { 27 | _this.set('errorMessage', error); 28 | }); 29 | 30 | } 31 | } 32 | }); 33 | -------------------------------------------------------------------------------- /client/app/pods/register/template.hbs: -------------------------------------------------------------------------------- 1 | {{outlet}} 2 |

User Registration

3 | 4 |
5 |
6 |
7 | 8 | {{input id='email' placeholder='Enter your email' type='email' class='form-control' value=model.email}} 9 |
10 |
11 | 12 | {{input id='password' placeholder='Enter password' class='form-control' type='password' value=model.password}} 13 |
14 | 15 |
16 |
17 | {{#if model.errorMessage}} 18 | Registration failed:{{model.errorMessage}} 19 | {{/if}} 20 |
21 |
22 | -------------------------------------------------------------------------------- /client/app/pods/section/model.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | export default DS.Model.extend({ 4 | page: DS.belongsTo('page', {async: true}), 5 | title: DS.attr('string'), 6 | description: DS.attr('string'), 7 | culture: DS.attr('string'), 8 | category: DS.attr('string'), 9 | subcategory: DS.attr('string'), 10 | metadata: DS.attr('string'), 11 | type: DS.attr('string'), 12 | subtype: DS.attr('string'), 13 | auth: DS.attr('string'), 14 | position: DS.attr('number'), 15 | hide: DS.attr('boolean'), 16 | publish: DS.attr(), 17 | }); 18 | -------------------------------------------------------------------------------- /client/app/pods/section/route.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Route.extend({ 4 | }); 5 | -------------------------------------------------------------------------------- /client/app/pods/section/template.hbs: -------------------------------------------------------------------------------- 1 | {{outlet}} 2 | -------------------------------------------------------------------------------- /client/app/pods/test/model.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | export default DS.Model.extend({ 4 | test2: DS.attr('number') 5 | }); 6 | -------------------------------------------------------------------------------- /client/app/pods/test/route.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Route.extend({ 4 | }); 5 | -------------------------------------------------------------------------------- /client/app/pods/test2/route.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Route.extend({ 4 | }); 5 | -------------------------------------------------------------------------------- /client/app/pods/test2/template.hbs: -------------------------------------------------------------------------------- 1 | {{outlet}} 2 | test2 3 | -------------------------------------------------------------------------------- /client/app/pods/translation/model.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | export default DS.Model.extend({ 4 | type: DS.attr('string'), 5 | tid: DS.attr('string'), 6 | culture: DS.attr('string'), 7 | title: DS.attr('string'), 8 | description: DS.attr('string') 9 | }); 10 | -------------------------------------------------------------------------------- /client/app/pods/translation/route.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Route.extend({ 4 | }); 5 | -------------------------------------------------------------------------------- /client/app/pods/translation/template.hbs: -------------------------------------------------------------------------------- 1 | {{outlet}} 2 | -------------------------------------------------------------------------------- /client/app/pods/user/model.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | export default DS.Model.extend({ 4 | name: DS.attr('string'), 5 | description: DS.attr('string'), 6 | firstName: DS.attr('string'), 7 | lastName: DS.attr('string'), 8 | email: DS.attr('string'), 9 | isAuthorized: DS.attr('string'), 10 | position: DS.attr('string'), 11 | disciplines: DS.attr('string'), 12 | organizations: DS.attr('string'), 13 | registration: DS.attr('string'), 14 | provinces: DS.attr('string'), 15 | username: DS.attr('string'), 16 | password: DS.attr('string'), 17 | email: DS.attr('string'), 18 | }); 19 | -------------------------------------------------------------------------------- /client/app/pods/user/route.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import AuthenticatedRouteMixin from 'simple-auth/mixins/authenticated-route-mixin'; 3 | 4 | export default Ember.Route.extend(AuthenticatedRouteMixin, { 5 | model: function () { 6 | return this.store.find('user'); 7 | } 8 | }); 9 | -------------------------------------------------------------------------------- /client/app/pods/user/template.hbs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/app/pods/user/template.hbs -------------------------------------------------------------------------------- /client/app/router.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import config from './config/environment'; 3 | import adminRouter from 'ember-admin/router'; 4 | 5 | var Router = Ember.Router.extend({ 6 | location: config.locationType 7 | }); 8 | 9 | Router.map(function() { 10 | adminRouter(this); 11 | 12 | //App 13 | this.route('protected'); 14 | 15 | this.route('company', function() { 16 | this.route('register'); 17 | this.route('detail', {path : "detail/:id"}); 18 | }); 19 | 20 | //Security 21 | this.route("login"); 22 | this.route("logout"); 23 | this.route("register"); 24 | 25 | 26 | //CMS 27 | this.route('page', { path : "page/:id"}, function() { 28 | 29 | }); 30 | this.route('section'); 31 | this.route('translation'); 32 | this.route('photo'); 33 | 34 | //Other 35 | this.route('400', { path: '/*wildcard'}); 36 | 37 | this.route('membership'); 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | }); 47 | 48 | 49 | 50 | export default Router; 51 | -------------------------------------------------------------------------------- /client/app/serializers/application.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | export default DS.RESTSerializer.extend(); -------------------------------------------------------------------------------- /client/app/serializers/company.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, { 4 | attrs: { 5 | memberships: { deserialize: 'links', serialize: false }, //save employees with company 6 | awards: { deserialize: 'links', serialize: false }, 7 | projects: { deserialize: 'links', serialize: false }, //ids, false, records, links 8 | } 9 | }); 10 | -------------------------------------------------------------------------------- /client/app/serializers/test.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, { 4 | attrs: { 5 | memberships: { deserialize: 'links', serialize: false }, //save employees with company 6 | awards: { deserialize: 'links', serialize: false }, 7 | projects: { deserialize: 'links', serialize: false }, //ids, false, records, links 8 | } 9 | }); 10 | -------------------------------------------------------------------------------- /client/app/services/admin.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import EmberAdminServiceAdmin from 'ember-admin/services/admin'; 3 | 4 | export default EmberAdminServiceAdmin.extend({ 5 | namespace: '', 6 | includedModels: ['page', 'photo'], //make null to add all 7 | // excludedModels: null 8 | excludedColumns: { 9 | 'page': ['description', 'title', 'parent','hide','publish'], 10 | 'photo': ['description', 'url', 'thumb'], 11 | 'section': ['description','hide','publish'], 12 | } 13 | }); 14 | -------------------------------------------------------------------------------- /client/app/services/history.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | const { observer, computed } = Ember; 4 | 5 | export default Ember.Service.extend({ 6 | max: 20, 7 | cursor: 0, 8 | log: [], 9 | // TODO: this observer is dubious 10 | enforceMaxLength: observer('log.length', 'max', function () { 11 | let log = this.get('log'); 12 | if ( log.length > this.get('max')) { 13 | log.shift(); 14 | } 15 | }), 16 | currentRoute: computed('log.[]', function () { 17 | return this.get('log')[this.get('cursor')-1]; 18 | }), 19 | back() { 20 | if (!this.get('cursorAtStart')) { 21 | this.decrementProperty('cursor'); 22 | this.container.lookup('router:main').router.replaceWith(this.get('log')[this.get('cursor')-1]); 23 | } 24 | }, 25 | forward() { 26 | if (!this.get('cursorAtEnd')) { 27 | this.incrementProperty('cursor'); 28 | this.container.lookup('router:main').router.replaceWith(this.get('log')[this.get('cursor')-1]); 29 | } 30 | }, 31 | go(index) { 32 | this.container.lookup('router:main').router.replaceWith(this.get('log')[index-1]); 33 | }, 34 | cursorAtEnd: computed('log.length', 'cursor', function () { 35 | return this.get('log').length === this.get('cursor'); 36 | }), 37 | cursorAtStart: computed('log.[]', 'cursor', function () { 38 | return this.get('cursor') === 1; 39 | }) 40 | 41 | }); 42 | -------------------------------------------------------------------------------- /client/app/styles/_functions.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @function strip-units($number) { 18 | @return $number / ($number * 0 + 1); 19 | } 20 | -------------------------------------------------------------------------------- /client/app/styles/animation/_animation.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../variables"; 18 | 19 | 20 | .mdl-animation--default { 21 | transition-timing-function: $animation-curve-default; 22 | } 23 | 24 | .mdl-animation--fast-out-slow-in { 25 | transition-timing-function: $animation-curve-fast-out-slow-in; 26 | } 27 | 28 | .mdl-animation--linear-out-slow-in { 29 | transition-timing-function: $animation-curve-linear-out-slow-in; 30 | } 31 | 32 | .mdl-animation--fast-out-linear-in { 33 | transition-timing-function: $animation-curve-fast-out-linear-in; 34 | } 35 | -------------------------------------------------------------------------------- /client/app/styles/animation/demo.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
Click me to animate
4 |
5 |
6 |
7 |
8 | -------------------------------------------------------------------------------- /client/app/styles/badge/snippets/badge-on-icon-icon-demo.html: -------------------------------------------------------------------------------- 1 | 9 | {% include "badge-on-icon-icon.html" %} 10 | -------------------------------------------------------------------------------- /client/app/styles/badge/snippets/badge-on-icon-icon.html: -------------------------------------------------------------------------------- 1 |
account_box
2 | -------------------------------------------------------------------------------- /client/app/styles/badge/snippets/badge-on-icon-text-demo.html: -------------------------------------------------------------------------------- 1 | 9 | {% include "badge-on-icon-text.html" %} 10 | -------------------------------------------------------------------------------- /client/app/styles/badge/snippets/badge-on-icon-text.html: -------------------------------------------------------------------------------- 1 | 2 |
account_box
3 | -------------------------------------------------------------------------------- /client/app/styles/badge/snippets/badge-on-text-icon-demo.html: -------------------------------------------------------------------------------- 1 | 6 | {% include "badge-on-text-icon.html" %} 7 | -------------------------------------------------------------------------------- /client/app/styles/badge/snippets/badge-on-text-icon.html: -------------------------------------------------------------------------------- 1 | 2 | Mood 3 | -------------------------------------------------------------------------------- /client/app/styles/badge/snippets/badge-on-text-text-demo.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | {% include "badge-on-text-text.html" %} 8 | -------------------------------------------------------------------------------- /client/app/styles/badge/snippets/badge-on-text-text.html: -------------------------------------------------------------------------------- 1 | 2 | Inbox 3 | -------------------------------------------------------------------------------- /client/app/styles/button/snippets/fab-colored-ripple.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /client/app/styles/button/snippets/fab-colored.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /client/app/styles/button/snippets/fab-disabled.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /client/app/styles/button/snippets/fab-mini-colored.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /client/app/styles/button/snippets/fab-mini.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /client/app/styles/button/snippets/fab-ripple.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /client/app/styles/button/snippets/fab.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /client/app/styles/button/snippets/flat-accent.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /client/app/styles/button/snippets/flat-disabled.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /client/app/styles/button/snippets/flat-primary.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /client/app/styles/button/snippets/flat-ripple.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /client/app/styles/button/snippets/flat.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /client/app/styles/button/snippets/icon-colored.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /client/app/styles/button/snippets/icon.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /client/app/styles/button/snippets/raised-accent.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /client/app/styles/button/snippets/raised-colored.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /client/app/styles/button/snippets/raised-disabled.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /client/app/styles/button/snippets/raised-ripple-accent.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /client/app/styles/button/snippets/raised-ripple.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /client/app/styles/button/snippets/raised.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /client/app/styles/card/snippets/event.html: -------------------------------------------------------------------------------- 1 | 2 | 31 | 32 |
33 |
34 |

35 | Featured event:
36 | May 24, 2016
37 | 7-11pm 38 |

39 |
40 |
41 | 42 | Add to Calendar 43 | 44 |
45 | event 46 |
47 |
48 | -------------------------------------------------------------------------------- /client/app/styles/card/snippets/image.html: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 |
21 |
22 |
23 | Image.jpg 24 |
25 |
26 | -------------------------------------------------------------------------------- /client/app/styles/card/snippets/square.html: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 |
15 |
16 |

Update

17 |
18 |
19 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. 20 | Aenan convallis. 21 |
22 |
23 | 24 | View Updates 25 | 26 |
27 |
28 | -------------------------------------------------------------------------------- /client/app/styles/card/snippets/wide.html: -------------------------------------------------------------------------------- 1 | 2 | 15 | 16 |
17 |
18 |

Welcome

19 |
20 |
21 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. 22 | Mauris sagittis pellentesque lacus eleifend lacinia... 23 |
24 |
25 | 26 | Get Started 27 | 28 |
29 |
30 | 33 |
34 |
35 | -------------------------------------------------------------------------------- /client/app/styles/checkbox/snippets/check-off.html: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /client/app/styles/checkbox/snippets/check-on.html: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /client/app/styles/data-table/snippets/data-table.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |
MaterialQuantityUnit price
Acrylic (Transparent)25$2.90
Plywood (Birch)50$1.25
Laminate (Gold on Blue)10$2.35
27 | -------------------------------------------------------------------------------- /client/app/styles/demos.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | .demo-page { 18 | width: 100%; 19 | height: auto; 20 | 21 | margin: 0; 22 | padding: 0; 23 | 24 | padding: 24px; 25 | box-sizing: border-box; 26 | } 27 | 28 | .demo-preview-block { 29 | padding: 20px; 30 | padding-bottom: 0; 31 | margin-bottom: 0; 32 | box-sizing: border-box; 33 | width: 100%; 34 | } 35 | 36 | .demo-code { 37 | width: 100%; 38 | box-sizing: border-box; 39 | } 40 | -------------------------------------------------------------------------------- /client/app/styles/footer/snippets/mini-footer.html: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /client/app/styles/grid/snippets/codepen-grid.css: -------------------------------------------------------------------------------- 1 | .mdl-cell { 2 | box-sizing: border-box; 3 | background-color: #BDBDBD; 4 | height: 200px; 5 | padding-left: 8px; 6 | padding-top: 4px; 7 | color: white; 8 | } 9 | .mdl-grid:first-of-type .mdl-cell { 10 | height: 50px; 11 | } 12 | -------------------------------------------------------------------------------- /client/app/styles/grid/snippets/grid-demo.html: -------------------------------------------------------------------------------- 1 | 14 | 15 | {% include "grid.html" %} 16 | -------------------------------------------------------------------------------- /client/app/styles/grid/snippets/grid.html: -------------------------------------------------------------------------------- 1 |
2 |
1
3 |
1
4 |
1
5 |
1
6 |
1
7 |
1
8 |
1
9 |
1
10 |
1
11 |
1
12 |
1
13 |
1
14 |
15 |
16 |
4
17 |
4
18 |
4
19 |
20 |
21 |
6
22 |
4
23 |
2
24 |
25 |
26 |
6 (8 tablet)
27 |
4 (6 tablet)
28 |
2 (4 phone)
29 |
30 | -------------------------------------------------------------------------------- /client/app/styles/icon-toggle/snippets/icon-off.html: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /client/app/styles/icon-toggle/snippets/icon-on.html: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /client/app/styles/images/buffer.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /client/app/styles/images/tick-mask.svg: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | 16 | 17 | 18 | 21 | 22 | 23 | 30 | 31 | -------------------------------------------------------------------------------- /client/app/styles/images/tick.svg: -------------------------------------------------------------------------------- 1 | 2 | 11 | 15 | 16 | -------------------------------------------------------------------------------- /client/app/styles/layout/snippets/fixed-drawer-demo.html: -------------------------------------------------------------------------------- 1 | 14 | 15 | {% include "fixed-drawer.html" %} 16 | -------------------------------------------------------------------------------- /client/app/styles/layout/snippets/fixed-drawer.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | Title 5 | 11 |
12 |
13 |
14 |
15 |
16 | -------------------------------------------------------------------------------- /client/app/styles/layout/snippets/fixed-header-demo.html: -------------------------------------------------------------------------------- 1 | 14 | 15 | {% include "fixed-header.html" %} 16 | -------------------------------------------------------------------------------- /client/app/styles/layout/snippets/fixed-header-drawer-demo.html: -------------------------------------------------------------------------------- 1 | 14 | 15 | {% include "fixed-header-drawer.html" %} 16 | -------------------------------------------------------------------------------- /client/app/styles/layout/snippets/fixed-header.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 | 6 | Title 7 | 8 |
9 | 10 | 16 |
17 |
18 |
19 | Title 20 | 26 |
27 |
28 |
29 |
30 |
31 | -------------------------------------------------------------------------------- /client/app/styles/layout/snippets/fixed-tabs-demo.html: -------------------------------------------------------------------------------- 1 | 14 | 15 | {% include "fixed-tabs.html" %} 16 | -------------------------------------------------------------------------------- /client/app/styles/layout/snippets/fixed-tabs.html: -------------------------------------------------------------------------------- 1 | 2 |
4 |
5 |
6 | 7 | Title 8 |
9 | 10 |
11 | Tab 1 12 | Tab 2 13 | Tab 3 14 |
15 |
16 |
17 | Title 18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | -------------------------------------------------------------------------------- /client/app/styles/layout/snippets/scrollable-tabs-demo.html: -------------------------------------------------------------------------------- 1 | 14 | 15 | {% include "scrollable-tabs.html" %} 16 | -------------------------------------------------------------------------------- /client/app/styles/layout/snippets/scrolling-header-demo.html: -------------------------------------------------------------------------------- 1 | 15 | 16 | {% include "scrolling-header.html" %} 17 | -------------------------------------------------------------------------------- /client/app/styles/layout/snippets/scrolling-header.html: -------------------------------------------------------------------------------- 1 | 3 |
4 |
5 |
6 | 7 | Title 8 | 9 |
10 | 11 | 17 |
18 |
19 |
20 | Title 21 | 27 |
28 |
29 |
30 |
31 |
32 | -------------------------------------------------------------------------------- /client/app/styles/layout/snippets/transparent-demo.html: -------------------------------------------------------------------------------- 1 | 11 | 12 | {% include "transparent.html" %} 13 | -------------------------------------------------------------------------------- /client/app/styles/layout/snippets/waterfall-header-demo.html: -------------------------------------------------------------------------------- 1 | 15 | 16 | {% include "waterfall-header.html" %} 17 | -------------------------------------------------------------------------------- /client/app/styles/list/snippets/icon.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |

Icon List

4 | 24 |
25 | -------------------------------------------------------------------------------- /client/app/styles/list/snippets/list-item.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |

List Item

4 | 21 |
22 | -------------------------------------------------------------------------------- /client/app/styles/material-design-lite-grid.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /* Material Design Lite Grid*/ 18 | 19 | @import "variables"; 20 | @import "mixins"; 21 | @import "grid/grid"; -------------------------------------------------------------------------------- /client/app/styles/menu/snippets/codepen-lower-buttons.css: -------------------------------------------------------------------------------- 1 | #demo-menu-lower-left { 2 | margin-left: 40%; 3 | } 4 | -------------------------------------------------------------------------------- /client/app/styles/menu/snippets/codepen-top-buttons.css: -------------------------------------------------------------------------------- 1 | #demo-menu-top-left { 2 | margin-left: 40%; 3 | } 4 | 5 | #demo-menu-top-left, 6 | #demo-menu-top-right { 7 | margin-top: 250px; 8 | } 9 | -------------------------------------------------------------------------------- /client/app/styles/menu/snippets/lower-left-demo.html: -------------------------------------------------------------------------------- 1 | 19 | 20 |
21 |
22 | {% include "lower-left.html" %} 23 |
24 |
25 |
26 | -------------------------------------------------------------------------------- /client/app/styles/menu/snippets/lower-left.html: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 14 | -------------------------------------------------------------------------------- /client/app/styles/menu/snippets/lower-right-demo.html: -------------------------------------------------------------------------------- 1 | 26 | 27 |
28 |
29 |
30 | {% include "lower-right.html" %} 31 |
32 |
33 |
34 |
35 | -------------------------------------------------------------------------------- /client/app/styles/menu/snippets/lower-right.html: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 14 | -------------------------------------------------------------------------------- /client/app/styles/menu/snippets/top-left-demo.html: -------------------------------------------------------------------------------- 1 | 19 | 20 |
21 |
22 |
23 | {% include "top-left.html" %} 24 |
25 |
26 | -------------------------------------------------------------------------------- /client/app/styles/menu/snippets/top-left.html: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 14 | -------------------------------------------------------------------------------- /client/app/styles/menu/snippets/top-right-demo.html: -------------------------------------------------------------------------------- 1 | 26 | 27 |
28 |
29 |
30 |
31 | {% include "top-right.html" %} 32 |
33 |
34 |
35 | -------------------------------------------------------------------------------- /client/app/styles/menu/snippets/top-right.html: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 14 | -------------------------------------------------------------------------------- /client/app/styles/progress/snippets/progress-buffering-demo.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | {% include "progress-buffering.html" %} 9 | -------------------------------------------------------------------------------- /client/app/styles/progress/snippets/progress-buffering.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 9 | -------------------------------------------------------------------------------- /client/app/styles/progress/snippets/progress-default-demo.html: -------------------------------------------------------------------------------- 1 | 7 | {% include "progress-default.html" %} 8 | -------------------------------------------------------------------------------- /client/app/styles/progress/snippets/progress-default.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 8 | -------------------------------------------------------------------------------- /client/app/styles/progress/snippets/progress-indeterminate-demo.html: -------------------------------------------------------------------------------- 1 | 7 | {% include "progress-indeterminate.html" %} 8 | -------------------------------------------------------------------------------- /client/app/styles/progress/snippets/progress-indeterminate.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | -------------------------------------------------------------------------------- /client/app/styles/radio/snippets/radio-off.html: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /client/app/styles/radio/snippets/radio-on.html: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /client/app/styles/resets/_mobile.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | /* Remove the unwanted box around FAB buttons */ 19 | /* More info: http://goo.gl/IPwKi */ 20 | a, .mdl-accordion, .mdl-button, .mdl-card, .mdl-checkbox, .mdl-dropdown-menu, 21 | .mdl-icon-toggle, .mdl-item, .mdl-radio, .mdl-slider, .mdl-switch, .mdl-tabs__tab { 22 | 23 | -webkit-tap-highlight-color: transparent; 24 | -webkit-tap-highlight-color: rgba(255, 255, 255, 0); 25 | } 26 | -------------------------------------------------------------------------------- /client/app/styles/shadow/_shadow.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../variables"; 18 | @import "../mixins"; 19 | 20 | .mdl-shadow--2dp { 21 | @include shadow-2dp(); 22 | } 23 | 24 | .mdl-shadow--3dp { 25 | @include shadow-3dp(); 26 | } 27 | 28 | .mdl-shadow--4dp { 29 | @include shadow-4dp(); 30 | } 31 | 32 | .mdl-shadow--6dp { 33 | @include shadow-6dp(); 34 | } 35 | 36 | .mdl-shadow--8dp { 37 | @include shadow-8dp(); 38 | } 39 | 40 | .mdl-shadow--16dp { 41 | @include shadow-16dp(); 42 | } 43 | 44 | .mdl-shadow--24dp { 45 | @include shadow-24dp(); 46 | } 47 | -------------------------------------------------------------------------------- /client/app/styles/shadow/demo.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | .demo-page--shadow .demo-preview-block { 18 | height: 100px; 19 | } 20 | 21 | .demo-shadow-card { 22 | background-color: #fff; 23 | border-radius: 2px; 24 | display: block; 25 | height: 72px; 26 | margin-bottom: 20px; 27 | margin-right: 32px; 28 | padding: 10px; 29 | text-align: center; 30 | float: left; 31 | color: #9E9E9E; 32 | display: flex; 33 | align-items: center; 34 | justify-content: center; 35 | transition-property: opacity, transform; 36 | width: 72px; 37 | } 38 | 39 | @media screen and (max-width: 360px ) { 40 | .demo-shadow-card { 41 | width: 27px; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /client/app/styles/shadow/demo.html: -------------------------------------------------------------------------------- 1 |
2 |
2dp
3 |
3dp
4 |
4dp
5 |
6dp
6 |
8dp
7 |
16dp
8 |
9 | -------------------------------------------------------------------------------- /client/app/styles/slider/snippets/demo.html: -------------------------------------------------------------------------------- 1 |
2 |

3 | 5 |

6 |

7 | 9 |

10 |
11 | -------------------------------------------------------------------------------- /client/app/styles/slider/snippets/slider-default-demo.html: -------------------------------------------------------------------------------- 1 | 7 | {% include "slider-default.html" %} 8 | -------------------------------------------------------------------------------- /client/app/styles/slider/snippets/slider-default.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | -------------------------------------------------------------------------------- /client/app/styles/slider/snippets/slider-starting-value-demo.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | {% include "slider-starting-value.html" %} 9 | -------------------------------------------------------------------------------- /client/app/styles/slider/snippets/slider-starting-value.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | -------------------------------------------------------------------------------- /client/app/styles/snackbar/snippets/snackbar.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 26 | -------------------------------------------------------------------------------- /client/app/styles/snackbar/snippets/toast.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 16 | -------------------------------------------------------------------------------- /client/app/styles/spinner/snippets/spinner-default.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | -------------------------------------------------------------------------------- /client/app/styles/spinner/snippets/spinner-single-color.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | -------------------------------------------------------------------------------- /client/app/styles/switch/snippets/switch-off.html: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /client/app/styles/switch/snippets/switch-on.html: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /client/app/styles/tabs/snippets/tabs.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | Starks 4 | Lannisters 5 | Targaryens 6 |
7 | 8 |
9 | 18 |
19 |
20 | 26 |
27 |
28 | 32 |
33 |
34 | -------------------------------------------------------------------------------- /client/app/styles/template.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /* Material Design Lite */ 18 | 19 | $styleguide-generate-template: true; 20 | 21 | @import "styleguide"; 22 | -------------------------------------------------------------------------------- /client/app/styles/textfield/snippets/textfield-expanding-demo.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | {% include "textfield-expanding.html" %} 8 | -------------------------------------------------------------------------------- /client/app/styles/textfield/snippets/textfield-expanding.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 7 |
8 | 9 | 10 |
11 |
12 |
13 | -------------------------------------------------------------------------------- /client/app/styles/textfield/snippets/textfield-floating-numeric-demo.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | {% include "textfield-floating-numeric.html" %} 8 | -------------------------------------------------------------------------------- /client/app/styles/textfield/snippets/textfield-floating-numeric.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 5 | 6 | Input is not a number! 7 |
8 |
9 | -------------------------------------------------------------------------------- /client/app/styles/textfield/snippets/textfield-floating-text-demo.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | {% include "textfield-floating-text.html" %} 8 | -------------------------------------------------------------------------------- /client/app/styles/textfield/snippets/textfield-floating-text.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |
5 | 6 | 7 |
8 |
9 | -------------------------------------------------------------------------------- /client/app/styles/textfield/snippets/textfield-multi-line-demo.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | {% include "textfield-multi-line.html" %} 8 | -------------------------------------------------------------------------------- /client/app/styles/textfield/snippets/textfield-multi-line.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 5 | 6 |
7 |
8 | -------------------------------------------------------------------------------- /client/app/styles/textfield/snippets/textfield-numeric-demo.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | {% include "textfield-numeric.html" %} 8 | -------------------------------------------------------------------------------- /client/app/styles/textfield/snippets/textfield-numeric.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 5 | 6 | Input is not a number! 7 |
8 |
9 | -------------------------------------------------------------------------------- /client/app/styles/textfield/snippets/textfield-text-demo.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | {% include "textfield-text.html" %} 8 | -------------------------------------------------------------------------------- /client/app/styles/textfield/snippets/textfield-text.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 5 | 6 |
7 |
8 | -------------------------------------------------------------------------------- /client/app/styles/tooltip/snippets/tooltip-large.html: -------------------------------------------------------------------------------- 1 | 2 |
print
3 |
4 | Print 5 |
6 | -------------------------------------------------------------------------------- /client/app/styles/tooltip/snippets/tooltip-multiline.html: -------------------------------------------------------------------------------- 1 | 2 |
share
3 |
4 | Share your content
via social media 5 |
6 | -------------------------------------------------------------------------------- /client/app/styles/tooltip/snippets/tooltip-rich.html: -------------------------------------------------------------------------------- 1 | 2 |
cloud_upload
3 |
4 | Upload file.zip 5 |
6 | -------------------------------------------------------------------------------- /client/app/styles/tooltip/snippets/tooltip-simple.html: -------------------------------------------------------------------------------- 1 | 2 |
add
3 |
4 | Follow 5 |
6 | -------------------------------------------------------------------------------- /client/app/templates/admin.hbs: -------------------------------------------------------------------------------- 1 |
2 | {{#each filteredModels as |name|}} 3 | {{link-to name 'model-records' name class="btn admin-link indigo"}} 4 | {{/each}} 5 | {{outlet}} 6 |
7 | -------------------------------------------------------------------------------- /client/app/templates/admin/index/page.hbs: -------------------------------------------------------------------------------- 1 |
2 |

Pages

3 | {{input value=filter placeholder="Filter"}} 4 | {{#unless hideCreate}} 5 | {{#if relationshipGiven}} 6 | {{link-to 'Create' 'model-records.new' recordType (query-params relationship-name=relationshipName relationship-id=relationshipId)}} 7 | {{else}} 8 | {{link-to 'Create' 'model-records.new' recordType}} 9 | {{/if}} 10 | {{/unless}} 11 | 12 | 13 | 14 | 15 | {{#each filteredColumns as |column|}} 16 | 17 | {{/each}} 18 | 19 | 20 | 21 | 22 | 23 | {{#each filteredRecords as |record|}} 24 | 25 | {{#each filteredColumns as |column|}} 26 | 31 | {{/each}} 32 | 33 | 34 | 35 | {{/each}} 36 | 37 |
{{column}}hiddenpublish
27 | {{#link-to 'model-records.edit' recordType record}} 28 | {{property-print record=record column=column}} 29 | {{/link-to}} 30 | {{md-check checked=record.hide disabled=true}}{{moment-from-now record.publish}}
38 | {{#unless records}} 39 | No records! 40 | {{/unless}} 41 |
42 | -------------------------------------------------------------------------------- /client/app/templates/admin/index/photo.hbs: -------------------------------------------------------------------------------- 1 |
2 |

Photos

3 | {{input value=filter placeholder="Filter"}} 4 | {{#unless hideCreate}} 5 | {{#if relationshipGiven}} 6 | {{link-to 'Create' 'model-records.new' recordType (query-params relationship-name=relationshipName relationship-id=relationshipId)}} 7 | {{else}} 8 | {{link-to 'Create' 'model-records.new' recordType}} 9 | {{/if}} 10 | {{/unless}} 11 | 12 | 13 | 14 | 15 | 16 | {{#each filteredColumns as |column|}} 17 | 18 | {{/each}} 19 | 20 | 21 | 22 | {{#each filteredRecords as |record|}} 23 | 24 | 25 | {{#each filteredColumns as |column|}} 26 | 31 | {{/each}} 32 | 33 | {{/each}} 34 | 35 |
url{{column}}
27 | {{#link-to 'model-records.edit' recordType record}} 28 | {{property-print record=record column=column}} 29 | {{/link-to}} 30 |
36 | {{#unless records}} 37 | No records! 38 | {{/unless}} 39 |
40 | -------------------------------------------------------------------------------- /client/app/templates/admin/index/section.hbs: -------------------------------------------------------------------------------- 1 |
2 |

Sections

3 | {{input value=filter placeholder="Filter"}} 4 | {{#unless hideCreate}} 5 | {{#if relationshipGiven}} 6 | {{link-to 'Create' 'model-records.new' recordType (query-params relationship-name=relationshipName relationship-id=relationshipId)}} 7 | {{else}} 8 | {{link-to 'Create' 'model-records.new' recordType}} 9 | {{/if}} 10 | {{/unless}} 11 | 12 | 13 | 14 | 15 | {{#each filteredColumns as |column|}} 16 | 17 | {{/each}} 18 | 19 | 20 | 21 | 22 | 23 | {{#each filteredRecords as |record|}} 24 | 25 | {{#each filteredColumns as |column|}} 26 | 31 | {{/each}} 32 | 33 | 34 | 35 | {{/each}} 36 | 37 |
{{column}}hiddenpublish
27 | {{#link-to 'model-records.edit' recordType record}} 28 | {{property-print record=record column=column}} 29 | {{/link-to}} 30 | {{md-check checked=record.hide disabled=true}}{{moment-from-now record.publish}}
38 | {{#unless records}} 39 | No records! 40 | {{/unless}} 41 |
42 | -------------------------------------------------------------------------------- /client/app/templates/admin/new/page.hbs: -------------------------------------------------------------------------------- 1 |
2 |

Create Page

3 | 4 |
5 |
6 | 10 |
11 | {{#each filteredColumns as |column|}} 12 |
13 | 17 |
18 | {{/each}} 19 |
20 | 23 |
24 |
25 | 28 |
29 | 34 |

35 | {{async-button action="save" default="Save" pending="Saving..." fulfilled="Saved" rejected="Error" class="save"}} 36 | 37 |
38 |
39 | -------------------------------------------------------------------------------- /client/app/templates/admin/new/photo.hbs: -------------------------------------------------------------------------------- 1 |
2 |

Create Photo

3 | 4 |
5 |
6 | 10 |
11 | {{file-upload uploadedUrl=model.url uploadBusy=uploadBusy}} 12 | {{#each filteredColumns as |column|}} 13 |
14 | 18 |
19 | {{/each}} 20 |
21 | 25 |
26 | {{async-button action="save" default="Save" pending="Saving..." fulfilled="Saved" rejected="Error" class="save"}} 27 | 28 |
29 |
30 | -------------------------------------------------------------------------------- /client/app/templates/admin/new/section.hbs: -------------------------------------------------------------------------------- 1 |
2 |

Create Section

3 | 4 |
5 | {{#each filteredColumns as |column|}} 6 |
7 | 11 |
12 | {{/each}} 13 |
14 | 18 |
19 |
20 | 23 |
24 |
25 | 28 |
29 | 34 |

35 | {{async-button action="save" default="Save" pending="Saving..." fulfilled="Saved" rejected="Error" class="save"}} 36 | 37 |
38 |
39 | -------------------------------------------------------------------------------- /client/app/templates/loading.hbs: -------------------------------------------------------------------------------- 1 | {{md-loader}} 2 | 3 | -------------------------------------------------------------------------------- /client/app/transforms/array.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import DS from 'ember-data'; 3 | 4 | export default DS.Transform.extend({ 5 | deserialize(serialized) { 6 | return (Ember.typeOf(serialized) === "array") ? serialized : []; 7 | }, 8 | 9 | serialize(deserialized) { 10 | var type = Ember.typeOf(deserialized); 11 | if (type === 'array') { 12 | return deserialized; 13 | } else if (type === 'string') { 14 | return deserialized.split(',').map((item) => { 15 | return $.trim(item); 16 | }); 17 | } else { 18 | return []; 19 | } 20 | } 21 | }); 22 | -------------------------------------------------------------------------------- /client/app/transforms/dateiso.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | import moment from 'moment'; 3 | 4 | export default DS.Transform.extend({ 5 | deserialize: function (serialized) { 6 | if (serialized) { 7 | return moment(serialized).toDate(); 8 | } 9 | return serialized; 10 | }, 11 | 12 | serialize: function (deserialized) { 13 | if (deserialized) { 14 | return moment(deserialized).format(); 15 | } 16 | return deserialized; 17 | } 18 | }); 19 | -------------------------------------------------------------------------------- /client/app/utils/to-geo-json.js: -------------------------------------------------------------------------------- 1 | export default { 2 | point: point 3 | }; 4 | 5 | export function point (latlong, properties) { 6 | return { 7 | "type": "Point", 8 | "coordinates": [latlong.lng, latlong.lat] 9 | }; 10 | } 11 | -------------------------------------------------------------------------------- /client/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "client", 3 | "dependencies": { 4 | "ember": "1.13.11", 5 | "ember-cli-shims": "0.0.6", 6 | "ember-cli-test-loader": "0.2.1", 7 | "ember-data": "1.13.15", 8 | "ember-load-initializers": "0.1.7", 9 | "ember-qunit": "0.4.16", 10 | "ember-qunit-notifications": "0.1.0", 11 | "ember-resolver": "~0.1.20", 12 | "jquery": "~2.1.4", 13 | "loader.js": "ember-cli/loader.js#3.4.0", 14 | "qunit": "~1.20.0", 15 | "bootstrap": "~3.3.5", 16 | "materialize": "~0.97.0", 17 | "ember-simple-auth": "0.7.3", 18 | "ember-uploader": "0.3.11", 19 | "quill": "~0.20.1", 20 | "linqjs": "~3.0.5", 21 | "moment": ">= 2.8.0", 22 | "moment-timezone": ">= 0.1.0", 23 | "material-design-icons": "~2.1.3", 24 | "messenger": "~1.4.2", 25 | "ember-validations": "~1.0.0", 26 | "photoswipe": "~4.1.1" 27 | }, 28 | "resolutions": { 29 | "jquery": ">=2.1.1" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /client/ember-cli-build.js: -------------------------------------------------------------------------------- 1 | /*jshint node:true*/ 2 | /* global require, module */ 3 | var EmberApp = require('ember-cli/lib/broccoli/ember-app'); 4 | 5 | module.exports = function(defaults) { 6 | var app = new EmberApp(defaults, { 7 | // Add options here 8 | }); 9 | 10 | // Use `app.import` to add additional libraries to the generated 11 | // output files. 12 | // 13 | // If you need to use different assets in different 14 | // environments, specify an object as the first parameter. That 15 | // object's keys should be the environment name and the values 16 | // should be the asset to use in that environment. 17 | // 18 | // If the library that you are including contains AMD or ES6 19 | // modules that you would like to import into your application 20 | // please specify an object with the list of modules as keys 21 | // along with the exports of each module as its value. 22 | 23 | app.import('bower_components/quill/dist/quill.min.js'); 24 | app.import('bower_components/quill/dist/quill.base.css'); 25 | app.import('bower_components/quill/dist/quill.snow.css'); 26 | app.import('bower_components/linqjs/linq.min.js'); 27 | app.import('vendor/ecms-globals.js'); 28 | 29 | 30 | return app.toTree(); 31 | }; 32 | -------------------------------------------------------------------------------- /client/public/assets/android-desktop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/android-desktop.png -------------------------------------------------------------------------------- /client/public/assets/app-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/app-icon.png -------------------------------------------------------------------------------- /client/public/assets/button_degradation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/button_degradation.png -------------------------------------------------------------------------------- /client/public/assets/codepen-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/codepen-logo.png -------------------------------------------------------------------------------- /client/public/assets/colors.svg: -------------------------------------------------------------------------------- 1 | Oval 43 + Oval 43 + Oval 43 -------------------------------------------------------------------------------- /client/public/assets/comp_badges.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/comp_badges.png -------------------------------------------------------------------------------- /client/public/assets/comp_buttons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/comp_buttons.png -------------------------------------------------------------------------------- /client/public/assets/comp_cards.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/comp_cards.png -------------------------------------------------------------------------------- /client/public/assets/comp_layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/comp_layout.png -------------------------------------------------------------------------------- /client/public/assets/comp_loading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/comp_loading.png -------------------------------------------------------------------------------- /client/public/assets/comp_menus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/comp_menus.png -------------------------------------------------------------------------------- /client/public/assets/comp_sliders.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/comp_sliders.png -------------------------------------------------------------------------------- /client/public/assets/comp_tables.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/comp_tables.png -------------------------------------------------------------------------------- /client/public/assets/comp_textfields.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/comp_textfields.png -------------------------------------------------------------------------------- /client/public/assets/comp_toggles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/comp_toggles.png -------------------------------------------------------------------------------- /client/public/assets/comp_tooltips.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/comp_tooltips.png -------------------------------------------------------------------------------- /client/public/assets/compindex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/compindex.png -------------------------------------------------------------------------------- /client/public/assets/compindex_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/compindex_2x.png -------------------------------------------------------------------------------- /client/public/assets/components.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/components.png -------------------------------------------------------------------------------- /client/public/assets/components.svg: -------------------------------------------------------------------------------- 1 | components -------------------------------------------------------------------------------- /client/public/assets/components_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/components_2x.png -------------------------------------------------------------------------------- /client/public/assets/components_mo.svg: -------------------------------------------------------------------------------- 1 | components_mo -------------------------------------------------------------------------------- /client/public/assets/customize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/customize.png -------------------------------------------------------------------------------- /client/public/assets/customize.svg: -------------------------------------------------------------------------------- 1 | customize -------------------------------------------------------------------------------- /client/public/assets/customize_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/customize_2x.png -------------------------------------------------------------------------------- /client/public/assets/customize_mo.svg: -------------------------------------------------------------------------------- 1 | customize copy -------------------------------------------------------------------------------- /client/public/assets/customizer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/customizer.png -------------------------------------------------------------------------------- /client/public/assets/demos/dog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/demos/dog.png -------------------------------------------------------------------------------- /client/public/assets/demos/image_card.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/demos/image_card.jpg -------------------------------------------------------------------------------- /client/public/assets/demos/transparent.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/demos/transparent.jpg -------------------------------------------------------------------------------- /client/public/assets/demos/welcome_card.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/demos/welcome_card.jpg -------------------------------------------------------------------------------- /client/public/assets/faq/subscribe-single-issue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/faq/subscribe-single-issue.png -------------------------------------------------------------------------------- /client/public/assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/favicon.png -------------------------------------------------------------------------------- /client/public/assets/github_white_24.svg: -------------------------------------------------------------------------------- 1 | Shape -------------------------------------------------------------------------------- /client/public/assets/google-services.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/google-services.png -------------------------------------------------------------------------------- /client/public/assets/header.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/header.jpg -------------------------------------------------------------------------------- /client/public/assets/header_2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/header_2x.jpg -------------------------------------------------------------------------------- /client/public/assets/icons.svg: -------------------------------------------------------------------------------- 1 | Shape -------------------------------------------------------------------------------- /client/public/assets/ie.css: -------------------------------------------------------------------------------- 1 | .docs-layout .docs-layout-header.mdl-layout__header{display:block}body>div.mdl-layout__container>div>main>div>section.about-panel.about-panel--components.mdl-color-text--white.mdl-cell.mdl-cell--6-col,body>div.mdl-layout__container>div>main>div>section.about-panel.about-panel--styles.mdl-color-text--white.mdl-cell.mdl-cell--6-col{width:50%;float:left} -------------------------------------------------------------------------------- /client/public/assets/img-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/img-1.png -------------------------------------------------------------------------------- /client/public/assets/img-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/img-2.png -------------------------------------------------------------------------------- /client/public/assets/index.js: -------------------------------------------------------------------------------- 1 | !function(){Array.prototype.forEach.call(document.querySelectorAll("[data-target]"),function(t){var e=t.getAttribute("data-target");t.addEventListener("click",function(){location.href=e})})}(); -------------------------------------------------------------------------------- /client/public/assets/ios-desktop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/ios-desktop.png -------------------------------------------------------------------------------- /client/public/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/logo.png -------------------------------------------------------------------------------- /client/public/assets/logo.svg: -------------------------------------------------------------------------------- 1 | Shape -------------------------------------------------------------------------------- /client/public/assets/main.js: -------------------------------------------------------------------------------- 1 | !function(){"use strict";function e(){c.classList.remove("disabled"),n.classList.remove("disabled"),l.scrollLeft<=0&&c.classList.add("disabled"),l.scrollLeft+l.clientWidth+5>=l.scrollWidth&&n.classList.add("disabled")}function t(e){l.scrollLeft+=e}var n=document.querySelector(".scrollindicator.scrollindicator--right"),c=document.querySelector(".scrollindicator.scrollindicator--left"),l=document.querySelector(".docs-navigation"),i=40;l.addEventListener("scroll",e),e(),n.addEventListener("click",t.bind(null,i)),n.addEventListener("tap",t.bind(null,i)),c.addEventListener("click",t.bind(null,-i)),c.addEventListener("tap",t.bind(null,-i))}(),function(){"use strict";var e=document.querySelector(".download-button-container");e&&e.addEventListener("click",function(){ga("send",{hitType:"event",eventCategory:"click",eventAction:"mdl-download"})})}(),function(){"use strict";var e=document.querySelectorAll('[href=""]');Array.prototype.forEach.call(e,function(e){e.addEventListener("click",function(e){e.preventDefault()})})}(); -------------------------------------------------------------------------------- /client/public/assets/mo.svg: -------------------------------------------------------------------------------- 1 | mo -------------------------------------------------------------------------------- /client/public/assets/prism-css.min.js: -------------------------------------------------------------------------------- 1 | Prism.languages.css={comment:/\/\*[\w\W]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*\{))/i,inside:{punctuation:/[;:]/}},url:/url\((?:(["'])(\\\n|\\?.)*?\1|.*?)\)/i,selector:/[^\{\}\s][^\{\};]*(?=\s*\{)/,string:/("|')(\\\n|\\?.)*?\1/,property:/(\b|\B)[\w-]+(?=\s*:)/i,important:/\B!important\b/i,punctuation:/[\{\};:]/,"function":/[-a-z0-9]+(?=\()/i},Prism.languages.markup&&(Prism.languages.insertBefore("markup","tag",{style:{pattern:/[\w\W]*?<\/style>/i,inside:{tag:{pattern:/|<\/style>/i,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.css},alias:"language-css"}}),Prism.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|').*?\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:Prism.languages.markup.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:Prism.languages.css}},alias:"language-css"}},Prism.languages.markup.tag)); -------------------------------------------------------------------------------- /client/public/assets/prism-javascript.min.js: -------------------------------------------------------------------------------- 1 | Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|function|get|if|implements|import|in|instanceof|interface|let|new|null|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|-?Infinity)\b/,"function":/(?!\d)[a-z0-9_$]+(?=\()/i}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^\/])\/(?!\/)(\[.+?]|\\.|[^\/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/[\w\W]*?<\/script>/i,inside:{tag:{pattern:/|<\/script>/i,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.javascript},alias:"language-javascript"}}); -------------------------------------------------------------------------------- /client/public/assets/prism-markup.min.js: -------------------------------------------------------------------------------- 1 | Prism.languages.markup={comment://,prolog:/<\?.+?\?>/,doctype://,cdata://i,tag:{pattern:/<\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|[^\s'">=]+))?\s*)*\/?>/i,inside:{tag:{pattern:/^<\/?[\w:-]+/i,inside:{punctuation:/^<\/?/,namespace:/^[\w-]+?:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i,inside:{punctuation:/=|>|"/}},punctuation:/\/?>/,"attr-name":{pattern:/[\w:-]+/,inside:{namespace:/^[\w-]+?:/}}}},entity:/&#?[\da-z]{1,8};/i},Prism.hooks.add("wrap",function(t){"entity"===t.type&&(t.attributes.title=t.content.replace(/&/,"&"))}); -------------------------------------------------------------------------------- /client/public/assets/rich-media-gallery.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/rich-media-gallery.png -------------------------------------------------------------------------------- /client/public/assets/showcase/contributor.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/showcase/contributor.jpg -------------------------------------------------------------------------------- /client/public/assets/showcase/contributor_2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/showcase/contributor_2x.jpg -------------------------------------------------------------------------------- /client/public/assets/showcase/developers.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/showcase/developers.jpg -------------------------------------------------------------------------------- /client/public/assets/showcase/developers_2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/showcase/developers_2x.jpg -------------------------------------------------------------------------------- /client/public/assets/showcase/rework.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/showcase/rework.jpg -------------------------------------------------------------------------------- /client/public/assets/showcase/rework_2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/showcase/rework_2x.jpg -------------------------------------------------------------------------------- /client/public/assets/showcase/sunroof.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/showcase/sunroof.jpg -------------------------------------------------------------------------------- /client/public/assets/showcase/sunroof_2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/showcase/sunroof_2x.jpg -------------------------------------------------------------------------------- /client/public/assets/showcase/wallet.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/showcase/wallet.jpg -------------------------------------------------------------------------------- /client/public/assets/showcase/wallet_2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/showcase/wallet_2x.jpg -------------------------------------------------------------------------------- /client/public/assets/showcase/work_partners.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/showcase/work_partners.jpg -------------------------------------------------------------------------------- /client/public/assets/showcase/work_partners_2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/showcase/work_partners_2x.jpg -------------------------------------------------------------------------------- /client/public/assets/sliders_degradation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/sliders_degradation.png -------------------------------------------------------------------------------- /client/public/assets/snippets.js: -------------------------------------------------------------------------------- 1 | function MaterialComponentsSnippets(){"use strict";this.snippets=document.querySelectorAll("code.language-markup"),this.init()}MaterialComponentsSnippets.prototype.init=function(){"use strict";[].slice.call(this.snippets).forEach(function(t){t.addEventListener("click",this.onMouseClickHandler(t)),t.addEventListener("mouseout",this.onMouseOutHandler(t))},this)},MaterialComponentsSnippets.prototype.CssClasses_={COPIED:"copied",NOT_SUPPORTED:"nosupport"},MaterialComponentsSnippets.prototype.copyToClipboard=function(t){"use strict";var e=window.getSelection(),n=document.createRange();n.selectNodeContents(t),e.removeAllRanges(),e.addRange(n);var s=!1;try{s=document.execCommand("copy")}catch(o){console.error(o)}return e.removeAllRanges(),s},MaterialComponentsSnippets.prototype.onMouseClickHandler=function(t){"use strict";return function(){if(!(window.getSelection().toString().length>0)){var e=this.CssClasses_.COPIED;this.copyToClipboard(t)||(e=this.CssClasses_.NOT_SUPPORTED),t.classList.add(e)}}.bind(this)},MaterialComponentsSnippets.prototype.onMouseOutHandler=function(t){"use strict";return function(){t.classList.remove(this.CssClasses_.COPIED)}.bind(this)},window.addEventListener("load",function(){"use strict";new MaterialComponentsSnippets}); -------------------------------------------------------------------------------- /client/public/assets/styles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/styles.png -------------------------------------------------------------------------------- /client/public/assets/styles.svg: -------------------------------------------------------------------------------- 1 | styles -------------------------------------------------------------------------------- /client/public/assets/styles_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/styles_2x.png -------------------------------------------------------------------------------- /client/public/assets/styles_mo.svg: -------------------------------------------------------------------------------- 1 | styles -------------------------------------------------------------------------------- /client/public/assets/table_degradation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/table_degradation.png -------------------------------------------------------------------------------- /client/public/assets/template-preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/template-preview.png -------------------------------------------------------------------------------- /client/public/assets/templates.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/templates.png -------------------------------------------------------------------------------- /client/public/assets/templates.svg: -------------------------------------------------------------------------------- 1 | templates_mo -------------------------------------------------------------------------------- /client/public/assets/templates/android-dot-com.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/templates/android-dot-com.jpg -------------------------------------------------------------------------------- /client/public/assets/templates/android-dot-com_2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/templates/android-dot-com_2x.jpg -------------------------------------------------------------------------------- /client/public/assets/templates/article.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/templates/article.jpg -------------------------------------------------------------------------------- /client/public/assets/templates/article_2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/templates/article_2x.jpg -------------------------------------------------------------------------------- /client/public/assets/templates/blog.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/templates/blog.jpg -------------------------------------------------------------------------------- /client/public/assets/templates/blog_2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/templates/blog_2x.jpg -------------------------------------------------------------------------------- /client/public/assets/templates/dashboard.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/templates/dashboard.jpg -------------------------------------------------------------------------------- /client/public/assets/templates/dashboard_2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/templates/dashboard_2x.jpg -------------------------------------------------------------------------------- /client/public/assets/templates/general.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/templates/general.jpg -------------------------------------------------------------------------------- /client/public/assets/templates/general_2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/templates/general_2x.jpg -------------------------------------------------------------------------------- /client/public/assets/templates/product.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/templates/product.jpg -------------------------------------------------------------------------------- /client/public/assets/templates/product_2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/templates/product_2x.jpg -------------------------------------------------------------------------------- /client/public/assets/templates/text-only.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/templates/text-only.jpg -------------------------------------------------------------------------------- /client/public/assets/templates/text-only_2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/templates/text-only_2x.jpg -------------------------------------------------------------------------------- /client/public/assets/templates_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/public/assets/templates_2x.png -------------------------------------------------------------------------------- /client/public/assets/templates_mo.svg: -------------------------------------------------------------------------------- 1 | templates_mo -------------------------------------------------------------------------------- /client/public/crossdomain.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 15 | 16 | -------------------------------------------------------------------------------- /client/public/robots.txt: -------------------------------------------------------------------------------- 1 | # http://www.robotstxt.org 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /client/testem.json: -------------------------------------------------------------------------------- 1 | { 2 | "framework": "qunit", 3 | "test_page": "tests/index.html?hidepassed", 4 | "disable_watching": true, 5 | "launch_in_ci": [ 6 | "PhantomJS" 7 | ], 8 | "launch_in_dev": [ 9 | "PhantomJS", 10 | "Chrome" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /client/tests/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "predef": [ 3 | "document", 4 | "window", 5 | "location", 6 | "setTimeout", 7 | "$", 8 | "-Promise", 9 | "define", 10 | "console", 11 | "visit", 12 | "exists", 13 | "fillIn", 14 | "click", 15 | "keyEvent", 16 | "triggerEvent", 17 | "find", 18 | "findWithAssert", 19 | "wait", 20 | "DS", 21 | "andThen", 22 | "currentURL", 23 | "currentPath", 24 | "currentRouteName" 25 | ], 26 | "node": false, 27 | "browser": false, 28 | "boss": true, 29 | "curly": true, 30 | "debug": false, 31 | "devel": false, 32 | "eqeqeq": true, 33 | "evil": true, 34 | "forin": false, 35 | "immed": false, 36 | "laxbreak": false, 37 | "newcap": true, 38 | "noarg": true, 39 | "noempty": false, 40 | "nonew": false, 41 | "nomen": false, 42 | "onevar": false, 43 | "plusplus": false, 44 | "regexp": false, 45 | "undef": true, 46 | "sub": true, 47 | "strict": false, 48 | "white": false, 49 | "eqnull": true, 50 | "esnext": true, 51 | "unused": true 52 | } 53 | -------------------------------------------------------------------------------- /client/tests/helpers/destroy-app.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default function destroyApp(application) { 4 | Ember.run(application, 'destroy'); 5 | } 6 | -------------------------------------------------------------------------------- /client/tests/helpers/module-for-acceptance.js: -------------------------------------------------------------------------------- 1 | import { module } from 'qunit'; 2 | import startApp from '../helpers/start-app'; 3 | import destroyApp from '../helpers/destroy-app'; 4 | 5 | export default function(name, options = {}) { 6 | module(name, { 7 | beforeEach() { 8 | this.application = startApp(); 9 | 10 | if (options.beforeEach) { 11 | options.beforeEach.apply(this, arguments); 12 | } 13 | }, 14 | 15 | afterEach() { 16 | destroyApp(this.application); 17 | 18 | if (options.afterEach) { 19 | options.afterEach.apply(this, arguments); 20 | } 21 | } 22 | }); 23 | } 24 | -------------------------------------------------------------------------------- /client/tests/helpers/resolver.js: -------------------------------------------------------------------------------- 1 | import Resolver from 'ember/resolver'; 2 | import config from '../../config/environment'; 3 | 4 | const resolver = Resolver.create(); 5 | 6 | resolver.namespace = { 7 | modulePrefix: config.modulePrefix, 8 | podModulePrefix: config.podModulePrefix 9 | }; 10 | 11 | export default resolver; 12 | -------------------------------------------------------------------------------- /client/tests/helpers/start-app.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import Application from '../../app'; 3 | import config from '../../config/environment'; 4 | 5 | export default function startApp(attrs) { 6 | let application; 7 | 8 | let attributes = Ember.merge({}, config.APP); 9 | attributes = Ember.merge(attributes, attrs); // use defaults, but you can override; 10 | 11 | Ember.run(() => { 12 | application = Application.create(attributes); 13 | application.setupForTesting(); 14 | application.injectTestHelpers(); 15 | }); 16 | 17 | return application; 18 | } 19 | -------------------------------------------------------------------------------- /client/tests/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Client Tests 7 | 8 | 9 | 10 | {{content-for 'head'}} 11 | {{content-for 'test-head'}} 12 | 13 | 14 | 15 | 16 | 17 | {{content-for 'head-footer'}} 18 | {{content-for 'test-head-footer'}} 19 | 20 | 21 | {{content-for 'body'}} 22 | {{content-for 'test-body'}} 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | {{content-for 'body-footer'}} 32 | {{content-for 'test-body-footer'}} 33 | 34 | 35 | -------------------------------------------------------------------------------- /client/tests/integration/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/tests/integration/.gitkeep -------------------------------------------------------------------------------- /client/tests/integration/pods/components/file-upload/component-test.js: -------------------------------------------------------------------------------- 1 | import { moduleForComponent, test } from 'ember-qunit'; 2 | import hbs from 'htmlbars-inline-precompile'; 3 | 4 | moduleForComponent('file-upload', 'Integration | Component | file upload', { 5 | integration: true 6 | }); 7 | 8 | test('it renders', function(assert) { 9 | 10 | // Set any properties with this.set('myProperty', 'value'); 11 | // Handle any actions with this.on('myAction', function(val) { ... });" + EOL + EOL + 12 | 13 | this.render(hbs`{{file-upload}}`); 14 | 15 | assert.equal(this.$().text().trim(), ''); 16 | 17 | // Template block usage:" + EOL + 18 | this.render(hbs` 19 | {{#file-upload}} 20 | template block text 21 | {{/file-upload}} 22 | `); 23 | 24 | assert.equal(this.$().text().trim(), 'template block text'); 25 | }); 26 | -------------------------------------------------------------------------------- /client/tests/test-helper.js: -------------------------------------------------------------------------------- 1 | import resolver from './helpers/resolver'; 2 | import { 3 | setResolver 4 | } from 'ember-qunit'; 5 | 6 | setResolver(resolver); 7 | -------------------------------------------------------------------------------- /client/tests/unit/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/tests/unit/.gitkeep -------------------------------------------------------------------------------- /client/tests/unit/pods/membership/model-test.js: -------------------------------------------------------------------------------- 1 | import { moduleForModel, test } from 'ember-qunit'; 2 | 3 | moduleForModel('membership', 'Unit | Model | membership', { 4 | // Specify the other units that are required for this test. 5 | needs: [] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let model = this.subject(); 10 | // let store = this.store(); 11 | assert.ok(!!model); 12 | }); 13 | -------------------------------------------------------------------------------- /client/tests/unit/pods/membership/route-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:membership', 'Unit | Route | membership', { 4 | // Specify the other units that are required for this test. 5 | // needs: ['controller:foo'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /client/tests/unit/pods/page/model-test.js: -------------------------------------------------------------------------------- 1 | import { moduleForModel, test } from 'ember-qunit'; 2 | 3 | moduleForModel('page', 'Unit | Model | page', { 4 | // Specify the other units that are required for this test. 5 | needs: [] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let model = this.subject(); 10 | // let store = this.store(); 11 | assert.ok(!!model); 12 | }); 13 | -------------------------------------------------------------------------------- /client/tests/unit/pods/page/route-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:page', 'Unit | Route | page', { 4 | // Specify the other units that are required for this test. 5 | // needs: ['controller:foo'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /client/tests/unit/pods/photo/model-test.js: -------------------------------------------------------------------------------- 1 | import { moduleForModel, test } from 'ember-qunit'; 2 | 3 | moduleForModel('photo', 'Unit | Model | photo', { 4 | // Specify the other units that are required for this test. 5 | needs: [] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let model = this.subject(); 10 | // let store = this.store(); 11 | assert.ok(!!model); 12 | }); 13 | -------------------------------------------------------------------------------- /client/tests/unit/pods/photo/route-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:photo', 'Unit | Route | photo', { 4 | // Specify the other units that are required for this test. 5 | // needs: ['controller:foo'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /client/tests/unit/pods/protected/route-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:protected', 'Unit | Route | protected', { 4 | // Specify the other units that are required for this test. 5 | // needs: ['controller:foo'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /client/tests/unit/pods/section/model-test.js: -------------------------------------------------------------------------------- 1 | import { moduleForModel, test } from 'ember-qunit'; 2 | 3 | moduleForModel('section', 'Unit | Model | section', { 4 | // Specify the other units that are required for this test. 5 | needs: [] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let model = this.subject(); 10 | // let store = this.store(); 11 | assert.ok(!!model); 12 | }); 13 | -------------------------------------------------------------------------------- /client/tests/unit/pods/section/route-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:section', 'Unit | Route | section', { 4 | // Specify the other units that are required for this test. 5 | // needs: ['controller:foo'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /client/tests/unit/pods/test2/route-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:test2', 'Unit | Route | test2', { 4 | // Specify the other units that are required for this test. 5 | // needs: ['controller:foo'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /client/tests/unit/pods/translation/model-test.js: -------------------------------------------------------------------------------- 1 | import { moduleForModel, test } from 'ember-qunit'; 2 | 3 | moduleForModel('translation', 'Unit | Model | translation', { 4 | // Specify the other units that are required for this test. 5 | needs: [] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let model = this.subject(); 10 | // let store = this.store(); 11 | assert.ok(!!model); 12 | }); 13 | -------------------------------------------------------------------------------- /client/tests/unit/pods/translation/route-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:translation', 'Unit | Route | translation', { 4 | // Specify the other units that are required for this test. 5 | // needs: ['controller:foo'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /client/tests/unit/pods/user/model-test.js: -------------------------------------------------------------------------------- 1 | import { moduleForModel, test } from 'ember-qunit'; 2 | 3 | moduleForModel('user', 'Unit | Model | user', { 4 | // Specify the other units that are required for this test. 5 | needs: [] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let model = this.subject(); 10 | // let store = this.store(); 11 | assert.ok(!!model); 12 | }); 13 | -------------------------------------------------------------------------------- /client/tests/unit/routes/test-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:test', 'Unit | Route | test', { 4 | // Specify the other units that are required for this test. 5 | // needs: ['controller:foo'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /client/tests/unit/routes/test2-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:test2', 'Unit | Route | test2', { 4 | // Specify the other units that are required for this test. 5 | // needs: ['controller:foo'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /client/tests/unit/test/model-test.js: -------------------------------------------------------------------------------- 1 | import { moduleForModel, test } from 'ember-qunit'; 2 | 3 | moduleForModel('test', 'Unit | Model | test', { 4 | // Specify the other units that are required for this test. 5 | needs: [] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let model = this.subject(); 10 | // let store = this.store(); 11 | assert.ok(!!model); 12 | }); 13 | -------------------------------------------------------------------------------- /client/tests/unit/test/route-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:test', 'Unit | Route | test', { 4 | // Specify the other units that are required for this test. 5 | // needs: ['controller:foo'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /client/vendor/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/client/vendor/.gitkeep -------------------------------------------------------------------------------- /client/vendor/ecms-globals.js: -------------------------------------------------------------------------------- 1 | window.ecms = {}; 2 | window.ecms.hasRole = function(roleName) { 3 | var user = localStorage.getItem('ember_simple_auth:session'); 4 | if (typeof user !== 'string') 5 | return false; 6 | user = JSON.parse(user); 7 | if (typeof user === 'undefined' || !user || typeof user.user === 'undefined' || !user.user || typeof user.user.roles === 'undefined' || !user.user.roles) 8 | return false; 9 | return Enumerable.from(user.user.roles).any("$.name === '" + roleName + "'"); 10 | }; 11 | 12 | window.ecms.myUser = function() { 13 | var user = localStorage.getItem('ember_simple_auth:session'); 14 | if (typeof user !== 'string') 15 | return null; 16 | return JSON.parse(user); 17 | }; 18 | 19 | window.ecms.regexEmail = /^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i; 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /client/vendor/phantom-polyfill.js: -------------------------------------------------------------------------------- 1 | if (!Function.prototype.bind) { 2 | Function.prototype.bind = function(scope){ 3 | var self = this; 4 | return function(){ 5 | return self.apply(scope, arguments); 6 | }; 7 | }; 8 | } 9 | -------------------------------------------------------------------------------- /fig.yml: -------------------------------------------------------------------------------- 1 | db: 2 | image: mongo:latest #postgres, mysql, mongo, redis. You can also specifiy a specific version instead of using latest. 3 | ports: 4 | - "27017:27017" #for postgres "5432:5432", for mysql "3306:3306", for mongo "27017:27017", etc 5 | server: 6 | #Docker-sails supports several different tags: 7 | #0.10.32/33/34 (node 0.10.32), stable (latest node 0.10.x), latest (latest node 0.11.x) 8 | #0.10.32/33/34-pm2 (node 0.10.32), stable-pm2 (latest node 0.10.x), latest-pm2 (latest node 0.11.x) 9 | image: artificial/docker-sails:stable-pm2 10 | command: sails lift 11 | volumes: 12 | - server/:/server 13 | ports: 14 | - "1337:1337" 15 | links: 16 | - db 17 | #For a future version 18 | #environment: 19 | # - VIRTUAL_HOST=sails 20 | # - VIRTUAL_PORT=1337 -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "project", 3 | "version": "0.0.1", 4 | "description": "A blank sane stack project.", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "MIT", 11 | "dependencies": { 12 | "sane-cli": "0.0.24" 13 | }, 14 | "devDependencies": { 15 | "sane-auth": "^0.3.3" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /server/.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | -------------------------------------------------------------------------------- /server/.sailsrc: -------------------------------------------------------------------------------- 1 | { 2 | "hooks": { 3 | "grunt": false, 4 | "views": false 5 | }, 6 | "paths": { 7 | "public": "assets" 8 | }, 9 | "generators": { 10 | "modules": { 11 | "permissions-api": "sails-permissions/generator" 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /server/README.md: -------------------------------------------------------------------------------- 1 | # server 2 | 3 | a [Sails](http://sailsjs.org) application 4 | -------------------------------------------------------------------------------- /server/api/blueprints/create.js: -------------------------------------------------------------------------------- 1 | module.exports = require('sails-generate-ember-blueprints/templates/advanced/api/blueprints/create.js'); 2 | -------------------------------------------------------------------------------- /server/api/blueprints/find.js: -------------------------------------------------------------------------------- 1 | module.exports = require('sails-generate-ember-blueprints/templates/advanced/api/blueprints/find.js'); 2 | -------------------------------------------------------------------------------- /server/api/blueprints/findone.js: -------------------------------------------------------------------------------- 1 | module.exports = require('sails-generate-ember-blueprints/templates/advanced/api/blueprints/findone.js'); 2 | -------------------------------------------------------------------------------- /server/api/blueprints/populate.js: -------------------------------------------------------------------------------- 1 | module.exports = require('sails-generate-ember-blueprints/templates/advanced/api/blueprints/populate.js'); 2 | -------------------------------------------------------------------------------- /server/api/blueprints/update.js: -------------------------------------------------------------------------------- 1 | module.exports = require('sails-generate-ember-blueprints/templates/advanced/api/blueprints/update.js'); 2 | -------------------------------------------------------------------------------- /server/api/controllers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/server/api/controllers/.gitkeep -------------------------------------------------------------------------------- /server/api/controllers/AppController.js: -------------------------------------------------------------------------------- 1 | /** 2 | * AppController 3 | * 4 | * @description :: Server-side logic for managing apps 5 | * @help :: See http://links.sailsjs.org/docs/controllers 6 | */ 7 | var fs = require('fs'); 8 | 9 | module.exports = { 10 | /** 11 | * `AppController.serve()` 12 | * Serves your Ember App directly from the assets/index.html 13 | * 14 | * Add some custom code before delivering the app if you want 15 | * You could add some analytics, or use this to serve different 16 | * ember apps to differen people. 17 | * That can be useful for limited feature roll-out or A/B Testing, etc. 18 | * 19 | */ 20 | serve: function(req, res) { 21 | var emberApp = __dirname + '/../../assets/index.html'; 22 | fs.exists(emberApp, function (exists) { 23 | if (!exists) { 24 | return res.notFound('The requested file does not exist.'); 25 | } 26 | 27 | fs.createReadStream(emberApp).pipe(res); 28 | }); 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /server/api/controllers/LookupController.js: -------------------------------------------------------------------------------- 1 | 2 | var crypto = require("crypto"); 3 | var ObjectId = require('mongodb').ObjectID; 4 | var uuid = require('node-uuid'); 5 | var redis = require('redis'); 6 | var Enumerable = require('linq'); 7 | 8 | module.exports = { 9 | lookup: function (req,res) { 10 | if (req.body.type === "usr") { 11 | if (req.body.prefix && req.body.prefix.length > 3) { 12 | var red = redis.createClient(); 13 | red.send_command('scan', ['0', 'match', "waterline:usr:uuid:*" + req.body.prefix.toUpperCase() + "*"], function(err,result){ 14 | red.quit(); 15 | res.send(result[1]); 16 | }); 17 | } 18 | else { 19 | res.json(400, { error: "Expected a longer prefix"}); 20 | } 21 | 22 | } 23 | else if (req.body.type === "random-test") { 24 | var query = Test.find().where( { 25 | rand : { 26 | '>=' : Math.random() 27 | }, 28 | }).limit(5); 29 | query.exec(function(err, m) { 30 | if (err) 31 | res.json(404, {error : err}); 32 | else 33 | res.json(m); 34 | }); 35 | } 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /server/api/controllers/MembershipController.js: -------------------------------------------------------------------------------- 1 | /** 2 | * MembershipController 3 | * 4 | * @description :: Server-side logic for managing memberships 5 | * @help :: See http://sailsjs.org/#!/documentation/concepts/Controllers 6 | */ 7 | 8 | module.exports = { 9 | 10 | }; 11 | 12 | -------------------------------------------------------------------------------- /server/api/controllers/PageController.js: -------------------------------------------------------------------------------- 1 | /** 2 | * PageController 3 | * 4 | * @description :: Server-side logic for managing pages 5 | * @help :: See http://sailsjs.org/#!/documentation/concepts/Controllers 6 | */ 7 | 8 | module.exports = { 9 | 10 | }; 11 | 12 | -------------------------------------------------------------------------------- /server/api/controllers/PhotoController.js: -------------------------------------------------------------------------------- 1 | /** 2 | * PhotoController 3 | * 4 | * @description :: Server-side logic for managing photos 5 | * @help :: See http://sailsjs.org/#!/documentation/concepts/Controllers 6 | */ 7 | 8 | module.exports = { 9 | 10 | }; 11 | 12 | -------------------------------------------------------------------------------- /server/api/controllers/ProjectController.js: -------------------------------------------------------------------------------- 1 | /** 2 | * ProjectController 3 | * 4 | * @description :: Server-side logic for managing projects 5 | * @help :: See http://sailsjs.org/#!/documentation/concepts/Controllers 6 | */ 7 | 8 | module.exports = { 9 | 10 | }; 11 | 12 | -------------------------------------------------------------------------------- /server/api/controllers/SectionController.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SectionController 3 | * 4 | * @description :: Server-side logic for managing sections 5 | * @help :: See http://sailsjs.org/#!/documentation/concepts/Controllers 6 | */ 7 | 8 | module.exports = { 9 | 10 | }; 11 | 12 | -------------------------------------------------------------------------------- /server/api/controllers/TranslationController.js: -------------------------------------------------------------------------------- 1 | /** 2 | * TranslationController 3 | * 4 | * @description :: Server-side logic for managing translations 5 | * @help :: See http://sailsjs.org/#!/documentation/concepts/Controllers 6 | */ 7 | 8 | module.exports = { 9 | 10 | }; 11 | 12 | -------------------------------------------------------------------------------- /server/api/controllers/UserController.js: -------------------------------------------------------------------------------- 1 | var _ = require('lodash'); 2 | var _super = require('sails-auth/api/controllers/UserController'); 3 | 4 | _.merge(exports, _super); 5 | _.merge(exports, { 6 | 7 | //isAdmin handled through policies... 8 | isAdmin: function(req,res) { 9 | res.json(200, true); 10 | 11 | }, 12 | 13 | }); 14 | -------------------------------------------------------------------------------- /server/api/models/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/server/api/models/.gitkeep -------------------------------------------------------------------------------- /server/api/models/Company.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Company.js 3 | * 4 | * @description :: TODO: You might write a short summary of how this model works and what it represents here. 5 | * @docs :: http://sailsjs.org/#!documentation/models 6 | */ 7 | 8 | module.exports = { 9 | lookups: { 10 | 11 | }, 12 | 13 | attributes: { 14 | 15 | autoCreatedBy: true, 16 | 17 | name : { type: 'string', unique: true, index: true}, 18 | 19 | description : { type: 'string' }, 20 | 21 | hq : { type: 'string' }, 22 | 23 | address : { type: 'string' }, 24 | 25 | registration : { type: 'string' }, 26 | 27 | createdBy: {model: 'User', index: true }, 28 | 29 | owner: {model: 'User', index: true }, 30 | 31 | memberships: { collection: 'membership', via : 'company', includeIn: { list: "link", detail: "link" }}, //index,record,link 32 | 33 | projects: { collection: 'project', via : 'company', includeIn: { list: "link", detail: "link" }}, 34 | 35 | 36 | toJSON: function() { 37 | var obj = this.toObject(); 38 | delete users; 39 | return obj; 40 | } 41 | 42 | } 43 | }; 44 | 45 | -------------------------------------------------------------------------------- /server/api/models/Membership.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Membership.js 3 | * 4 | * @description :: TODO: You might write a short summary of how this model works and what it represents here. 5 | * @docs :: http://sailsjs.org/#!documentation/models 6 | */ 7 | 8 | module.exports = { 9 | 10 | attributes: { 11 | 12 | name : { type: 'string' }, 13 | 14 | description : { type: 'string' }, 15 | 16 | firstName : { type: 'string' }, 17 | 18 | lastName : { type: 'string' }, 19 | 20 | email: {type: 'string'}, 21 | 22 | registration : { type: 'string' }, 23 | 24 | position : { type: 'string' }, 25 | 26 | privileges : { type: 'array', defaultsTo: [] }, 27 | 28 | projects : { collection: 'project', via: 'memberships' }, 29 | 30 | user : { model: 'user' }, 31 | 32 | company : { model: 'company' } 33 | }, 34 | 35 | }; 36 | 37 | -------------------------------------------------------------------------------- /server/api/models/Page.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Page.js 3 | * 4 | * @description :: TODO: You might write a short summary of how this model works and what it represents here. 5 | * @docs :: http://sailsjs.org/#!documentation/models 6 | */ 7 | 8 | module.exports = { 9 | autoPK: false, 10 | attributes: { 11 | 12 | id : {type: 'string', primaryKey: true, unique: true, columnName: 'title'}, 13 | 14 | title : { type: 'string' }, 15 | 16 | description : { type: 'string' }, 17 | 18 | culture : { type: 'string' }, 19 | 20 | theme : { type: 'string' }, 21 | 22 | metadata : { type: 'string' }, 23 | 24 | category : { type: 'string' }, 25 | 26 | subcategory : { type: 'string' }, 27 | 28 | type : { type: 'string' }, 29 | 30 | subtype : { type: 'string' }, 31 | 32 | auth : { type: 'string' }, 33 | 34 | parent : { type: 'string' }, 35 | 36 | position : { type: 'float' }, 37 | 38 | hide: { type: 'boolean' }, 39 | 40 | publish: { type: 'datetime' }, 41 | 42 | sections : { 43 | collection: 'section', 44 | via: 'page', 45 | includeIn: { 46 | list: "index", 47 | detail: "record" 48 | } 49 | //dominant : true 50 | }, 51 | 52 | toJSON : function() { 53 | var obj = this.toObject(); 54 | obj.title = obj.id; 55 | return obj; 56 | }, 57 | 58 | } 59 | }; 60 | 61 | -------------------------------------------------------------------------------- /server/api/models/Photo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Photo.js 3 | * 4 | * @description :: TODO: You might write a short summary of how this model works and what it represents here. 5 | * @docs :: http://sailsjs.org/#!documentation/models 6 | */ 7 | 8 | module.exports = { 9 | 10 | attributes: { 11 | 12 | url : { type: 'string' }, 13 | 14 | thumb : { type: 'string' }, 15 | 16 | title : { type: 'string' }, 17 | 18 | description : { type: 'string' }, 19 | 20 | culture : { type: 'string' }, 21 | 22 | category : { type: 'string' }, 23 | 24 | tags : { type: 'string' }, 25 | 26 | auth : { type: 'string' }, 27 | 28 | reference : { type: 'string' } 29 | } 30 | }; 31 | 32 | -------------------------------------------------------------------------------- /server/api/models/Project.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Project.js 3 | * 4 | * @description :: TODO: You might write a short summary of how this model works and what it represents here. 5 | * @docs :: http://sailsjs.org/#!documentation/models 6 | */ 7 | 8 | module.exports = { 9 | 10 | attributes: { 11 | 12 | name : { type: 'string' }, 13 | 14 | description : { type: 'string' }, 15 | 16 | completed : { type: 'date' }, 17 | 18 | valuation : { type: 'float', defaultsTo: 0 }, 19 | 20 | photos: {type: 'array', defaultsTo: []}, 21 | 22 | company : { model: 'company' }, 23 | 24 | memberships : { collection: 'membership', via: 'projects' , includeIn: { list: "link", detail: "link" }}, 25 | 26 | } 27 | }; 28 | 29 | -------------------------------------------------------------------------------- /server/api/models/Section.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Section.js 3 | * 4 | * @description :: TODO: You might write a short summary of how this model works and what it represents here. 5 | * @docs :: http://sailsjs.org/#!documentation/models 6 | */ 7 | 8 | module.exports = { 9 | 10 | attributes: { 11 | 12 | page : { 13 | model: 'page', 14 | via: 'title', 15 | index: true 16 | }, 17 | 18 | title : { type: 'string' }, 19 | 20 | description : { type: 'string' }, 21 | 22 | culture : { type: 'string' }, 23 | 24 | category : { type: 'string' }, 25 | 26 | subcategory : { type: 'string' }, 27 | 28 | type : { type: 'string' }, 29 | 30 | subtype : { type: 'string' }, 31 | 32 | metadata : { type: 'string' }, 33 | 34 | auth : { type: 'string' }, 35 | 36 | position : { type: 'float' }, 37 | 38 | hide: { type: 'boolean' }, 39 | 40 | publish: { type: 'datetime' }, 41 | } 42 | }; 43 | 44 | -------------------------------------------------------------------------------- /server/api/models/Translation.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Translation.js 3 | * 4 | * @description :: TODO: You might write a short summary of how this model works and what it represents here. 5 | * @docs :: http://sailsjs.org/#!documentation/models 6 | */ 7 | 8 | module.exports = { 9 | 10 | attributes: { 11 | 12 | type : { type: 'string' }, 13 | 14 | tid : { type: 'string' }, 15 | 16 | culture : { type: 'string' }, 17 | 18 | title : { type: 'string' }, 19 | 20 | description : { type: 'string' } 21 | } 22 | }; 23 | 24 | -------------------------------------------------------------------------------- /server/api/models/UserPublic.js: -------------------------------------------------------------------------------- 1 | //Query Cache (Redis for lookups) 2 | module.exports = { 3 | connection:'redis', 4 | attributes: { 5 | 6 | uuid: { type: 'string', index: true, primaryKey: true }, 7 | json: { type: 'string'}, 8 | 9 | }, 10 | beforeValidate: function(values, cb) { 11 | cb(); 12 | }, 13 | }; 14 | -------------------------------------------------------------------------------- /server/api/policies/AuditPolicy.js: -------------------------------------------------------------------------------- 1 | var fnv = require('fnv-plus'); 2 | var _ = require('lodash'); 3 | var url = require('url'); 4 | 5 | module.exports = function (req, res, next) { 6 | var ipAddress = req.headers['x-forwarded-for'] || (req.connection && req.connection.remoteAddress); 7 | req.requestId = fnv.hash(new Date().valueOf() + ipAddress, 128).str(); 8 | 9 | sails.models.requestlog.create({ 10 | id: req.requestId, 11 | ipAddress: ipAddress, 12 | url: sanitizeRequestUrl(req), 13 | method: req.method, 14 | body: _.omit(req.body, 'password'), 15 | model: req.options.modelIdentity, 16 | user: (req.user || {}).id 17 | }).exec(_.identity); 18 | 19 | // persist RequestLog entry in the background; continue immediately 20 | next(); 21 | }; 22 | 23 | function sanitizeRequestUrl (req) { 24 | var requestUrl = url.format({ 25 | protocol: req.protocol, 26 | host: req.host || sails.getHost(), 27 | pathname: req.originalUrl || req.url, 28 | query: req.query 29 | }); 30 | 31 | return requestUrl.replace(/(password=).*?(&|$)/ig, '$1$2'); 32 | } 33 | -------------------------------------------------------------------------------- /server/api/policies/OwnerPolicy.js: -------------------------------------------------------------------------------- 1 | /** 2 | * TODO - this is setting createdBy, not owner. 3 | * The comment below, and the name of this file/function is confusing to me 4 | * Ensure that the 'owner' property of an Object is set upon creation. 5 | */ 6 | module.exports = function OwnerPolicy (req, res, next) { 7 | //sails.log('OwnerPolicy()'); 8 | if (!req.user || !req.user.id) { 9 | req.logout(); 10 | return res.send(500, new Error('req.user is not set')); 11 | } 12 | 13 | /* 14 | sails.log.verbose('OwnerPolicy user', req.user); 15 | sails.log.verbose('OwnerPolicy method', req.method); 16 | sails.log.verbose('OwnerPolicy req.body', req.body); 17 | */ 18 | 19 | if (req.options.modelDefinition.autoCreatedBy === false) { 20 | // sails.log.verbose('OwnerPolicy hasOwnershipPolicy: false'); 21 | return next(); 22 | } 23 | 24 | if ('POST' == req.method) { 25 | //req.body || (req.body = { }); 26 | req.body.createdBy = req.user.id; 27 | req.body.owner = req.user.id; 28 | } 29 | 30 | //sails.log.verbose('OwnerPolicy req.model', req.model); 31 | next(); 32 | }; 33 | -------------------------------------------------------------------------------- /server/api/policies/hasToken.js: -------------------------------------------------------------------------------- 1 | module.exports = require('express-jwt')({secret: sails.config.jwt.secret}); -------------------------------------------------------------------------------- /server/api/policies/isIDsOnly.js: -------------------------------------------------------------------------------- 1 | var Enumerable = require('linq'); 2 | 3 | module.exports = function (req, res, next) { 4 | keys = Object.keys(req.allParams()); 5 | if (Enumerable.from(keys).where("$ !== 'ids' && $ !== 'id'").any()) 6 | return res.status(403).json({ error: 'Only ids filterable' }); 7 | next(); 8 | }; 9 | -------------------------------------------------------------------------------- /server/api/policies/sessionAuth.js: -------------------------------------------------------------------------------- 1 | /** 2 | * sessionAuth 3 | * 4 | * @module :: Policy 5 | * @description :: Simple policy to allow any authenticated user 6 | * Assumes that your login action in one of your controllers sets `req.session.authenticated = true;` 7 | * @docs :: http://sailsjs.org/#!/documentation/concepts/Policies 8 | * 9 | */ 10 | module.exports = function(req, res, next) { 11 | 12 | // User is allowed, proceed to the next policy, 13 | // or if this is the last policy, the controller 14 | if (req.session.authenticated) { 15 | return next(); 16 | } 17 | 18 | // User is not allowed 19 | // (default res.forbidden() behavior can be overridden in `config/403.js`) 20 | return res.forbidden('You are not permitted to perform this action.'); 21 | }; 22 | -------------------------------------------------------------------------------- /server/api/responses/badRequest.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 400 (Bad Request) Handler 3 | * 4 | * Usage: 5 | * return res.badRequest(); 6 | * return res.badRequest(data); 7 | * return res.badRequest(data, 'some/specific/badRequest/view'); 8 | * 9 | * e.g.: 10 | * ``` 11 | * return res.badRequest( 12 | * 'Please choose a valid `password` (6-12 characters)', 13 | * 'trial/signup' 14 | * ); 15 | * ``` 16 | */ 17 | 18 | module.exports = function badRequest(data, options) { 19 | 20 | // Get access to `req`, `res`, & `sails` 21 | var req = this.req; 22 | var res = this.res; 23 | var sails = req._sails; 24 | 25 | // Set status code 26 | res.status(400); 27 | 28 | // Log error to console 29 | if (data !== undefined) { 30 | sails.log.verbose('Sending 400 ("Bad Request") response: \n',data); 31 | } 32 | else sails.log.verbose('Sending 400 ("Bad Request") response'); 33 | 34 | // Only include errors in response if application environment 35 | // is not set to 'production'. In production, we shouldn't 36 | // send back any identifying information about errors. 37 | if (sails.config.environment === 'production') { 38 | data = undefined; 39 | } 40 | 41 | // If the user-agent wants JSON, always respond with JSON 42 | return res.jsonx(data); 43 | }; 44 | -------------------------------------------------------------------------------- /server/api/responses/forbidden.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 403 (Forbidden) Handler 3 | * 4 | * Usage: 5 | * return res.forbidden(); 6 | * return res.forbidden(err); 7 | * return res.forbidden(err, 'some/specific/forbidden/view'); 8 | * 9 | * e.g.: 10 | * ``` 11 | * return res.forbidden('Access denied.'); 12 | * ``` 13 | */ 14 | 15 | module.exports = function forbidden (data, options) { 16 | 17 | // Get access to `req`, `res`, & `sails` 18 | var req = this.req; 19 | var res = this.res; 20 | var sails = req._sails; 21 | 22 | // Set status code 23 | res.status(403); 24 | 25 | // Log error to console 26 | if (data !== undefined) { 27 | sails.log.verbose('Sending 403 ("Forbidden") response: \n',data); 28 | } 29 | else sails.log.verbose('Sending 403 ("Forbidden") response'); 30 | 31 | // Only include errors in response if application environment 32 | // is not set to 'production'. In production, we shouldn't 33 | // send back any identifying information about errors. 34 | if (sails.config.environment === 'production') { 35 | data = undefined; 36 | } 37 | 38 | // If the user-agent wants JSON, always respond with JSON 39 | return res.jsonx(data); 40 | }; 41 | -------------------------------------------------------------------------------- /server/api/responses/notFound.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 404 (Not Found) Handler 3 | * 4 | * Usage: 5 | * return res.notFound(); 6 | * return res.notFound(err); 7 | * return res.notFound(err, 'some/specific/notfound/view'); 8 | * 9 | * e.g.: 10 | * ``` 11 | * return res.notFound(); 12 | * ``` 13 | * 14 | * NOTE: 15 | * If a request doesn't match any explicit routes (i.e. `config/routes.js`) 16 | * or route blueprints (i.e. "shadow routes", Sails will call `res.notFound()` 17 | * automatically. 18 | */ 19 | 20 | module.exports = function notFound (data, options) { 21 | 22 | // Get access to `req`, `res`, & `sails` 23 | var req = this.req; 24 | var res = this.res; 25 | var sails = req._sails; 26 | 27 | // Set status code 28 | res.status(404); 29 | 30 | // Log error to console 31 | if (data !== undefined) { 32 | sails.log.verbose('Sending 404 ("Not Found") response: \n',data); 33 | } 34 | else sails.log.verbose('Sending 404 ("Not Found") response'); 35 | 36 | // Only include errors in response if application environment 37 | // is not set to 'production'. In production, we shouldn't 38 | // send back any identifying information about errors. 39 | if (sails.config.environment === 'production') { 40 | data = undefined; 41 | } 42 | 43 | // If the user-agent wants JSON, always respond with JSON 44 | return res.jsonx(data); 45 | }; 46 | -------------------------------------------------------------------------------- /server/api/responses/ok.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 200 (OK) Response 3 | * 4 | * Usage: 5 | * return res.ok(); 6 | * return res.ok(data); 7 | * return res.ok(data, 'auth/login'); 8 | * 9 | * @param {Object} data 10 | * @param {String|Object} options 11 | * - pass string to render specified view 12 | */ 13 | 14 | module.exports = function sendOK (data, options) { 15 | 16 | // Get access to `req`, `res`, & `sails` 17 | var req = this.req; 18 | var res = this.res; 19 | var sails = req._sails; 20 | 21 | sails.log.silly('res.ok() :: Sending 200 ("OK") response'); 22 | 23 | // Set status code 24 | res.status(200); 25 | 26 | return res.jsonx(data); 27 | }; 28 | -------------------------------------------------------------------------------- /server/api/responses/serverError.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 500 (Server Error) Response 3 | * 4 | * Usage: 5 | * return res.serverError(); 6 | * return res.serverError(err); 7 | * return res.serverError(err, 'some/specific/error/view'); 8 | * 9 | * NOTE: 10 | * If something throws in a policy or controller, or an internal 11 | * error is encountered, Sails will call `res.serverError()` 12 | * automatically. 13 | */ 14 | 15 | module.exports = function serverError (data, options) { 16 | 17 | // Get access to `req`, `res`, & `sails` 18 | var req = this.req; 19 | var res = this.res; 20 | var sails = req._sails; 21 | 22 | // Set status code 23 | res.status(500); 24 | 25 | // Log error to console 26 | if (data !== undefined) { 27 | sails.log.error('Sending 500 ("Server Error") response: \n',data); 28 | } 29 | else sails.log.error('Sending empty 500 ("Server Error") response'); 30 | 31 | // Only include errors in response if application environment 32 | // is not set to 'production'. In production, we shouldn't 33 | // send back any identifying information about errors. 34 | if (sails.config.environment === 'production') { 35 | data = undefined; 36 | } 37 | 38 | // If the user-agent wants JSON, always respond with JSON 39 | return res.jsonx(data); 40 | }; 41 | -------------------------------------------------------------------------------- /server/api/services/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/server/api/services/.gitkeep -------------------------------------------------------------------------------- /server/api/services/Ember.js: -------------------------------------------------------------------------------- 1 | module.exports = require('sails-generate-ember-blueprints/templates/advanced/api/services/Ember.js'); 2 | -------------------------------------------------------------------------------- /server/api/services/Token.js: -------------------------------------------------------------------------------- 1 | var jwt = require('jsonwebtoken'); 2 | var secret = sails.config.jwt.secret 3 | var refresh_secret = sails.config.jwt.refresh_secret; 4 | var bcrypt = require('bcrypt'); 5 | var _ = require('lodash'); 6 | 7 | exports.getUser = function(token) { 8 | return new Promise(function (resolve, reject) { 9 | if (typeof token === 'undefined' || !token) { 10 | console.log("no token"); 11 | return reject('not a valid token [0]'); 12 | } 13 | else { 14 | var parts = token.split(' '); 15 | if (parts.length == 2) { 16 | var scheme = parts[0], 17 | credentials = parts[1]; 18 | if (/^Bearer$/i.test(scheme)) { 19 | jwt.verify(credentials, secret, function (err, result) { 20 | //console.log("err:", err, " result: ", result); 21 | if (err) { 22 | return reject(err); 23 | } 24 | else { 25 | if (typeof result.user !== 'undefined' && result.user) 26 | result = result.user; 27 | return resolve(result['0'] || result[0] || result); 28 | } 29 | }); 30 | } 31 | else { 32 | return reject('not a valid token [1]'); 33 | } 34 | } else { 35 | return reject('not a valid token [2]'); 36 | } 37 | } 38 | }); 39 | 40 | }; 41 | -------------------------------------------------------------------------------- /server/api/services/passport.js: -------------------------------------------------------------------------------- 1 | module.exports = require('sails-auth/api/services/passport'); 2 | -------------------------------------------------------------------------------- /server/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/server/assets/favicon.ico -------------------------------------------------------------------------------- /server/assets/fonts/WorkSans-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/server/assets/fonts/WorkSans-Light.ttf -------------------------------------------------------------------------------- /server/assets/images/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/server/assets/images/.gitkeep -------------------------------------------------------------------------------- /server/assets/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/server/assets/index.html -------------------------------------------------------------------------------- /server/assets/public/inject.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/server/assets/public/inject.js -------------------------------------------------------------------------------- /server/assets/robots.txt: -------------------------------------------------------------------------------- 1 | # The robots.txt file is used to control how search engines index your live URLs. 2 | # See http://www.robotstxt.org/wc/norobots.html for more information. 3 | 4 | 5 | 6 | # To prevent search engines from seeing the site altogether, uncomment the next two lines: 7 | # User-Agent: * 8 | # Disallow: / 9 | -------------------------------------------------------------------------------- /server/assets/styles/importer.less: -------------------------------------------------------------------------------- 1 | /** 2 | * importer.less 3 | * 4 | * By default, new Sails projects are configured to compile this file 5 | * from LESS to CSS. Unlike CSS files, LESS files are not compiled and 6 | * included automatically unless they are imported below. 7 | * 8 | * The LESS files imported below are compiled and included in the order 9 | * they are listed. Mixins, variables, etc. should be imported first 10 | * so that they can be accessed by subsequent LESS stylesheets. 11 | * 12 | * (Just like the rest of the asset pipeline bundled in Sails, you can 13 | * always omit, customize, or replace this behavior with SASS, SCSS, 14 | * or any other Grunt tasks you like.) 15 | */ 16 | 17 | 18 | 19 | // For example: 20 | // 21 | // @import 'variables/colors.less'; 22 | // @import 'mixins/foo.less'; 23 | // @import 'mixins/bar.less'; 24 | // @import 'mixins/baz.less'; 25 | // 26 | // @import 'styleguide.less'; 27 | // @import 'pages/login.less'; 28 | // @import 'pages/signup.less'; 29 | // 30 | // etc. 31 | -------------------------------------------------------------------------------- /server/assets/templates/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dioptre/embercms/d2223842ff2dc9ecd888bb4a81737306ebf27d1e/server/assets/templates/.gitkeep -------------------------------------------------------------------------------- /server/config/autoreload.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | 3 | module.exports.autoreload = { 4 | active: process.env.NODE_ENV === undefined || process.env.NODE_ENV ==='development', 5 | //use polling to watch file changes 6 | //slower but needed for the docker image 7 | usePolling: false, 8 | // Set dirs to watch 9 | dirs: [ 10 | path.resolve('api','blueprints'), 11 | path.resolve('api','controllers'), 12 | path.resolve('api','models'), 13 | path.resolve('api','policies'), 14 | path.resolve('api','responses'), 15 | path.resolve('api','services'), 16 | path.resolve('config') 17 | ] 18 | }; 19 | -------------------------------------------------------------------------------- /server/config/blueprint.js: -------------------------------------------------------------------------------- 1 | // config/blueprints.js 2 | module.exports.blueprints = { 3 | // existing configuration 4 | // ... 5 | 6 | //ember: { 7 | //sideload: true 8 | //} 9 | } 10 | -------------------------------------------------------------------------------- /server/config/bootstrap.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Bootstrap 3 | * (sails.config.bootstrap) 4 | * 5 | * An asynchronous bootstrap function that runs before your Sails app gets lifted. 6 | * This gives you an opportunity to set up your data model, run jobs, or perform some special logic. 7 | * 8 | * For more information on bootstrapping your app, check out: 9 | * http://sailsjs.org/#!/documentation/reference/sails.config/sails.config.bootstrap.html 10 | */ 11 | 12 | module.exports.bootstrap = function(cb) { 13 | // It's very important to trigger this callback method when you are finished 14 | // with the bootstrap! (otherwise your server will never lift, since it's waiting on the bootstrap) 15 | sails.on('lifted', function() { 16 | // Your post-lift startup code here 17 | console.log("SAILS LIFTED"); 18 | 19 | }); 20 | cb(); 21 | }; 22 | -------------------------------------------------------------------------------- /server/config/env/development.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Development environment settings 3 | * 4 | * This file can include shared settings for a development team, 5 | * such as API keys or remote database passwords. If you're using 6 | * a version control solution for your Sails app, this file will 7 | * be committed to your repository unless you add it to your .gitignore 8 | * file. If your repository will be publicly viewable, don't add 9 | * any private information to this file! 10 | * 11 | */ 12 | 13 | module.exports = { 14 | 15 | /*************************************************************************** 16 | * Set the default database connection for models in the development * 17 | * environment (see config/connections.js and config/models.js ) * 18 | ***************************************************************************/ 19 | 20 | // models: { 21 | // connection: 'someMongodbServer' 22 | // } 23 | 24 | }; 25 | -------------------------------------------------------------------------------- /server/config/installedHooks.js: -------------------------------------------------------------------------------- 1 | module.exports.installedHooks = { 2 | "sails-permissions": { 3 | "name": "permissions", 4 | "configKey": "permissions" 5 | } 6 | }; 7 | -------------------------------------------------------------------------------- /server/config/jwt.js: -------------------------------------------------------------------------------- 1 | // set environment variables in production deployments to set secrets 2 | // use from global `sails.config.jwt.secret` 3 | //CHANGEME 4 | module.exports.jwt = { 5 | secret: process.env.JWT_SECRET || '**n0t-S0-s3cr3t-K3y!', 6 | refresh_secret: process.env.JWT_REFRESH_SECRET || 'r3Fr3sh-K3y*!', 7 | expiration_time_in_minutes: process.env.JWT_EXPIRATION_TIME_IN_MINUTES || 60*2 8 | } 9 | -------------------------------------------------------------------------------- /server/config/locales/_README.md: -------------------------------------------------------------------------------- 1 | # Internationalization / Localization Settings 2 | 3 | > Also see the official docs on internationalization/localization: 4 | > http://links.sailsjs.org/docs/config/locales 5 | 6 | ## Locales 7 | All locale files live under `config/locales`. Here is where you can add translations 8 | as JSON key-value pairs. The name of the file should match the language that you are supporting, which allows for automatic language detection based on request headers. 9 | 10 | Here is an example locale stringfile for the Spanish language (`config/locales/es.json`): 11 | ```json 12 | { 13 | "Hello!": "Hola!", 14 | "Hello %s, how are you today?": "¿Hola %s, como estas?", 15 | } 16 | ``` 17 | ## Usage 18 | Locales can be accessed in controllers/policies through `res.i18n()`, or in views through the `__(key)` or `i18n(key)` functions. 19 | Remember that the keys are case sensitive and require exact key matches, e.g. 20 | 21 | ```ejs 22 |

<%= __('Welcome to PencilPals!') %>

23 |

<%= i18n('Hello %s, how are you today?', 'Pencil Maven') %>

24 |

<%= i18n('That\'s right-- you can use either i18n() or __()') %>

25 | ``` 26 | 27 | ## Configuration 28 | Localization/internationalization config can be found in `config/i18n.js`, from where you can set your supported locales. 29 | -------------------------------------------------------------------------------- /server/config/locales/de.json: -------------------------------------------------------------------------------- 1 | { 2 | "Welcome": "Willkommen", 3 | "A brand new app.": "Eine neue App." 4 | } 5 | -------------------------------------------------------------------------------- /server/config/locales/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "Welcome": "Welcome", 3 | "A brand new app.": "A brand new app." 4 | } 5 | -------------------------------------------------------------------------------- /server/config/locales/es.json: -------------------------------------------------------------------------------- 1 | { 2 | "Welcome": "Bienvenido", 3 | "A brand new app.": "Una aplicación de la nueva marca." 4 | } 5 | -------------------------------------------------------------------------------- /server/config/locales/fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "Welcome": "Bienvenue", 3 | "A brand new app.": "Une toute nouvelle application." 4 | } 5 | -------------------------------------------------------------------------------- /server/config/log.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Built-in Log Configuration 3 | * (sails.config.log) 4 | * 5 | * Configure the log level for your app, as well as the transport 6 | * (Underneath the covers, Sails uses Winston for logging, which 7 | * allows for some pretty neat custom transports/adapters for log messages) 8 | * 9 | * For more information on the Sails logger, check out: 10 | * http://sailsjs.org/#!/documentation/concepts/Logging 11 | */ 12 | 13 | module.exports.log = { 14 | 15 | /*************************************************************************** 16 | * * 17 | * Valid `level` configs: i.e. the minimum log level to capture with * 18 | * sails.log.*() * 19 | * * 20 | * The order of precedence for log levels from lowest to highest is: * 21 | * silly, verbose, info, debug, warn, error * 22 | * * 23 | * You may also set the level to "silent" to suppress all logs. * 24 | * * 25 | ***************************************************************************/ 26 | 27 | // level: 'info' 28 | 29 | }; 30 | -------------------------------------------------------------------------------- /server/config/permission.js: -------------------------------------------------------------------------------- 1 | // config/permissions.js 2 | 3 | var _ = require('lodash'); 4 | _.merge(exports, { 5 | 6 | // Extend with custom logic here by adding additional fields, methods, etc. 7 | 8 | }); 9 | 10 | -------------------------------------------------------------------------------- /server/config/permissions.js: -------------------------------------------------------------------------------- 1 | // config/permissions.js 2 | 3 | var _ = require('lodash'); 4 | var _super = require('sails-permissions/config/permissions'); 5 | 6 | _.merge(exports, _super); 7 | _.merge(exports, { 8 | 9 | // Extend with custom logic here by adding additional fields, methods, etc. 10 | 11 | }); 12 | 13 | -------------------------------------------------------------------------------- /server/config/sendgrid.js: -------------------------------------------------------------------------------- 1 | // set environment variables in production deployments to set secrets 2 | // use from global `sails.config.sendgrid.psk` 3 | //CHANGEME 4 | module.exports.sendgrid = { 5 | psk: "KKKKKKKK", 6 | sender: "admin@gmail.com", 7 | admin: "admin@gmail.com" 8 | } 9 | -------------------------------------------------------------------------------- /server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "private": true, 4 | "version": "0.0.0", 5 | "description": "a Sails application", 6 | "keywords": [], 7 | "dependencies": { 8 | "bcrypt": "^0.8.5", 9 | "bluebird": "^3.1.1", 10 | "express-jwt": "^3.0.1", 11 | "fnv-plus": "^1.2.12", 12 | "gm": "^1.21.1", 13 | "grunt-contrib-coffee": "~0.10.1", 14 | "include-all": "~0.1.3", 15 | "jsonwebtoken": "^5.0.5", 16 | "kerberos": "0.0.17", 17 | "linq": "^3.0.5", 18 | "lodash": "^3.10.1", 19 | "moment": "^2.11.0", 20 | "node-uuid": "^1.4.7", 21 | "pdfkit": "^0.7.2", 22 | "pluralize": "^1.2.1", 23 | "rc": "~0.5.0", 24 | "redis": "^2.4.2", 25 | "request": "^2.67.0", 26 | "request-promise": "^2.0.0", 27 | "require-all": "^2.0.0", 28 | "sails": "~0.11.3", 29 | "sails-auth": "^2.1.1", 30 | "sails-disk": "~0.10.0", 31 | "sails-generate-ember-blueprints": "0.0.9", 32 | "sails-hook-autoreload": "^0.11.5", 33 | "sails-mongo": "^0.11.5", 34 | "sails-permissions": "^2.1.11", 35 | "sails-redis": "^0.10.6", 36 | "sanitize-html": "^1.11.2", 37 | "sendgrid": "^2.0.0" 38 | }, 39 | "scripts": { 40 | "debug": "node debug app.js", 41 | "start": "node app.js" 42 | }, 43 | "main": "app.js", 44 | "repository": { 45 | "type": "git", 46 | "url": "git://github.com/a/server.git" 47 | }, 48 | "author": "a", 49 | "license": "" 50 | } 51 | --------------------------------------------------------------------------------