Showing preview only (1,478K chars total). Download the full file or copy to clipboard to get everything.
Repository: edshadi/relax
Branch: master
Commit: 04620b4323b7
Files: 798
Total size: 1.2 MB
Directory structure:
gitextract_vwl5em8h/
├── .eslintrc
├── .gitignore
├── .npmignore
├── .relaxrc.sample
├── LICENSE
├── README.md
├── ROADMAP.md
├── app.js
├── assets/
│ └── fonts/
│ └── FontAwesome.otf
├── config.js
├── lib/
│ ├── client/
│ │ ├── admin.js
│ │ ├── auth.js
│ │ ├── helpers/
│ │ │ └── render-routes.js
│ │ └── public.js
│ ├── server/
│ │ ├── graphql/
│ │ │ ├── authorize.js
│ │ │ ├── mutations/
│ │ │ │ ├── color/
│ │ │ │ │ ├── add.js
│ │ │ │ │ ├── duplicate.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── remove.js
│ │ │ │ │ └── update.js
│ │ │ │ ├── draft/
│ │ │ │ │ ├── drop.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── update.js
│ │ │ │ ├── fonts/
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── remove-custom.js
│ │ │ │ │ ├── submit-custom.js
│ │ │ │ │ └── upload.js
│ │ │ │ ├── index.js
│ │ │ │ ├── media/
│ │ │ │ │ ├── add.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── remove.js
│ │ │ │ ├── menu/
│ │ │ │ │ ├── add.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── remove.js
│ │ │ │ │ └── update.js
│ │ │ │ ├── page/
│ │ │ │ │ ├── add.js
│ │ │ │ │ ├── duplicate.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── remove.js
│ │ │ │ │ ├── restore.js
│ │ │ │ │ └── update.js
│ │ │ │ ├── schema-entry/
│ │ │ │ │ ├── add.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── remove.js
│ │ │ │ │ ├── restore.js
│ │ │ │ │ └── update.js
│ │ │ │ ├── schemas/
│ │ │ │ │ ├── add.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── remove.js
│ │ │ │ │ ├── restore.js
│ │ │ │ │ └── update.js
│ │ │ │ ├── settings/
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── save.js
│ │ │ │ ├── style/
│ │ │ │ │ ├── add.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── parsable-fields.js
│ │ │ │ │ ├── remove.js
│ │ │ │ │ └── update.js
│ │ │ │ ├── symbol/
│ │ │ │ │ ├── add.js
│ │ │ │ │ └── index.js
│ │ │ │ ├── tab/
│ │ │ │ │ ├── add.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── remove.js
│ │ │ │ └── user/
│ │ │ │ ├── add.js
│ │ │ │ ├── index.js
│ │ │ │ └── remove.js
│ │ │ ├── queries/
│ │ │ │ ├── color/
│ │ │ │ │ ├── colors.js
│ │ │ │ │ └── index.js
│ │ │ │ ├── draft/
│ │ │ │ │ ├── draft.js
│ │ │ │ │ └── index.js
│ │ │ │ ├── generators/
│ │ │ │ │ ├── schema-list-count.js
│ │ │ │ │ └── schema-list.js
│ │ │ │ ├── index.js
│ │ │ │ ├── media/
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── media-count.js
│ │ │ │ │ └── media.js
│ │ │ │ ├── menu/
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── menu.js
│ │ │ │ │ ├── menus-count.js
│ │ │ │ │ └── menus.js
│ │ │ │ ├── page/
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── page.js
│ │ │ │ │ ├── pages-count.js
│ │ │ │ │ └── pages.js
│ │ │ │ ├── revision/
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── revisions.js
│ │ │ │ ├── schema-entry/
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── schema-entry.js
│ │ │ │ │ ├── schema-list-count.js
│ │ │ │ │ └── schema-list.js
│ │ │ │ ├── schemas/
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── schema.js
│ │ │ │ │ ├── schemas-count.js
│ │ │ │ │ └── schemas.js
│ │ │ │ ├── settings/
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── settings.js
│ │ │ │ ├── style/
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── styles.js
│ │ │ │ ├── symbol/
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── symbol.js
│ │ │ │ │ └── symbols.js
│ │ │ │ ├── tab/
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── tabs.js
│ │ │ │ └── user/
│ │ │ │ ├── index.js
│ │ │ │ ├── session.js
│ │ │ │ ├── user.js
│ │ │ │ ├── users-count.js
│ │ │ │ └── users.js
│ │ │ ├── query-pagination.js
│ │ │ └── types/
│ │ │ ├── color-input.js
│ │ │ ├── color.js
│ │ │ ├── count.js
│ │ │ ├── custom-font.js
│ │ │ ├── draft-id-input.js
│ │ │ ├── draft-id.js
│ │ │ ├── draft-input.js
│ │ │ ├── draft.js
│ │ │ ├── filter.js
│ │ │ ├── generators/
│ │ │ │ ├── schema-entry-input.js
│ │ │ │ └── schema-entry.js
│ │ │ ├── media-input.js
│ │ │ ├── media.js
│ │ │ ├── menu-data.js
│ │ │ ├── menu-input.js
│ │ │ ├── menu.js
│ │ │ ├── page-input.js
│ │ │ ├── page.js
│ │ │ ├── revision.js
│ │ │ ├── schema-entry-input.js
│ │ │ ├── schema-entry.js
│ │ │ ├── schema-input.js
│ │ │ ├── schema.js
│ │ │ ├── setting-input.js
│ │ │ ├── setting.js
│ │ │ ├── style-input.js
│ │ │ ├── style.js
│ │ │ ├── symbol-input.js
│ │ │ ├── symbol.js
│ │ │ ├── tab-item.js
│ │ │ ├── tab.js
│ │ │ ├── uploaded-input.js
│ │ │ ├── uploaded.js
│ │ │ ├── user-input.js
│ │ │ └── user.js
│ │ ├── index.js
│ │ ├── logger.js
│ │ ├── middleware/
│ │ │ ├── fonts.js
│ │ │ ├── google-analytics.js
│ │ │ └── index.js
│ │ ├── migrate.js
│ │ ├── models/
│ │ │ ├── color.js
│ │ │ ├── draft.js
│ │ │ ├── index.js
│ │ │ ├── media.js
│ │ │ ├── menu.js
│ │ │ ├── migration.js
│ │ │ ├── page.js
│ │ │ ├── revision.js
│ │ │ ├── schema-entry.js
│ │ │ ├── schema.js
│ │ │ ├── setting.js
│ │ │ ├── style.js
│ │ │ ├── symbol.js
│ │ │ ├── tab.js
│ │ │ └── user.js
│ │ ├── routers/
│ │ │ ├── admin.js
│ │ │ ├── auth.js
│ │ │ ├── index.js
│ │ │ └── public.js
│ │ ├── schema.js
│ │ └── shared/
│ │ ├── components/
│ │ │ └── html.jsx
│ │ └── helpers/
│ │ ├── create-image-thumbnail.js
│ │ ├── default-favicon.js
│ │ ├── file-mimetype.js
│ │ ├── get-markup.js
│ │ ├── get-projection.js
│ │ ├── get-unique-slug.js
│ │ ├── resize-image.js
│ │ ├── route-handler.js
│ │ ├── safe-html-string.js
│ │ └── write-file.js
│ └── shared/
│ ├── actions/
│ │ ├── admin-menu.js
│ │ ├── colors.js
│ │ ├── display.js
│ │ ├── dnd.js
│ │ ├── draft.js
│ │ ├── elements.js
│ │ ├── fonts.js
│ │ ├── graphql.js
│ │ ├── index.js
│ │ ├── media.js
│ │ ├── menu.js
│ │ ├── page-builder.js
│ │ ├── page.js
│ │ ├── revisions.js
│ │ ├── schema-entry.js
│ │ ├── schema-list.js
│ │ ├── schema.js
│ │ ├── schemas.js
│ │ ├── session.js
│ │ ├── settings.js
│ │ ├── styles.js
│ │ ├── symbols.js
│ │ ├── tabs.js
│ │ └── users.js
│ ├── components/
│ │ ├── a.jsx
│ │ ├── animate-props.jsx
│ │ ├── animate.jsx
│ │ ├── background-image.jsx
│ │ ├── button/
│ │ │ ├── index.jsx
│ │ │ └── index.less
│ │ ├── component.jsx
│ │ ├── dnd/
│ │ │ ├── draggable/
│ │ │ │ ├── draggable.jsx
│ │ │ │ └── index.js
│ │ │ ├── dragger/
│ │ │ │ ├── dragger.jsx
│ │ │ │ ├── dragger.less
│ │ │ │ └── index.js
│ │ │ └── droppable/
│ │ │ ├── add-ballon.jsx
│ │ │ ├── add-ballon.less
│ │ │ ├── droppable.jsx
│ │ │ ├── droppable.less
│ │ │ ├── index.js
│ │ │ ├── marker.jsx
│ │ │ └── marker.less
│ │ ├── image.jsx
│ │ ├── medium-editor/
│ │ │ ├── index.jsx
│ │ │ └── index.less
│ │ └── portal.jsx
│ ├── decorators/
│ │ ├── bind.js
│ │ ├── debounce.js
│ │ └── query-props.jsx
│ ├── elements/
│ │ ├── button/
│ │ │ ├── classes.js
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ ├── settings.js
│ │ │ └── style.js
│ │ ├── column/
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ └── settings.js
│ │ ├── columns/
│ │ │ ├── classes.js
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ └── settings.js
│ │ ├── component.jsx
│ │ ├── container/
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ ├── settings.js
│ │ │ └── style.js
│ │ ├── counter/
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ └── settings.js
│ │ ├── date/
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.jsx
│ │ │ └── settings.js
│ │ ├── dynamic-list/
│ │ │ ├── classes.js
│ │ │ ├── container.jsx
│ │ │ ├── index.jsx
│ │ │ ├── list.jsx
│ │ │ ├── props-schema.js
│ │ │ └── settings.js
│ │ ├── element/
│ │ │ ├── context-menu/
│ │ │ │ ├── context-menu.jsx
│ │ │ │ ├── context-menu.less
│ │ │ │ └── index.js
│ │ │ ├── element.jsx
│ │ │ ├── empty.jsx
│ │ │ ├── empty.less
│ │ │ ├── highlight.jsx
│ │ │ ├── highlight.less
│ │ │ └── index.js
│ │ ├── form/
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ └── settings.js
│ │ ├── gap/
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ └── settings.js
│ │ ├── google-maps/
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ └── settings.js
│ │ ├── icon/
│ │ │ ├── classes.js
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ ├── settings.js
│ │ │ └── style.js
│ │ ├── image/
│ │ │ ├── classes.js
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ └── settings.js
│ │ ├── index.js
│ │ ├── line-divider/
│ │ │ ├── classes.js
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ ├── settings.js
│ │ │ └── style.js
│ │ ├── menu/
│ │ │ ├── classes.js
│ │ │ ├── entry.jsx
│ │ │ ├── index.jsx
│ │ │ ├── menu.jsx
│ │ │ ├── props-schema.js
│ │ │ ├── settings.js
│ │ │ └── style.js
│ │ ├── music-player/
│ │ │ ├── classes.js
│ │ │ ├── container.jsx
│ │ │ ├── index.jsx
│ │ │ ├── player.jsx
│ │ │ ├── props-schema.js
│ │ │ ├── settings.js
│ │ │ └── style.js
│ │ ├── section/
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ ├── settings.js
│ │ │ └── style.js
│ │ ├── symbol/
│ │ │ ├── classes.js
│ │ │ ├── container.jsx
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ └── settings.js
│ │ ├── text-box/
│ │ │ ├── classes.js
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ ├── settings.js
│ │ │ └── style.js
│ │ ├── text-input/
│ │ │ ├── classes.js
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ ├── settings.js
│ │ │ └── style.js
│ │ ├── textarea/
│ │ │ ├── classes.js
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ └── settings.js
│ │ └── video/
│ │ ├── index.jsx
│ │ ├── props-schema.js
│ │ └── settings.js
│ ├── helpers/
│ │ ├── colors.js
│ │ ├── configure-store.js
│ │ ├── data-types/
│ │ │ ├── index.js
│ │ │ └── native.js
│ │ ├── displays.js
│ │ ├── ga-send.js
│ │ ├── get-element-position.js
│ │ ├── get-element-props.js
│ │ ├── get-element-style-values.js
│ │ ├── get-gravatar-image.js
│ │ ├── icons.js
│ │ ├── load-fonts.js
│ │ ├── mime-types.js
│ │ ├── parse-fields.js
│ │ ├── parse-settings.js
│ │ ├── request.js
│ │ ├── schema-filter-default-options.js
│ │ ├── schema-link-actions.js
│ │ ├── schema-static-properties.js
│ │ ├── stringify-fields.js
│ │ ├── styles-manager.js
│ │ ├── stylesheet.js
│ │ └── utils.js
│ ├── reducers/
│ │ ├── admin-menu.js
│ │ ├── display.js
│ │ ├── dnd.js
│ │ ├── fonts.js
│ │ ├── index.js
│ │ ├── media.js
│ │ ├── menu.js
│ │ ├── page-builder-actions/
│ │ │ ├── add.js
│ │ │ ├── change-animation.js
│ │ │ ├── change-children.js
│ │ │ ├── change-content.js
│ │ │ ├── change-display.js
│ │ │ ├── change-label.js
│ │ │ ├── change-position.js
│ │ │ ├── change-prop.js
│ │ │ ├── change-style.js
│ │ │ ├── duplicate.js
│ │ │ ├── element-add-schema-link.js
│ │ │ ├── element-change-schema-link-action.js
│ │ │ ├── element-remove-schema-link.js
│ │ │ ├── helpers/
│ │ │ │ ├── clone-children.js
│ │ │ │ ├── get-id.js
│ │ │ │ └── remove-children.js
│ │ │ ├── index.js
│ │ │ ├── make-dynamic.js
│ │ │ ├── move.js
│ │ │ ├── new.js
│ │ │ └── remove.js
│ │ ├── page-builder.js
│ │ ├── revisions.js
│ │ ├── schema-entry.js
│ │ ├── schema.js
│ │ ├── session.js
│ │ ├── settings.js
│ │ ├── styles.js
│ │ └── symbols.js
│ ├── routers/
│ │ ├── admin.js
│ │ ├── auth.js
│ │ └── public.js
│ ├── screens/
│ │ ├── admin/
│ │ │ ├── components/
│ │ │ │ ├── admin/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── loading/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── menu/
│ │ │ │ │ ├── content-types.jsx
│ │ │ │ │ ├── content-types.less
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── menu.jsx
│ │ │ │ │ ├── menu.less
│ │ │ │ │ ├── user.jsx
│ │ │ │ │ └── user.less
│ │ │ │ └── top-bar/
│ │ │ │ ├── actions/
│ │ │ │ │ ├── actions.jsx
│ │ │ │ │ ├── actions.less
│ │ │ │ │ ├── back.jsx
│ │ │ │ │ ├── back.less
│ │ │ │ │ ├── display.jsx
│ │ │ │ │ ├── display.less
│ │ │ │ │ ├── displays.jsx
│ │ │ │ │ ├── displays.less
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── right-menu.jsx
│ │ │ │ │ ├── right-menu.less
│ │ │ │ │ ├── statuses.jsx
│ │ │ │ │ └── statuses.less
│ │ │ │ ├── index.jsx
│ │ │ │ ├── index.less
│ │ │ │ └── tabs/
│ │ │ │ ├── index.js
│ │ │ │ ├── tab.jsx
│ │ │ │ ├── tab.less
│ │ │ │ ├── tabs.jsx
│ │ │ │ └── tabs.less
│ │ │ ├── index.js
│ │ │ ├── screens/
│ │ │ │ ├── colors/
│ │ │ │ │ ├── components/
│ │ │ │ │ │ ├── colors.jsx
│ │ │ │ │ │ ├── entry.jsx
│ │ │ │ │ │ ├── entry.less
│ │ │ │ │ │ └── list.jsx
│ │ │ │ │ └── index.js
│ │ │ │ ├── fonts/
│ │ │ │ │ ├── components/
│ │ │ │ │ │ ├── entry.jsx
│ │ │ │ │ │ ├── entry.less
│ │ │ │ │ │ ├── fonts.jsx
│ │ │ │ │ │ ├── list.jsx
│ │ │ │ │ │ ├── manage/
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ ├── manage.jsx
│ │ │ │ │ │ │ └── manage.less
│ │ │ │ │ │ ├── preview-text.jsx
│ │ │ │ │ │ └── preview-text.less
│ │ │ │ │ └── index.js
│ │ │ │ ├── media/
│ │ │ │ │ ├── components/
│ │ │ │ │ │ ├── entry.jsx
│ │ │ │ │ │ ├── entry.less
│ │ │ │ │ │ ├── list.jsx
│ │ │ │ │ │ ├── media.jsx
│ │ │ │ │ │ ├── media.less
│ │ │ │ │ │ ├── menu.jsx
│ │ │ │ │ │ ├── menu.less
│ │ │ │ │ │ ├── sorting.jsx
│ │ │ │ │ │ ├── sorting.less
│ │ │ │ │ │ └── uploading/
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── item.jsx
│ │ │ │ │ │ ├── item.less
│ │ │ │ │ │ ├── uploading.jsx
│ │ │ │ │ │ └── uploading.less
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── menu.js
│ │ │ │ ├── menus/
│ │ │ │ │ ├── components/
│ │ │ │ │ │ ├── content.jsx
│ │ │ │ │ │ ├── content.less
│ │ │ │ │ │ ├── entry.jsx
│ │ │ │ │ │ ├── entry.less
│ │ │ │ │ │ ├── list.jsx
│ │ │ │ │ │ ├── menu.jsx
│ │ │ │ │ │ ├── menu.less
│ │ │ │ │ │ └── new/
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ └── new.jsx
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── menu.js
│ │ │ │ │ └── screens/
│ │ │ │ │ └── menu/
│ │ │ │ │ ├── components/
│ │ │ │ │ │ ├── menu-builder/
│ │ │ │ │ │ │ ├── builder.jsx
│ │ │ │ │ │ │ ├── builder.less
│ │ │ │ │ │ │ ├── collapsable.jsx
│ │ │ │ │ │ │ ├── collapsable.less
│ │ │ │ │ │ │ ├── entry.jsx
│ │ │ │ │ │ │ ├── entry.less
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ ├── link/
│ │ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ │ ├── link.jsx
│ │ │ │ │ │ │ │ └── link.less
│ │ │ │ │ │ │ ├── menu/
│ │ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ │ ├── menu.jsx
│ │ │ │ │ │ │ │ └── menu.less
│ │ │ │ │ │ │ └── pages/
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ ├── pages.jsx
│ │ │ │ │ │ │ └── pages.less
│ │ │ │ │ │ ├── menu.jsx
│ │ │ │ │ │ ├── menu.less
│ │ │ │ │ │ ├── state.jsx
│ │ │ │ │ │ └── state.less
│ │ │ │ │ └── index.js
│ │ │ │ ├── pages/
│ │ │ │ │ ├── components/
│ │ │ │ │ │ ├── entry.jsx
│ │ │ │ │ │ ├── entry.less
│ │ │ │ │ │ ├── list.jsx
│ │ │ │ │ │ ├── menu.jsx
│ │ │ │ │ │ ├── menu.less
│ │ │ │ │ │ ├── new/
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ └── new.jsx
│ │ │ │ │ │ ├── pages.jsx
│ │ │ │ │ │ └── pages.less
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── menu.js
│ │ │ │ │ └── screens/
│ │ │ │ │ └── page/
│ │ │ │ │ ├── components/
│ │ │ │ │ │ ├── info/
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ ├── info.jsx
│ │ │ │ │ │ │ ├── info.less
│ │ │ │ │ │ │ ├── item.jsx
│ │ │ │ │ │ │ └── item.less
│ │ │ │ │ │ ├── page.jsx
│ │ │ │ │ │ ├── page.less
│ │ │ │ │ │ └── revisions/
│ │ │ │ │ │ └── index.js
│ │ │ │ │ └── index.js
│ │ │ │ ├── schemas/
│ │ │ │ │ └── screens/
│ │ │ │ │ ├── new/
│ │ │ │ │ │ ├── components/
│ │ │ │ │ │ │ └── builder/
│ │ │ │ │ │ │ ├── builder.jsx
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ ├── model.jsx
│ │ │ │ │ │ │ ├── model.less
│ │ │ │ │ │ │ ├── name.jsx
│ │ │ │ │ │ │ ├── name.less
│ │ │ │ │ │ │ ├── properties/
│ │ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ │ ├── properties.jsx
│ │ │ │ │ │ │ │ ├── properties.less
│ │ │ │ │ │ │ │ ├── property-options.jsx
│ │ │ │ │ │ │ │ ├── property-options.less
│ │ │ │ │ │ │ │ ├── property.jsx
│ │ │ │ │ │ │ │ └── property.less
│ │ │ │ │ │ │ ├── type.jsx
│ │ │ │ │ │ │ ├── type.less
│ │ │ │ │ │ │ ├── types.jsx
│ │ │ │ │ │ │ └── types.less
│ │ │ │ │ │ └── index.js
│ │ │ │ │ └── schema/
│ │ │ │ │ ├── components/
│ │ │ │ │ │ ├── entry.jsx
│ │ │ │ │ │ ├── entry.less
│ │ │ │ │ │ ├── list.jsx
│ │ │ │ │ │ ├── menu.jsx
│ │ │ │ │ │ ├── menu.less
│ │ │ │ │ │ ├── new/
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ └── new.jsx
│ │ │ │ │ │ ├── schema.jsx
│ │ │ │ │ │ └── schema.less
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── menu.js
│ │ │ │ ├── settings/
│ │ │ │ │ ├── components/
│ │ │ │ │ │ ├── menu.jsx
│ │ │ │ │ │ └── menu.less
│ │ │ │ │ ├── menu.js
│ │ │ │ │ ├── screens/
│ │ │ │ │ │ ├── analytics/
│ │ │ │ │ │ │ ├── components/
│ │ │ │ │ │ │ │ └── analytics.jsx
│ │ │ │ │ │ │ └── index.js
│ │ │ │ │ │ ├── data/
│ │ │ │ │ │ │ ├── components/
│ │ │ │ │ │ │ │ └── data.jsx
│ │ │ │ │ │ │ └── index.js
│ │ │ │ │ │ ├── email/
│ │ │ │ │ │ │ ├── components/
│ │ │ │ │ │ │ │ └── email.jsx
│ │ │ │ │ │ │ └── index.js
│ │ │ │ │ │ └── general/
│ │ │ │ │ │ ├── components/
│ │ │ │ │ │ │ └── general.jsx
│ │ │ │ │ │ └── index.js
│ │ │ │ │ └── shared/
│ │ │ │ │ └── components/
│ │ │ │ │ └── settings-content/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ └── users/
│ │ │ │ ├── components/
│ │ │ │ │ ├── entry.jsx
│ │ │ │ │ ├── entry.less
│ │ │ │ │ ├── list.jsx
│ │ │ │ │ ├── new/
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ └── new.jsx
│ │ │ │ │ └── users.jsx
│ │ │ │ └── index.js
│ │ │ └── shared/
│ │ │ ├── components/
│ │ │ │ ├── balloon/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── content/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── content-displays/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── content-header/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── content-header-actions/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── content-loading/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── content-new/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── content-search/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── content-sidebar/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── editable-title/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── input-options/
│ │ │ │ │ ├── border/
│ │ │ │ │ │ ├── index.jsx
│ │ │ │ │ │ └── index.less
│ │ │ │ │ ├── border-style/
│ │ │ │ │ │ ├── index.jsx
│ │ │ │ │ │ └── index.less
│ │ │ │ │ ├── box-shadow/
│ │ │ │ │ │ ├── edit.jsx
│ │ │ │ │ │ ├── index.jsx
│ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ ├── shadow.jsx
│ │ │ │ │ │ └── shadow.less
│ │ │ │ │ ├── button/
│ │ │ │ │ │ └── index.js
│ │ │ │ │ ├── checkbox/
│ │ │ │ │ │ ├── index.jsx
│ │ │ │ │ │ └── index.less
│ │ │ │ │ ├── color/
│ │ │ │ │ │ ├── color-palette-picker.jsx
│ │ │ │ │ │ ├── color-palette-picker.less
│ │ │ │ │ │ ├── color-picker.jsx
│ │ │ │ │ │ ├── color-picker.less
│ │ │ │ │ │ ├── color.jsx
│ │ │ │ │ │ ├── color.less
│ │ │ │ │ │ ├── colors-collection.jsx
│ │ │ │ │ │ ├── colors-collection.less
│ │ │ │ │ │ ├── edit.jsx
│ │ │ │ │ │ ├── edit.less
│ │ │ │ │ │ ├── gradient-points.jsx
│ │ │ │ │ │ ├── gradient-points.less
│ │ │ │ │ │ ├── hue.jsx
│ │ │ │ │ │ ├── hue.less
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── input.jsx
│ │ │ │ │ │ ├── input.less
│ │ │ │ │ │ ├── inputs.jsx
│ │ │ │ │ │ ├── inputs.less
│ │ │ │ │ │ ├── linear-gradient.jsx
│ │ │ │ │ │ ├── linear-gradient.less
│ │ │ │ │ │ ├── opacity.jsx
│ │ │ │ │ │ ├── opacity.less
│ │ │ │ │ │ ├── radial-gradient.jsx
│ │ │ │ │ │ ├── radial-gradient.less
│ │ │ │ │ │ ├── radial-radius.jsx
│ │ │ │ │ │ ├── radial-radius.less
│ │ │ │ │ │ ├── sat-light.jsx
│ │ │ │ │ │ ├── sat-light.less
│ │ │ │ │ │ ├── types.jsx
│ │ │ │ │ │ └── types.less
│ │ │ │ │ ├── columns/
│ │ │ │ │ │ ├── column.jsx
│ │ │ │ │ │ ├── column.less
│ │ │ │ │ │ ├── columns-manager.jsx
│ │ │ │ │ │ ├── columns-manager.less
│ │ │ │ │ │ └── index.js
│ │ │ │ │ ├── combobox/
│ │ │ │ │ │ ├── index.jsx
│ │ │ │ │ │ └── index.less
│ │ │ │ │ ├── corners/
│ │ │ │ │ │ └── index.jsx
│ │ │ │ │ ├── filters/
│ │ │ │ │ │ ├── edit.jsx
│ │ │ │ │ │ ├── filter.jsx
│ │ │ │ │ │ ├── filters.jsx
│ │ │ │ │ │ └── index.js
│ │ │ │ │ ├── font/
│ │ │ │ │ │ ├── dropdown.jsx
│ │ │ │ │ │ ├── dropdown.less
│ │ │ │ │ │ ├── font-picker.jsx
│ │ │ │ │ │ ├── font-picker.less
│ │ │ │ │ │ ├── font.jsx
│ │ │ │ │ │ ├── font.less
│ │ │ │ │ │ └── index.js
│ │ │ │ │ ├── icon/
│ │ │ │ │ │ ├── icon-picker.jsx
│ │ │ │ │ │ └── index.js
│ │ │ │ │ ├── image/
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── picker.jsx
│ │ │ │ │ │ └── picker.less
│ │ │ │ │ ├── input/
│ │ │ │ │ │ ├── index.jsx
│ │ │ │ │ │ └── index.less
│ │ │ │ │ ├── menu/
│ │ │ │ │ │ └── index.js
│ │ │ │ │ ├── number/
│ │ │ │ │ │ ├── index.jsx
│ │ │ │ │ │ └── index.less
│ │ │ │ │ ├── optional/
│ │ │ │ │ │ ├── index.jsx
│ │ │ │ │ │ └── index.less
│ │ │ │ │ ├── page/
│ │ │ │ │ │ └── index.js
│ │ │ │ │ ├── rich-text/
│ │ │ │ │ │ └── index.jsx
│ │ │ │ │ ├── schema/
│ │ │ │ │ │ └── index.js
│ │ │ │ │ ├── section/
│ │ │ │ │ │ ├── index.jsx
│ │ │ │ │ │ └── index.less
│ │ │ │ │ ├── shadow-position/
│ │ │ │ │ │ ├── index.jsx
│ │ │ │ │ │ └── index.less
│ │ │ │ │ ├── sorts/
│ │ │ │ │ │ ├── edit.jsx
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── sort.jsx
│ │ │ │ │ │ └── sorts.jsx
│ │ │ │ │ ├── spacing/
│ │ │ │ │ │ ├── index.jsx
│ │ │ │ │ │ └── index.less
│ │ │ │ │ └── text-shadow/
│ │ │ │ │ ├── edit.jsx
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ ├── index.less
│ │ │ │ │ ├── shadow.jsx
│ │ │ │ │ └── shadow.less
│ │ │ │ ├── list-header/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── list-search-sort/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── media-item-preview/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── media-selector/
│ │ │ │ │ ├── entry.jsx
│ │ │ │ │ ├── entry.less
│ │ │ │ │ ├── filters.jsx
│ │ │ │ │ ├── filters.less
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── list.jsx
│ │ │ │ │ ├── list.less
│ │ │ │ │ ├── media-selector.jsx
│ │ │ │ │ ├── media-selector.less
│ │ │ │ │ ├── mock-entry.jsx
│ │ │ │ │ ├── mock-entry.less
│ │ │ │ │ ├── selected/
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── selected.jsx
│ │ │ │ │ │ └── selected.less
│ │ │ │ │ ├── sidebar.jsx
│ │ │ │ │ ├── sidebar.less
│ │ │ │ │ ├── top-bar.jsx
│ │ │ │ │ └── top-bar.less
│ │ │ │ ├── menu-button/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── menu-sub-button/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── modal/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── modal-delete/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── modal-input/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── modal-new/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── options-list/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── options-menu/
│ │ │ │ │ └── index.jsx
│ │ │ │ ├── page-builder/
│ │ │ │ │ ├── canvas/
│ │ │ │ │ │ ├── canvas.jsx
│ │ │ │ │ │ ├── canvas.less
│ │ │ │ │ │ ├── empty.jsx
│ │ │ │ │ │ ├── empty.less
│ │ │ │ │ │ └── index.js
│ │ │ │ │ ├── elements-menu/
│ │ │ │ │ │ ├── autocomplete.jsx
│ │ │ │ │ │ ├── autocomplete.less
│ │ │ │ │ │ ├── elements-menu.jsx
│ │ │ │ │ │ ├── elements-menu.less
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── list.jsx
│ │ │ │ │ │ ├── list.less
│ │ │ │ │ │ ├── search.jsx
│ │ │ │ │ │ └── search.less
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── page-builder.jsx
│ │ │ │ │ └── page-builder.less
│ │ │ │ ├── page-builder-menu/
│ │ │ │ │ ├── breadcrumbs/
│ │ │ │ │ │ ├── breadcrumbs.jsx
│ │ │ │ │ │ ├── breadcrumbs.less
│ │ │ │ │ │ ├── entry.jsx
│ │ │ │ │ │ ├── entry.less
│ │ │ │ │ │ └── index.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── menu.jsx
│ │ │ │ │ ├── menu.less
│ │ │ │ │ └── tabs/
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── layers/
│ │ │ │ │ │ ├── entry.jsx
│ │ │ │ │ │ ├── entry.less
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── layers.jsx
│ │ │ │ │ │ └── layers.less
│ │ │ │ │ ├── settings/
│ │ │ │ │ │ ├── animation.jsx
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── position.jsx
│ │ │ │ │ │ ├── props.jsx
│ │ │ │ │ │ ├── props.less
│ │ │ │ │ │ ├── settings.jsx
│ │ │ │ │ │ └── settings.less
│ │ │ │ │ ├── style/
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── style-picker/
│ │ │ │ │ │ │ ├── edit.jsx
│ │ │ │ │ │ │ ├── edit.less
│ │ │ │ │ │ │ ├── entry.jsx
│ │ │ │ │ │ │ ├── entry.less
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ ├── style-picker.jsx
│ │ │ │ │ │ │ └── style-picker.less
│ │ │ │ │ │ ├── style.jsx
│ │ │ │ │ │ └── style.less
│ │ │ │ │ ├── tab-button.jsx
│ │ │ │ │ ├── tab-button.less
│ │ │ │ │ ├── tabs.jsx
│ │ │ │ │ └── tabs.less
│ │ │ │ ├── scrollable/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── spinner/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── stick/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ └── upload/
│ │ │ │ ├── index.jsx
│ │ │ │ └── index.less
│ │ │ └── helpers/
│ │ │ └── input-options-map.js
│ │ └── auth/
│ │ ├── components/
│ │ │ └── logo/
│ │ │ ├── index.jsx
│ │ │ └── index.less
│ │ ├── index.css
│ │ ├── index.jsx
│ │ ├── screens/
│ │ │ ├── init/
│ │ │ │ ├── components/
│ │ │ │ │ └── init.jsx
│ │ │ │ └── index.js
│ │ │ └── login/
│ │ │ ├── components/
│ │ │ │ └── login.jsx
│ │ │ └── index.js
│ │ └── shared/
│ │ └── styles/
│ │ └── auth.less
│ └── styles/
│ ├── colors.less
│ ├── element.less
│ ├── normalize.less
│ ├── nucleo/
│ │ ├── index.less
│ │ ├── mini/
│ │ │ └── less/
│ │ │ ├── icons.less
│ │ │ ├── mixins.less
│ │ │ ├── nucleo-mini.less
│ │ │ └── variables.less
│ │ └── outline/
│ │ └── less/
│ │ ├── icons.less
│ │ ├── mixins.less
│ │ ├── nucleo-outline.less
│ │ └── variables.less
│ └── sizes.less
├── migrations/
│ └── .gitempty
├── package.json
├── uploads/
│ └── .gitignore
└── webpack/
├── webpack.browser.config.js
└── webpack.node.config.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .eslintrc
================================================
{
"extends": "airbnb",
"parser": "babel-eslint",
"rules": {
"object-curly-spacing": [2, "never"],
"space-before-function-paren": [2, "always"],
"comma-dangle": [2, "never"],
'max-len': [1, 115, 2, {
'ignoreUrls': true,
'ignoreComments': false
}],
"no-unused-expressions": [2, { allowShortCircuit: true }],
"no-use-before-define": [2, { "functions": false, "classes": true }],
"no-param-reassign": [2, {"props": false}],
'react/prefer-stateless-function': 0,
"consistent-return": 0,
new-cap: [2, {"capIsNewExceptions": ["ObjectId"]}],
"jsx-quotes": 0,
'react/jsx-no-bind': [2, {
'ignoreRefs': true,
'allowArrowFunctions': false,
'allowBind': false,
}],
"react/sort-comp": [2, { // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/sort-comp.md
"order": [
'lifecycle',
'everything-else',
'renderstuff'
],
"groups": {
lifecycle: [
"displayName",
"fragments",
"panelSettings",
"propTypes",
"contextTypes",
"childContextTypes",
"mixins",
"statics",
"defaultProps",
"defaultChildren",
"propsSchema",
"settings",
"style",
"constructor",
"getDefaultProps",
"getInitState",
"getChildContext",
"componentWillMount",
"componentDidMount",
"componentWillReceiveProps",
"shouldComponentUpdate",
"componentWillUpdate",
"componentDidUpdate",
"componentWillUnmount"
],
renderstuff: [
"render",
"/^render.+$/"
]
}
}]
}
}
================================================
FILE: .gitignore
================================================
# Config
.relaxrc
# Logs
logs
*.log
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Compiled binary addons (http://nodejs.org/api/addons.html)
build
build/Release
# Dependency directory
# Commenting this out is preferred by some people, see
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git-
node_modules
#Webstorm Config
.idea
# Users Environment Variables
.lock-wscript
/public/
dist/
================================================
FILE: .npmignore
================================================
.relaxrc
lib/
uploads/
build/
package.json.tmp
================================================
FILE: .relaxrc.sample
================================================
{
"port": 8080,
"devPort": 8181,
"db": {
"uri": "mongodb://localhost/relax"
}
}
================================================
FILE: LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
================================================
FILE: README.md
================================================

====================================
[](http://slack-relax.herokuapp.com/)
**IMPORTANT NOTE:** Relax isn't yet ready for production, stay tuned for releases, beta version will come soon
Support our work and help us make this the best open source CMS, be our [patreon](http://patreon.com/relax)!
Relax is a powerful new generation CMS on top of
[React](https://facebook.github.io/react/) and [Node.js](https://nodejs.org/en/)
which aims for a better way of building websites.
It features a live page builder based on components and a smart and easy way of
binding dynamic data to them.
We're currently working on releasing the beta version which should come up early 2016. If you want to collaborate in the meantime or just say anything join us at [Relax Slack](http://slack-relax.herokuapp.com/)
**You can check the demo [here](http://demo.getrelax.io/admin)**
Demo credentials:
- user: demo
- pass: demo
New design for beta release
------------
(taken from using version in master branch, demo is outdated as master isn't yet stable)




Installation
------------
### Dependencies
Relax uses [sharp](https://github.com/lovell/sharp) to resize images.
If you're using OS X, you'll need to install its libvips dependency via `brew install homebrew/science/vips`.
Full installation instructions are available [here](http://sharp.dimens.io/en/stable/install/).
You'll also need [MongoDB](https://www.mongodb.org/).
### How to Relax
Since we are yet to tag our first release, git clone this repository and run
`npm install` followed by `npm start`.
By default the application runs at port `8080`. Go ahead and visit
`http://localhost:8080/admin/init`, here you can setup the first user and you're ready to relax.
Configuration
-------------
To configure the application you can use a `.relaxrc` file. You can place it
next to the application, on any parent folder, in your `HOME` folder, etc.
You can find a sample with the default values [here](.relaxrc.sample).
Contributing
------------
### Build and start
#### Development
While in development it's convenient to keep your application running while
watching for changes, for that you can run `npm run dev`.
The application will automatically restart when needed and keep your bundles
up to date.
#### Production
To build your assets ready to go for production run `npm run build` and `npm start` to start the application.
License
-------
Relax is [GPL-3 licensed](LICENSE).
Troubleshooting
---------------
Please create [an issue](https://github.com/relax/relax/issues/new).
================================================
FILE: ROADMAP.md
================================================
Roadmap
=======
v1.0.0-Beta (Spring 2016)
-------------------------
Since the start of the project we've been through some major refactors in
order to achieve the desired stack and experience to finally have a first stable
release.
We've changed from a RESTful API into a GraphQL API, while also changing the data
architecture in the front end to include Redux.
Our first dashboard was also not designed at all because our focus was mainly on
the page builder. We're now finally tuning up the entire admin experience
so that we can make it as relaxed as possible.
Below you can find the major things that are still in the road we're going through to
reach the beta release, there are of course other minor issues that can be found
[here](https://github.com/relax/relax/milestones/1.0.0-Beta).
**What must be done:**
- [ ] Dashboard (*ongoing*) (#214)
- [ ] Settings
- [ ] Pages
- [ ] Menus
- [ ] Schemas
- [ ] Fonts
- [ ] Users
- [ ] Media
- [ ] Symbols
- [ ] Link Element
- [ ] Allow to navigate to another page
- [ ] Allow to go an absolute URL
- [ ] Allow anchoring (with sections)
- [ ] Forms
- [ ] Compose e-mail and set where the e-mail should be sent to
- [ ] Symbols Management
- [x] Manage through context menu (#208)
- [ ] Edit symbol content (#209)
- [ ] Delete symbol through context menu
- [ ] Page Templates (#133)
- [ ] Save page as template
- [ ] Use template as a schema *single* template
- [ ] Use template as a starting point to a page
- [ ] Input option types (#158)
- [ ] Schema entry *singles* (#127)
- [ ] Import/export database
- [ ] Export theme (#56)
- [ ] Export data
- [ ] Export all
- [ ] Users
- [ ] Recover password
- [ ] Change password
- [ ] Edit basic info
- [ ] Third party elements API (#55)
- [ ] Developer API Documentation (#53)
**If we have time:**
- [ ] Link forms to schemas (#124)
- [ ] User account activation
- [ ] User roles management
- [ ] Schema entry single override template (#128)
- [ ] Docker image (#213)
There are no optional issues, we really want to have everything as polished as
possible for the first release.
Feel free to create missing issues or discuss some of the features in the issues
section or with us over Slack. All help and feedback is welcome.
================================================
FILE: app.js
================================================
import 'babel-polyfill';
import mongoose from 'mongoose';
import app from './lib/server';
import config from './config';
import logger from './lib/server/logger';
import migrate from './lib/server/migrate';
// Connect mongoose
if (!config.db) {
throw new Error('Configuration to MongoDB required');
}
mongoose.connect(config.db.uri, config.db);
// Run migrations
migrate()
.then(() => {
// Start server
var server = app.listen(config.port, () => {
var port = server.address().port;
logger.debug('Listening at port', port);
});
})
.done();
================================================
FILE: config.js
================================================
var rc = require('rc');
module.exports = rc('relax', {
port: 8080,
devPort: 8181,
db: {
uri: 'mongodb://localhost/relax'
}
});
================================================
FILE: lib/client/admin.js
================================================
import 'babel-polyfill';
import routes from 'routers/admin';
import renderRoutes from './helpers/render-routes';
renderRoutes(routes);
================================================
FILE: lib/client/auth.js
================================================
import routes from 'routers/auth';
import renderRoutes from './helpers/render-routes';
renderRoutes(routes);
================================================
FILE: lib/client/helpers/render-routes.js
================================================
import configureStore from 'helpers/configure-store';
import createHistory from 'history/lib/createBrowserHistory';
import React from 'react';
import {render} from 'react-dom';
import {Provider} from 'react-redux';
import {reduxReactRouter, ReduxRouter} from 'redux-router';
export default function renderRoutes (routes) {
const state = window.__initialState;
state.router = undefined;
const store = configureStore(
reduxReactRouter({createHistory, routes}),
state
);
render(
<Provider store={store}>
<ReduxRouter routes={routes} />
</Provider>,
document.getElementById('view')
);
}
================================================
FILE: lib/client/public.js
================================================
import routes from 'routers/public';
import renderRoutes from './helpers/render-routes';
renderRoutes(routes);
================================================
FILE: lib/server/graphql/authorize.js
================================================
export default function authorize (root) {
if (!root.user) {
throw new Error('Unauthorized');
}
}
================================================
FILE: lib/server/graphql/mutations/color/add.js
================================================
import {
GraphQLNonNull
} from 'graphql';
import authorize from '../../authorize';
import colorInputType from '../../types/color-input';
import colorType from '../../types/color';
import ColorModel from '../../../models/color';
export default {
type: colorType,
args: {
data: {
name: 'data',
type: new GraphQLNonNull(colorInputType)
}
},
async resolve (root, params) {
authorize(root);
const colorModel = new ColorModel(params.data);
const color = await colorModel.save();
if (!color) {
throw new Error('Error adding new color');
}
return color;
}
};
================================================
FILE: lib/server/graphql/mutations/color/duplicate.js
================================================
import {
GraphQLNonNull,
GraphQLID
} from 'graphql';
import authorize from '../../authorize';
import colorType from '../../types/color';
import ColorModel from '../../../models/color';
export default {
type: colorType,
args: {
id: {
name: 'id',
type: new GraphQLNonNull(GraphQLID)
}
},
async resolve (root, params) {
authorize(root);
const colorToDuplicate = await ColorModel.findById(params.id).select('-_id label value').exec();
if (!colorToDuplicate) {
throw new Error('Color to duplicate could not be found!');
}
const color = new ColorModel(colorToDuplicate.toJSON());
const newColor = await color.save();
if (!newColor) {
throw new Error('Error adding new duplicate color');
}
return newColor;
}
};
================================================
FILE: lib/server/graphql/mutations/color/index.js
================================================
import addColor from './add';
import duplicateColor from './duplicate';
import removeColor from './remove';
import updateColor from './update';
export default {
addColor,
removeColor,
updateColor,
duplicateColor
};
================================================
FILE: lib/server/graphql/mutations/color/remove.js
================================================
import getProjection from 'helpers/get-projection';
import {
GraphQLNonNull,
GraphQLID
} from 'graphql';
import authorize from '../../authorize';
import colorType from '../../types/color';
import ColorModel from '../../../models/color';
export default {
type: colorType,
args: {
id: {
name: 'id',
type: new GraphQLNonNull(GraphQLID)
}
},
async resolve (root, params, options) {
authorize(root);
const removedColor = await ColorModel
.findByIdAndRemove(params.id, {
select: getProjection(options.fieldASTs[0])
})
.exec();
if (!removedColor) {
throw new Error('Color not found');
}
return removedColor;
}
};
================================================
FILE: lib/server/graphql/mutations/color/update.js
================================================
import {
GraphQLNonNull
} from 'graphql';
import getProjection from 'helpers/get-projection';
import authorize from '../../authorize';
import colorInputType from '../../types/color-input';
import colorType from '../../types/color';
import ColorModel from '../../../models/color';
export default {
type: colorType,
args: {
data: {
name: 'data',
type: new GraphQLNonNull(colorInputType)
}
},
async resolve (root, params, options) {
authorize(root);
const resultColor = await ColorModel
.findByIdAndUpdate(params.data._id, params.data, {
upsert: true,
new: true,
select: getProjection(options.fieldASTs[0])
})
.exec();
if (!resultColor) {
throw new Error('Color not found');
}
return resultColor;
}
};
================================================
FILE: lib/server/graphql/mutations/draft/drop.js
================================================
import {
GraphQLNonNull,
GraphQLString
} from 'graphql';
import {Types} from 'mongoose';
import getProjection from 'helpers/get-projection';
import authorize from '../../authorize';
import draftType from '../../types/draft';
import DraftModel from '../../../models/draft';
import PageModel from '../../../models/page';
export default {
type: draftType,
args: {
id: {
name: 'id',
type: new GraphQLNonNull(GraphQLString)
}
},
async resolve (root, params, options) {
authorize(root);
const projection = getProjection(options.fieldASTs[0]);
const _id = new Types.ObjectId(params.id);
const _userId = root.user._id;
const page = await PageModel.findById(_id);
const data = {
data: page.data,
actions: [],
__v: page.__v
};
const resultDraft = await DraftModel
.findByIdAndUpdate(
{_id, _userId},
data,
{upsert: true, new: true}
)
.select(projection)
.exec();
if (!resultDraft) {
throw new Error('Draft not found');
}
return resultDraft;
}
};
================================================
FILE: lib/server/graphql/mutations/draft/index.js
================================================
import dropDraft from './drop';
import updateDraft from './update';
export default {
dropDraft,
updateDraft
};
================================================
FILE: lib/server/graphql/mutations/draft/update.js
================================================
import getProjection from 'helpers/get-projection';
import {
GraphQLNonNull,
GraphQLID
} from 'graphql';
import {Types} from 'mongoose';
import authorize from '../../authorize';
import draftInputType from '../../types/draft-input';
import draftType from '../../types/draft';
import DraftModel from '../../../models/draft';
export default {
type: draftType,
args: {
id: {
name: 'id',
type: new GraphQLNonNull(GraphQLID)
},
data: {
name: 'data',
type: new GraphQLNonNull(draftInputType)
}
},
resolve (root, params, options) {
authorize(root);
const projection = getProjection(options.fieldASTs[0]);
const _id = new Types.ObjectId(params.id);
const _userId = root.user._id;
const data = Object.assign({}, params.data, {
data: JSON.parse(params.data.data),
actions: JSON.parse(params.data.actions)
});
delete data._id;
return DraftModel
.findByIdAndUpdate(
{_id, _userId},
data,
{upsert: true, new: true}
)
.select(projection)
.exec()
.then((resultDraft) => {
if (!resultDraft) {
throw new Error('Draft not found');
}
return resultDraft;
});
}
};
================================================
FILE: lib/server/graphql/mutations/fonts/index.js
================================================
import removeCustomFont from './remove-custom';
import submitCustomFont from './submit-custom';
import uploadFont from './upload';
export default {
removeCustomFont,
submitCustomFont,
uploadFont
};
================================================
FILE: lib/server/graphql/mutations/fonts/remove-custom.js
================================================
import path from 'path';
import rmdir from 'rimraf';
import Q from 'q';
import {
GraphQLNonNull,
GraphQLString,
GraphQLObjectType
} from 'graphql';
import authorize from '../../authorize';
export default {
type: new GraphQLObjectType({
name: 'removeCustomFont',
fields: {
id: {type: new GraphQLNonNull(GraphQLString)}
}
}),
args: {
id: {
name: 'id',
type: new GraphQLNonNull(GraphQLString)
}
},
resolve (root, params) {
authorize(root);
const id = params.id;
const fontsFolder = path.join(__dirname, '../../../../..', 'public/fonts', id);
return Q
.nfcall(rmdir, fontsFolder)
.then(() => ({
id
}))
.catch(() => {
throw new Error('Error removing custom fonts folder');
});
}
};
================================================
FILE: lib/server/graphql/mutations/fonts/submit-custom.js
================================================
import forEach from 'lodash.foreach';
import fs from 'fs';
import mkdirp from 'mkdirp';
import mongoose from 'mongoose';
import path from 'path';
import Q from 'q';
import {
GraphQLNonNull,
GraphQLString,
GraphQLList
} from 'graphql';
import authorize from '../../authorize';
import customFontType from '../../types/custom-font';
import uploadedInputType from '../../types/uploaded-input';
export default {
type: customFontType,
args: {
name: {
name: 'name',
type: new GraphQLNonNull(GraphQLString)
},
files: {
name: 'files',
type: new GraphQLNonNull(new GraphQLList(uploadedInputType))
},
types: {
name: 'types',
type: new GraphQLNonNull(new GraphQLList(GraphQLString))
}
},
resolve (root, params) {
authorize(root);
const files = params.files;
const types = params.types;
const id = mongoose.Types.ObjectId().toString();
const rootFolder = path.join(__dirname, '../../../../..');
const fontsFolder = path.join(rootFolder, 'public/fonts', id);
return Q
.nfcall(mkdirp, fontsFolder)
.then(() => {
const promises = [];
forEach(files, (file) => {
promises.push(
Q.ninvoke(
fs,
'rename',
path.join(rootFolder, file.path),
path.join(fontsFolder, file.originalname)
)
);
});
return Q.all(promises);
})
.then(() => {
// map types to file
const map = {};
for (let a = 0; a < files.length; a++) {
map[types[a]] = files[a].originalname;
}
return {
family: params.name,
id,
files: map
};
})
.catch(() => {
throw new Error('Error submiting custom fonts');
});
}
};
================================================
FILE: lib/server/graphql/mutations/fonts/upload.js
================================================
import authorize from '../../authorize';
import uploadedType from '../../types/uploaded';
export default {
type: uploadedType,
resolve (root) {
authorize(root);
return root.file;
}
};
================================================
FILE: lib/server/graphql/mutations/index.js
================================================
import color from './color';
import draft from './draft';
import fonts from './fonts';
import media from './media';
import menu from './menu';
import page from './page';
import schema from './schemas';
import schemaEntry from './schema-entry';
import settings from './settings';
import style from './style';
import symbol from './symbol';
import tab from './tab';
import user from './user';
export default {
...color,
...draft,
...fonts,
...media,
...menu,
...page,
...schemaEntry,
...schema,
...settings,
...style,
...symbol,
...tab,
...user
};
================================================
FILE: lib/server/graphql/mutations/media/add.js
================================================
import createImageThumbnail from 'helpers/create-image-thumbnail';
import fileMimetype from 'helpers/file-mimetype';
import filesize from 'file-size';
import mongoose from 'mongoose';
import path from 'path';
import writeFile from 'helpers/write-file';
import {
GraphQLNonNull
} from 'graphql';
import {getMediaType} from 'helpers/mime-types';
import authorize from '../../authorize';
import mediaInputType from '../../types/media-input';
import mediaType from '../../types/media';
import MediaModel from '../../../models/media';
export default {
type: mediaType,
args: {
data: {
name: 'data',
type: new GraphQLNonNull(mediaInputType)
}
},
async resolve (root, params) {
authorize(root);
const mediaModel = {};
const id = mongoose.Types.ObjectId();
const idStr = id.toString();
let file = params.data.file;
const mimetype = fileMimetype(file);
const relativePath = path.join('media', idStr);
const filePath = path.join('.', 'public', relativePath);
file = await writeFile(file, filePath);
// Image Upload
if (getMediaType(mimetype) === 'image') {
const {thumbnailPath, metadata} = await createImageThumbnail(
file.destPath,
filePath,
{
width: 100,
height: 100,
quality: 100
}
);
Object.assign(mediaModel, {
dimension: {
width: metadata.width,
height: metadata.height
},
thumbnail: path.join(relativePath, thumbnailPath)
});
}
// Create and save a new `MediaModel`
const media = new MediaModel(Object.assign(mediaModel, {
_id: id,
name: file.filename,
fileName: file.filename,
type: mimetype,
size: filesize(file.size).human(),
filesize: file.size,
absoluteUrl: file.destPath,
url: path.join(relativePath, file.filename)
}));
const newMedia = await media.save();
if (!newMedia) {
throw new Error('Error adding new media');
}
return newMedia;
}
};
================================================
FILE: lib/server/graphql/mutations/media/index.js
================================================
import addMedia from './add';
import removeMedia, {removeMediaItem} from './remove';
export default {
addMedia,
removeMedia,
removeMediaItem
};
================================================
FILE: lib/server/graphql/mutations/media/remove.js
================================================
import getProjection from 'helpers/get-projection';
import path from 'path';
import rmdir from 'rimraf';
import {
GraphQLNonNull,
GraphQLID,
GraphQLList
} from 'graphql';
import {all, nfcall} from 'q';
import authorize from '../../authorize';
import mediaType from '../../types/media';
import MediaModel from '../../../models/media';
const mediaPath = './public/media';
export default {
type: new GraphQLList(mediaType),
args: {
ids: {
name: 'ids',
type: new GraphQLList(new GraphQLNonNull(GraphQLID))
}
},
async resolve (root, params) {
authorize(root);
const {ids} = params;
const promises = [];
ids.forEach((id) => {
if (id) {
promises.push(nfcall(rmdir, path.join(mediaPath, id)));
}
});
await all(promises);
const removedMedia = await MediaModel.remove({
_id: {
$in: ids
}
});
return removedMedia.result.ok && ids.map(_id => ({_id})) || [];
}
};
export const removeMediaItem = {
type: mediaType,
args: {
id: {
name: 'id',
type: new GraphQLNonNull(GraphQLID)
}
},
async resolve (root, params, options) {
authorize(root);
const {id} = params;
const projection = getProjection(options.fieldASTs[0]);
await nfcall(rmdir, path.join(mediaPath, id));
const removedMedia = await MediaModel
.findByIdAndRemove(id)
.select(projection)
.exec();
return removedMedia;
}
};
================================================
FILE: lib/server/graphql/mutations/menu/add.js
================================================
import {
GraphQLNonNull
} from 'graphql';
import authorize from '../../authorize';
import menuInputType from '../../types/menu-input';
import menuType from '../../types/menu';
import MenuModel from '../../../models/menu';
export default {
type: menuType,
args: {
data: {
name: 'data',
type: new GraphQLNonNull(menuInputType)
}
},
async resolve (root, params) {
authorize(root);
const data = Object.assign(
{
data: {}
},
params.data
);
const menuModel = new MenuModel(data);
const menu = await menuModel.save();
if (!menu) {
throw new Error('Error adding menu');
}
return menu;
}
};
================================================
FILE: lib/server/graphql/mutations/menu/index.js
================================================
import addMenu from './add';
import removeMenu from './remove';
import updateMenu from './update';
export default {
addMenu,
removeMenu,
updateMenu
};
================================================
FILE: lib/server/graphql/mutations/menu/remove.js
================================================
import {
GraphQLNonNull,
GraphQLID
} from 'graphql';
import authorize from '../../authorize';
import menuType from '../../types/menu';
import MenuModel from '../../../models/menu';
export default {
type: menuType,
args: {
id: {
name: 'id',
type: new GraphQLNonNull(GraphQLID)
}
},
resolve (root, params) {
authorize(root);
return MenuModel
.findByIdAndRemove(params.id)
.exec()
.then((removedMenu) => {
if (!removedMenu) {
throw new Error('Error removing menu');
}
return removedMenu;
});
}
};
================================================
FILE: lib/server/graphql/mutations/menu/update.js
================================================
import getProjection from 'helpers/get-projection';
import {
GraphQLNonNull
} from 'graphql';
import authorize from '../../authorize';
import menuInputType from '../../types/menu-input';
import menuType from '../../types/menu';
import MenuModel from '../../../models/menu';
export default {
type: menuType,
args: {
data: {
name: 'data',
type: new GraphQLNonNull(menuInputType)
}
},
resolve (root, params, options) {
authorize(root);
const projection = getProjection(options.fieldASTs[0]);
const menuChanges = Object.assign({}, params.data);
const id = params.data._id;
// data hidrate
if (params.data.data && typeof params.data.data === 'string') {
menuChanges.data = JSON.parse(params.data.data);
}
return MenuModel
.findByIdAndUpdate(
id,
menuChanges,
{upsert: true, new: true}
)
.select(projection)
.exec()
.then((resultMenu) => {
if (!resultMenu) {
throw new Error('Menu not found');
}
return resultMenu;
});
}
};
================================================
FILE: lib/server/graphql/mutations/page/add.js
================================================
import getUniqueSlug from 'helpers/get-unique-slug';
import {
GraphQLNonNull
} from 'graphql';
import authorize from '../../authorize';
import pageInputType from '../../types/page-input';
import pageType from '../../types/page';
import PageModel from '../../../models/page';
export default {
type: pageType,
args: {
data: {
name: 'data',
type: new GraphQLNonNull(pageInputType)
}
},
async resolve (root, params) {
authorize(root);
const pageData = Object.assign({}, params.data);
// Generate slug if needed
if (!pageData.slug) {
pageData.slug = await getUniqueSlug(PageModel, pageData.title);
}
// Add user info
pageData.createdBy = root.user._id;
pageData.updatedBy = root.user._id;
const pageModel = new PageModel(pageData);
const page = await pageModel.save();
if (!page) {
throw new Error('Error creating page');
}
return page;
}
};
================================================
FILE: lib/server/graphql/mutations/page/duplicate.js
================================================
import {
GraphQLNonNull,
GraphQLString
} from 'graphql';
import authorize from '../../authorize';
import pageType from '../../types/page';
import PageModel from '../../../models/page';
function getUniqueSlug (slug, it) {
const sufix = it > 0 ? `-${it}` : '';
const resultSlug = `${slug}${sufix}`;
return PageModel
.findOne({slug: resultSlug})
.exec()
.then((response) => {
let result;
if (!response) {
result = resultSlug;
} else {
result = getUniqueSlug(slug, it + 1);
}
return result;
});
}
export default {
type: pageType,
args: {
data: {
name: 'data',
type: new GraphQLNonNull(GraphQLString)
}
},
async resolve (root, params) {
authorize(root);
let page = await PageModel.findById(params.data);
if (!page) {
throw new Error('Page to duplicate not found');
}
page = page.toJSON();
const slug = await getUniqueSlug(`${page.slug}-copy`, 0);
page.slug = slug;
page.title += ' (copy)';
page.state = 'draft';
delete page._id;
delete page.date;
delete page.actions;
const pageModel = new PageModel(page);
const newPage = await pageModel.save();
if (!newPage) {
throw new Error('Error duplicating page');
}
return newPage;
}
};
================================================
FILE: lib/server/graphql/mutations/page/index.js
================================================
import addPage from './add';
import duplicatePage from './duplicate';
import removePage from './remove';
import restorePage from './restore';
import updatePage from './update';
export default {
addPage,
duplicatePage,
removePage,
restorePage,
updatePage
};
================================================
FILE: lib/server/graphql/mutations/page/remove.js
================================================
import {
GraphQLNonNull,
GraphQLID
} from 'graphql';
import authorize from '../../authorize';
import pageType from '../../types/page';
import PageModel from '../../../models/page';
import RevisionModel from '../../../models/revision';
import TabModel from '../../../models/tab';
export default {
type: pageType,
args: {
id: {
name: 'id',
type: new GraphQLNonNull(GraphQLID)
}
},
async resolve (root, params) {
authorize(root);
const removedPage = await PageModel.findByIdAndRemove(params.id).exec();
if (!removedPage) {
throw new Error('Page not found');
}
await TabModel.find({'_id._id': params.id}).remove().exec();
await RevisionModel.find({'_id._id': params.id}).remove().exec();
return removedPage;
}
};
================================================
FILE: lib/server/graphql/mutations/page/restore.js
================================================
import {
GraphQLNonNull,
GraphQLID,
GraphQLInt
} from 'graphql';
import authorize from '../../authorize';
import pageType from '../../types/page';
import updatePageMutation from './update';
import RevisionModel from '../../../models/revision';
export default {
type: pageType,
args: {
pageId: {
name: 'pageId',
type: new GraphQLNonNull(GraphQLID)
},
version: {
name: 'version',
type: new GraphQLNonNull(GraphQLInt)
}
},
async resolve (root, params, options) {
authorize(root);
const {pageId: _id, version: __v} = params;
const revision = await RevisionModel.findOne({
'_id._id': _id,
'_id.__v': __v
}).exec();
return await updatePageMutation.resolve(root, {data: revision.doc}, options);
}
};
================================================
FILE: lib/server/graphql/mutations/page/update.js
================================================
import {
GraphQLNonNull
} from 'graphql';
import getProjection from 'helpers/get-projection';
import authorize from '../../authorize';
import pageInputType from '../../types/page-input';
import pageType from '../../types/page';
import PageModel from '../../../models/page';
import RevisionModel from '../../../models/revision';
export default {
type: pageType,
args: {
data: {
name: 'data',
type: new GraphQLNonNull(pageInputType)
}
},
async resolve (root, params, options) {
authorize(root);
const projection = getProjection(options.fieldASTs[0]);
const page = await PageModel.findById(params.data._id);
const revision = new RevisionModel({
_id: {
_id: page._id,
__v: page.__v
},
date: page.updatedDate,
user: page.updatedBy,
doc: page
});
await revision.save();
const pageChanges = Object.assign({}, params.data, {
__v: page.__v + 1,
updatedDate: new Date()
});
if (params.data.data && typeof params.data.data === 'string') {
pageChanges.data = JSON.parse(params.data.data);
}
const resultPage = await PageModel.findByIdAndUpdate(
params.data._id,
pageChanges,
{upsert: true, new: true}
).select(projection).exec();
if (!resultPage) {
throw new Error('Error updating page');
}
return resultPage;
}
};
================================================
FILE: lib/server/graphql/mutations/schema-entry/add.js
================================================
import getUniqueSlug from 'helpers/get-unique-slug';
import parseFields from 'helpers/parse-fields';
import {
GraphQLNonNull,
GraphQLID
} from 'graphql';
import authorize from '../../authorize';
import schemaEntryInputType from '../../types/schema-entry-input';
import schemaEntryModel from '../../../models/schema-entry';
import schemaEntryType from '../../types/schema-entry';
const parsableFields = ['data', 'properties'];
export default {
type: schemaEntryType,
args: {
schemaId: {
name: 'schemaId',
type: GraphQLID
},
data: {
name: 'data',
type: new GraphQLNonNull(schemaEntryInputType)
}
},
async resolve (root, params) {
authorize(root);
const Model = await schemaEntryModel(params.schemaId);
const data = parseFields(Object.assign({}, params.data), parsableFields);
// generate slug
if (!data.slug) {
data.slug = await getUniqueSlug(Model, data.title);
}
const schemaEntry = new Model(data);
const newSchemaEntry = await schemaEntry.save();
if (!newSchemaEntry) {
throw new Error('Error creating schema entry');
}
return newSchemaEntry;
}
};
================================================
FILE: lib/server/graphql/mutations/schema-entry/index.js
================================================
import addSchemaEntry from './add';
import removeSchemaEntry from './remove';
import restoreSchemaEntry from './restore';
import updateSchemaEntry from './update';
export default {
addSchemaEntry,
removeSchemaEntry,
restoreSchemaEntry,
updateSchemaEntry
};
================================================
FILE: lib/server/graphql/mutations/schema-entry/remove.js
================================================
import {
GraphQLNonNull,
GraphQLID
} from 'graphql';
import authorize from '../../authorize';
import schemaEntryModel from '../../../models/schema-entry';
import schemaEntryType from '../../types/schema-entry';
export default {
type: schemaEntryType,
args: {
schemaId: {
name: 'schemaId',
type: GraphQLID
},
id: {
name: 'id',
type: new GraphQLNonNull(GraphQLID)
}
},
async resolve (root, params) {
authorize(root);
const Model = await schemaEntryModel(params.schemaId);
const removedSchemaEntry = await Model.findByIdAndRemove(params.id).exec();
if (!removedSchemaEntry) {
throw new Error('Schema entry not found');
}
return removedSchemaEntry;
}
};
================================================
FILE: lib/server/graphql/mutations/schema-entry/restore.js
================================================
import {
GraphQLNonNull,
GraphQLID,
GraphQLInt
} from 'graphql';
import authorize from '../../authorize';
import schemaEntryType from '../../types/schema-entry';
import updateSchemaEntryMutation from './update';
import RevisionModel from '../../../models/revision';
export default {
type: schemaEntryType,
args: {
schemaId: {
name: 'schemaId',
type: GraphQLID
},
schemaEntryId: {
name: 'schemaEntryId',
type: new GraphQLNonNull(GraphQLID)
},
version: {
name: 'version',
type: new GraphQLNonNull(GraphQLInt)
}
},
async resolve (root, params, options) {
authorize(root);
const {schemaEntryId: _id, version: __v} = params;
const revision = await RevisionModel.findOne({
'_id._id': _id,
'_id.__v': __v
}).exec();
return await updateSchemaEntryMutation.resolve(
root,
{schemaId: params.schemaId, data: revision.doc},
options
);
}
};
================================================
FILE: lib/server/graphql/mutations/schema-entry/update.js
================================================
import getProjection from 'helpers/get-projection';
import parseFields from 'helpers/parse-fields';
import {
GraphQLNonNull,
GraphQLID
} from 'graphql';
import authorize from '../../authorize';
import schemaEntryInputType from '../../types/schema-entry-input';
import schemaEntryModel from '../../../models/schema-entry';
import schemaEntryType from '../../types/schema-entry';
import RevisionModel from '../../../models/revision';
const parsableFields = ['data', 'properties'];
export default {
type: schemaEntryType,
args: {
schemaId: {
name: 'schemaId',
type: GraphQLID
},
data: {
name: 'data',
type: new GraphQLNonNull(schemaEntryInputType)
}
},
async resolve (root, params, options) {
authorize(root);
const projection = getProjection(options.fieldASTs[0]);
const Model = await schemaEntryModel(params.schemaId);
const schemaEntry = await Model.findById(params.data._id);
const revision = new RevisionModel({
_id: {
_id: schemaEntry._id,
__v: schemaEntry.__v
},
date: schemaEntry.updatedDate,
user: schemaEntry.updatedBy,
doc: schemaEntry
});
await revision.save();
const schemaEntryChanges = parseFields(Object.assign({}, params.data, {
__v: schemaEntry.__v + 1,
updatedDate: new Date()
}), parsableFields);
const resultSchemaEntry = await Model.findByIdAndUpdate(
params.data._id,
schemaEntryChanges,
{upsert: true, new: true}
).select(projection).exec();
if (!resultSchemaEntry) {
throw new Error('Error updating schemaEntry');
}
return resultSchemaEntry;
}
};
================================================
FILE: lib/server/graphql/mutations/schemas/add.js
================================================
import getUniqueSlug from 'helpers/get-unique-slug';
import {
GraphQLNonNull
} from 'graphql';
import authorize from '../../authorize';
import schemaInputType from '../../types/schema-input';
import schemaType from '../../types/schema';
import SchemaModel from '../../../models/schema';
export default {
type: schemaType,
args: {
data: {
name: 'data',
type: new GraphQLNonNull(schemaInputType)
}
},
async resolve (root, params) {
authorize(root);
const data = Object.assign({}, params.data, {
properties: JSON.parse(params.data.properties)
});
// generate slug
if (!data.slug) {
data.slug = await getUniqueSlug(SchemaModel, data.title);
}
const schema = new SchemaModel(data);
const newSchema = await schema.save();
if (!newSchema) {
throw new Error('Error adding schema');
}
return newSchema;
}
};
================================================
FILE: lib/server/graphql/mutations/schemas/index.js
================================================
import addSchema from './add';
import removeSchema from './remove';
import restoreSchema from './restore';
import updateSchema from './update';
export default {
addSchema,
removeSchema,
restoreSchema,
updateSchema
};
================================================
FILE: lib/server/graphql/mutations/schemas/remove.js
================================================
import {
GraphQLNonNull,
GraphQLString
} from 'graphql';
import authorize from '../../authorize';
import schemaType from '../../types/schema';
import SchemaModel from '../../../models/schema';
export default {
type: schemaType,
args: {
id: {
name: 'id',
type: new GraphQLNonNull(GraphQLString)
}
},
async resolve (root, params) {
authorize(root);
const removedSchema = await SchemaModel.findByIdAndRemove(params.id);
if (!removedSchema) {
throw new Error('Schema not found');
}
return removedSchema;
}
};
================================================
FILE: lib/server/graphql/mutations/schemas/restore.js
================================================
import {
GraphQLNonNull,
GraphQLID,
GraphQLInt
} from 'graphql';
import authorize from '../../authorize';
import schemaType from '../../types/schema';
import updateSchemaMutation from './update';
import RevisionModel from '../../../models/revision';
export default {
type: schemaType,
args: {
schemaId: {
name: 'schemaId',
type: new GraphQLNonNull(GraphQLID)
},
version: {
name: 'version',
type: new GraphQLNonNull(GraphQLInt)
}
},
async resolve (root, params, options) {
authorize(root);
const {schemaId: _id, version: __v} = params;
const revision = await RevisionModel.findOne({
'_id._id': _id,
'_id.__v': __v
}).exec();
return await updateSchemaMutation.resolve(root, {data: revision.doc}, options);
}
};
================================================
FILE: lib/server/graphql/mutations/schemas/update.js
================================================
import {
GraphQLNonNull
} from 'graphql';
import getProjection from 'helpers/get-projection';
import authorize from '../../authorize';
import schemaInputType from '../../types/schema-input';
import schemaType from '../../types/schema';
import RevisionModel from '../../../models/revision';
import SchemaModel from '../../../models/schema';
export default {
type: schemaType,
args: {
data: {
name: 'data',
type: new GraphQLNonNull(schemaInputType)
}
},
async resolve (root, params, options) {
authorize(root);
const projection = getProjection(options.fieldASTs[0]);
const schema = await SchemaModel.findById(params.data._id);
const revision = new RevisionModel({
_id: {
_id: schema._id,
__v: schema.__v
},
date: schema.updatedDate,
user: schema.updatedBy,
doc: schema
});
await revision.save();
const schemaChanges = Object.assign({}, params.data, {
__v: schema.__v + 1,
updatedDate: new Date()
});
if (params.data.data && typeof params.data.data === 'string') {
schemaChanges.data = JSON.parse(params.data.data);
}
if (params.data.properties && typeof params.data.properties === 'string') {
schemaChanges.properties = JSON.parse(params.data.properties);
}
const resultSchema = await SchemaModel.findByIdAndUpdate(
params.data._id,
schemaChanges,
{upsert: true, new: true}
).select(projection).exec();
if (!resultSchema) {
throw new Error('Error updating schema');
}
return resultSchema;
}
};
================================================
FILE: lib/server/graphql/mutations/settings/index.js
================================================
import saveSettings from './save';
export default {
saveSettings
};
================================================
FILE: lib/server/graphql/mutations/settings/save.js
================================================
import forEach from 'lodash.foreach';
import getProjection from 'helpers/get-projection';
import Q from 'q';
import {
GraphQLNonNull,
GraphQLList
} from 'graphql';
import authorize from '../../authorize';
import settingInputType from '../../types/setting-input';
import settingType from '../../types/setting';
import SettingModel from '../../../models/setting';
export default {
type: new GraphQLList(settingType),
args: {
data: {
name: 'data',
type: new GraphQLNonNull(
new GraphQLList(settingInputType)
)
}
},
resolve (root, params, options) {
authorize(root);
const projection = getProjection(options.fieldASTs[0]);
const promises = [];
forEach(params.data, (setting) => {
promises.push(
SettingModel.findByIdAndUpdate(setting._id, setting, {upsert: true, new: true}).select(projection)
);
});
return Q
.all(promises)
.spread((...settings) => settings);
}
};
================================================
FILE: lib/server/graphql/mutations/style/add.js
================================================
import parseFields from 'helpers/parse-fields';
import {
GraphQLNonNull
} from 'graphql';
import authorize from '../../authorize';
import parsableFields from './parsable-fields';
import styleInputType from '../../types/style-input';
import styleType from '../../types/style';
import StyleModel from '../../../models/style';
export default {
type: styleType,
args: {
data: {
name: 'data',
type: new GraphQLNonNull(styleInputType)
}
},
async resolve (root, params) {
authorize(root);
const data = parseFields(params.data, parsableFields);
const styleModel = new StyleModel(data);
const style = await styleModel.save();
if (!style) {
throw new Error('Style not found');
}
return style;
}
};
================================================
FILE: lib/server/graphql/mutations/style/index.js
================================================
import addStyle from './add';
import removeStyle from './remove';
import updateStyle from './update';
export default {
addStyle,
removeStyle,
updateStyle
};
================================================
FILE: lib/server/graphql/mutations/style/parsable-fields.js
================================================
export default ['options', 'displayOptions'];
================================================
FILE: lib/server/graphql/mutations/style/remove.js
================================================
import getProjection from 'helpers/get-projection';
import {
GraphQLNonNull,
GraphQLID
} from 'graphql';
import authorize from '../../authorize';
import styleType from '../../types/style';
import StyleModel from '../../../models/style';
export default {
type: styleType,
args: {
_id: {
name: '_id',
type: new GraphQLNonNull(GraphQLID)
}
},
async resolve (root, params, options) {
authorize(root);
const removedStyle = await StyleModel
.findByIdAndRemove(params._id, {
select: getProjection(options.fieldASTs[0])
})
.exec();
if (!removedStyle) {
throw new Error('Style not found');
}
return removedStyle;
}
};
================================================
FILE: lib/server/graphql/mutations/style/update.js
================================================
import getProjection from 'helpers/get-projection';
import parseFields from 'helpers/parse-fields';
import {
GraphQLNonNull
} from 'graphql';
import authorize from '../../authorize';
import parsableFields from './parsable-fields';
import styleInputType from '../../types/style-input';
import styleType from '../../types/style';
import StyleModel from '../../../models/style';
export default {
type: styleType,
args: {
data: {
name: 'data',
type: new GraphQLNonNull(styleInputType)
}
},
async resolve (root, params, options) {
authorize(root);
const data = parseFields(params.data, parsableFields);
const resultStyle = await StyleModel
.findByIdAndUpdate(data._id, data, {
upsert: true,
new: true,
select: getProjection(options.fieldASTs[0])
})
.exec();
if (!resultStyle) {
throw new Error('Style not found');
}
return resultStyle;
}
};
================================================
FILE: lib/server/graphql/mutations/symbol/add.js
================================================
import {
GraphQLNonNull
} from 'graphql';
import authorize from '../../authorize';
import symbolInputType from '../../types/symbol-input';
import symbolType from '../../types/symbol';
import SymbolModel from '../../../models/symbol';
export default {
type: symbolType,
args: {
data: {
name: 'data',
type: new GraphQLNonNull(symbolInputType)
}
},
async resolve (root, params) {
authorize(root);
const data = Object.assign({}, params.data, {
data: JSON.parse(params.data.data)
});
const symbolModel = new SymbolModel(data);
const newSymbol = await symbolModel.save();
if (!newSymbol) {
throw new Error('Error adding symbol');
}
return newSymbol;
}
};
================================================
FILE: lib/server/graphql/mutations/symbol/index.js
================================================
import addSymbol from './add';
export default {
addSymbol
};
================================================
FILE: lib/server/graphql/mutations/tab/add.js
================================================
import {
GraphQLNonNull,
GraphQLString,
GraphQLID
} from 'graphql';
import authorize from '../../authorize';
import tabType from '../../types/tab';
import TabModel from '../../../models/tab';
export default {
type: tabType,
args: {
type: {
name: 'type',
type: new GraphQLNonNull(GraphQLString)
},
id: {
name: 'id',
type: new GraphQLNonNull(GraphQLID)
}
},
async resolve (root, params) {
authorize(root);
const _userId = root.user._id;
const item = params.id;
const type = params.type;
let tab = await TabModel.findOne({_userId, item}).exec();
if (!tab) {
const tabModel = new TabModel({
_userId,
type,
item
});
tab = await tabModel.save();
if (!tab) {
throw new Error('Error creating tab');
}
} else {
tab = null;
}
return tab;
}
};
================================================
FILE: lib/server/graphql/mutations/tab/index.js
================================================
import addTab from './add';
import removeTab from './remove';
export default {
removeTab,
addTab
};
================================================
FILE: lib/server/graphql/mutations/tab/remove.js
================================================
import getProjection from 'helpers/get-projection';
import {
GraphQLNonNull,
GraphQLID
} from 'graphql';
import authorize from '../../authorize';
import tabType from '../../types/tab';
import TabModel from '../../../models/tab';
export default {
type: tabType,
args: {
id: {
name: 'id',
type: new GraphQLNonNull(GraphQLID)
}
},
async resolve (root, params, options) {
authorize(root);
const removedTab = await TabModel
.findByIdAndRemove(params.id, {
select: getProjection(options.fieldASTs[0])
})
.exec();
if (!removedTab) {
throw new Error('Tab not found');
}
return removedTab;
}
};
================================================
FILE: lib/server/graphql/mutations/user/add.js
================================================
import {
GraphQLNonNull
} from 'graphql';
import authorize from '../../authorize';
import userInputType from '../../types/user-input';
import userType from '../../types/user';
import UserModel from '../../../models/user';
async function registerUser (user, password) {
return new Promise((resolve, reject) => {
UserModel.register(user, password, (err) => {
if (err) {
reject(err);
}
resolve();
});
});
}
export default {
type: userType,
args: {
data: {
name: 'data',
type: new GraphQLNonNull(userInputType)
}
},
async resolve (root, params) {
const {username, name, email, password} = params.data;
const user = new UserModel({
username,
name,
email
});
const count = await UserModel.count();
if (count > 0) {
authorize(root);
}
await registerUser(user, password);
return user;
}
};
================================================
FILE: lib/server/graphql/mutations/user/index.js
================================================
import addUser from './add';
import removeUser from './remove';
export default {
addUser,
removeUser
};
================================================
FILE: lib/server/graphql/mutations/user/remove.js
================================================
import {
GraphQLNonNull,
GraphQLID
} from 'graphql';
import authorize from '../../authorize';
import config from '../../../../../config';
import userType from '../../types/user';
import UserModel from '../../../models/user';
export default {
type: userType,
args: {
id: {
name: 'id',
type: new GraphQLNonNull(GraphQLID)
}
},
resolve (root, params) {
authorize(root);
if (config.demo) {
throw new Error('Remove user is disabled on the demo');
}
return UserModel
.findByIdAndRemove(params.id)
.exec()
.then((removedUser) => {
if (!removedUser) {
throw new Error('Error removing user');
}
return removedUser;
});
}
};
================================================
FILE: lib/server/graphql/queries/color/colors.js
================================================
import getProjection from 'helpers/get-projection';
import {
GraphQLList
} from 'graphql';
import colorType from '../../types/color';
import ColorModel from '../../../models/color';
export default {
type: new GraphQLList(colorType),
args: {},
resolve (root, params, options) {
const projection = getProjection(options.fieldASTs[0]);
return ColorModel.find().select(projection).exec();
}
};
================================================
FILE: lib/server/graphql/queries/color/index.js
================================================
import colors from './colors';
export default {
colors
};
================================================
FILE: lib/server/graphql/queries/draft/draft.js
================================================
import getProjection from 'helpers/get-projection';
import {
GraphQLID
} from 'graphql';
import {Types} from 'mongoose';
import authorize from '../../authorize';
import draftType from '../../types/draft';
import DraftModel from '../../../models/draft';
import PageModel from '../../../models/page';
export default {
type: draftType,
args: {
id: {
name: 'id',
type: GraphQLID
}
},
async resolve (root, params, options) {
authorize(root);
const projection = getProjection(options.fieldASTs[0]);
const _id = new Types.ObjectId(params.id);
const _userId = root.user._id;
let result = await DraftModel.findById({_id, _userId}).select(projection).exec();
if (!result) {
const page = await PageModel.findById(_id).exec();
const draft = new DraftModel({
_id: {
_id,
_userId
},
__v: page.__v,
data: page.data
});
result = await draft.save();
}
return result;
}
};
================================================
FILE: lib/server/graphql/queries/draft/index.js
================================================
import draft from './draft';
export default {
draft
};
================================================
FILE: lib/server/graphql/queries/generators/schema-list-count.js
================================================
import authorize from '../../authorize';
import countType from '../../types/count';
import schemaEntryModel from '../../../models/schema-entry';
export default (type, schema) => ({
type: countType,
args: {},
async resolve (root) {
authorize(root);
const Model = schemaEntryModel(schema);
const count = await Model.count({}).exec();
return {count};
}
});
================================================
FILE: lib/server/graphql/queries/generators/schema-list.js
================================================
import getProjection from 'helpers/get-projection';
import {
GraphQLList
} from 'graphql';
import authorize from '../../authorize';
import schemaEntryModel from '../../../models/schema-entry';
import {paginationQueryArgs, paginateQuery, searchQuery} from '../../query-pagination';
export default (type, schema) => ({
type: new GraphQLList(type),
args: {
...paginationQueryArgs
},
async resolve (root, params, options) {
authorize(root);
const Model = schemaEntryModel(schema);
const projection = getProjection(options.fieldASTs[0]);
const query = Model.find(searchQuery({}, params));
paginateQuery(query, params);
return await query.select(projection).exec();
}
});
================================================
FILE: lib/server/graphql/queries/index.js
================================================
import color from './color';
import draft from './draft';
import media from './media';
import menu from './menu';
import page from './page';
import revision from './revision';
import schema from './schemas';
import schemaEntry from './schema-entry';
import settings from './settings';
import style from './style';
import symbol from './symbol';
import tab from './tab';
import user from './user';
export default {
...color,
...draft,
...media,
...menu,
...page,
...revision,
...schemaEntry,
...schema,
...settings,
...style,
...symbol,
...tab,
...user
};
================================================
FILE: lib/server/graphql/queries/media/index.js
================================================
import mediaCount from './media-count';
import media, {mediaItem} from './media';
export default {
media,
mediaItem,
mediaCount
};
================================================
FILE: lib/server/graphql/queries/media/media-count.js
================================================
import {GraphQLInt} from 'graphql';
import authorize from '../../authorize';
import MediaModel from '../../../models/media';
export default {
type: GraphQLInt,
args: {},
async resolve (root) {
authorize(root);
return await MediaModel.count();
}
};
================================================
FILE: lib/server/graphql/queries/media/media.js
================================================
import getProjection from 'helpers/get-projection';
import {
GraphQLList,
GraphQLNonNull,
GraphQLID
} from 'graphql';
import authorize from '../../authorize';
import mediaType from '../../types/media';
import MediaModel from '../../../models/media';
import {paginationQueryArgs, paginateQuery, searchQuery} from '../../query-pagination';
export default {
type: new GraphQLList(mediaType),
args: {
...paginationQueryArgs
},
async resolve (root, params, options) {
authorize(root);
const projection = getProjection(options.fieldASTs[0]);
const query = MediaModel.find(searchQuery({}, params));
paginateQuery(query, params);
return query.select(projection).exec();
}
};
export const mediaItem = {
type: mediaType,
args: {
id: {
name: 'id',
type: new GraphQLNonNull(GraphQLID)
}
},
async resolve (root, params, options) {
const projection = getProjection(options.fieldASTs[0]);
const query = MediaModel.findById(params.id);
return query.select(projection).exec();
}
};
================================================
FILE: lib/server/graphql/queries/menu/index.js
================================================
import menus from './menus';
import menusCount from './menus-count';
import menu, {validateMenuSlug} from './menu';
export default {
menus,
menusCount,
menu,
validateMenuSlug
};
================================================
FILE: lib/server/graphql/queries/menu/menu.js
================================================
import getProjection from 'helpers/get-projection';
import {
GraphQLString,
GraphQLID,
GraphQLNonNull,
GraphQLBoolean
} from 'graphql';
import authorize from '../../authorize';
import menuType from '../../types/menu';
import MenuModel from '../../../models/menu';
export default {
type: menuType,
args: {
_id: {
name: '_id',
type: GraphQLID
}
},
async resolve (root, params, options) {
authorize(root);
const projection = getProjection(options.fieldASTs[0]);
return await MenuModel.findById(params._id).select(projection).exec();
}
};
export const validateMenuSlug = {
type: GraphQLBoolean,
args: {
slug: {
name: 'slug',
type: new GraphQLNonNull(GraphQLString)
},
menuId: {
name: 'menuId',
type: GraphQLID
}
},
async resolve (root, {slug, menuId}) {
authorize(root);
return await MenuModel.count({
slug,
_id: {
$ne: menuId
}
}) === 0;
}
};
================================================
FILE: lib/server/graphql/queries/menu/menus-count.js
================================================
import {GraphQLInt} from 'graphql';
import authorize from '../../authorize';
import MenuModel from '../../../models/menu';
export default {
type: GraphQLInt,
args: {},
async resolve (root) {
authorize(root);
return await MenuModel.count();
}
};
================================================
FILE: lib/server/graphql/queries/menu/menus.js
================================================
import getProjection from 'helpers/get-projection';
import {
GraphQLList
} from 'graphql';
import authorize from '../../authorize';
import menuType from '../../types/menu';
import MenuModel from '../../../models/menu';
import {paginationQueryArgs, paginateQuery, searchQuery} from '../../query-pagination';
export default {
type: new GraphQLList(menuType),
args: {
...paginationQueryArgs
},
resolve: (root, params, options) => {
authorize(root);
const projection = getProjection(options.fieldASTs[0]);
const query = MenuModel.find(searchQuery({}, params));
paginateQuery(query, params);
return query.select(projection).exec();
}
};
================================================
FILE: lib/server/graphql/queries/page/index.js
================================================
import pages from './pages';
import pagesCount from './pages-count';
import page, {validatePageSlug} from './page';
export default {
pages,
pagesCount,
page,
validatePageSlug
};
================================================
FILE: lib/server/graphql/queries/page/page.js
================================================
import getProjection from 'helpers/get-projection';
import {
GraphQLString,
GraphQLBoolean,
GraphQLNonNull,
GraphQLID
} from 'graphql';
import authorize from '../../authorize';
import pageType from '../../types/page';
import PageModel from '../../../models/page';
import SettingModel from '../../../models/setting';
export default {
type: pageType,
args: {
_id: {
name: '_id',
type: GraphQLID
},
slug: {
name: 'slug',
type: GraphQLString
}
},
async resolve (root, params, options) {
const projection = getProjection(options.fieldASTs[0]);
let result = false;
if (params.slug || params._id) {
result = await PageModel.findOne(params).select(projection).exec();
} else {
const frontpage = await SettingModel.findById('frontpage').exec();
if (!frontpage) {
throw new Error('Frontpage not defined');
}
result = await PageModel.findById(frontpage.value).select(projection).exec();
}
return result;
}
};
export const validatePageSlug = {
type: GraphQLBoolean,
args: {
slug: {
name: 'slug',
type: new GraphQLNonNull(GraphQLString)
},
pageId: {
name: 'pageId',
type: GraphQLID
}
},
async resolve (root, {slug, pageId}) {
authorize(root);
return await PageModel.count({
slug,
_id: {
$ne: pageId
}
}) === 0;
}
};
================================================
FILE: lib/server/graphql/queries/page/pages-count.js
================================================
import {GraphQLInt} from 'graphql';
import PageModel from '../../../models/page';
export default {
type: GraphQLInt,
args: {},
async resolve () {
const count = PageModel.count();
return count;
}
};
================================================
FILE: lib/server/graphql/queries/page/pages.js
================================================
import getProjection from 'helpers/get-projection';
import {
GraphQLList
} from 'graphql';
import authorize from '../../authorize';
import pageType from '../../types/page';
import PageModel from '../../../models/page';
import {paginationQueryArgs, paginateQuery, searchQuery} from '../../query-pagination';
export default {
type: new GraphQLList(pageType),
args: {
...paginationQueryArgs
},
resolve (root, params, options) {
authorize(root);
const projection = getProjection(options.fieldASTs[0]);
const query = PageModel.find(searchQuery({}, params));
paginateQuery(query, params);
return query.select(projection).exec();
}
};
================================================
FILE: lib/server/graphql/queries/revision/index.js
================================================
import revisions from './revisions';
export default {
revisions
};
================================================
FILE: lib/server/graphql/queries/revision/revisions.js
================================================
import getProjection from 'helpers/get-projection';
import {
GraphQLList,
GraphQLString
} from 'graphql';
import {Types} from 'mongoose';
import authorize from '../../authorize';
import revisionType from '../../types/revision';
import RevisionModel from '../../../models/revision';
export default {
type: new GraphQLList(revisionType),
args: {
id: {
name: 'id',
type: GraphQLString
}
},
async resolve (root, params, options) {
authorize(root);
const id = new Types.ObjectId(params.id);
const projection = getProjection(options.fieldASTs[0]);
return await RevisionModel
.find({
'_id._id': id
})
.sort({'_id.__v': -1})
.select(projection)
.exec();
}
};
================================================
FILE: lib/server/graphql/queries/schema-entry/index.js
================================================
import schemaList from './schema-list';
import schemaListCount from './schema-list-count';
import schemaEntry, {validateSchemaEntrySlug} from './schema-entry';
export default {
schemaEntry,
validateSchemaEntrySlug,
schemaList,
schemaListCount
};
================================================
FILE: lib/server/graphql/queries/schema-entry/schema-entry.js
================================================
import getProjection from 'helpers/get-projection';
import {
GraphQLString,
GraphQLBoolean,
GraphQLNonNull,
GraphQLID
} from 'graphql';
import authorize from '../../authorize';
import schemaEntryModel from '../../../models/schema-entry';
import schemaEntryType from '../../types/schema-entry';
export default {
type: schemaEntryType,
args: {
id: {
name: 'id',
type: GraphQLID
},
schemaId: {
name: 'schemaId',
type: GraphQLID
}
},
async resolve (root, {schemaId, id}, options) {
const Model = await schemaEntryModel(schemaId);
const projection = getProjection(options.fieldASTs[0]);
return await Model.findById(id).select(projection).exec();
}
};
export const validateSchemaEntrySlug = {
type: GraphQLBoolean,
args: {
slug: {
name: 'slug',
type: new GraphQLNonNull(GraphQLString)
},
schemaId: {
name: 'schemaId',
type: GraphQLID
},
schemaEntryId: {
name: 'schemaEntryId',
type: GraphQLID
}
},
async resolve (root, {slug, schemaId, schemaEntryId}) {
authorize(root);
const Model = await schemaEntryModel(schemaId);
return await Model.count({
slug,
_id: {
$ne: schemaEntryId
}
}) === 0;
}
};
================================================
FILE: lib/server/graphql/queries/schema-entry/schema-list-count.js
================================================
import {
GraphQLID,
GraphQLInt
} from 'graphql';
import authorize from '../../authorize';
import schemaEntryModel from '../../../models/schema-entry';
export default {
type: GraphQLInt,
args: {
schemaId: {
name: 'schemaId',
type: GraphQLID
}
},
async resolve (root, params) {
authorize(root);
const Model = await schemaEntryModel(params.schemaId);
return await Model.count().exec();
}
};
================================================
FILE: lib/server/graphql/queries/schema-entry/schema-list.js
================================================
import getProjection from 'helpers/get-projection';
import {
GraphQLList,
GraphQLID
} from 'graphql';
import authorize from '../../authorize';
import schemaEntryModel from '../../../models/schema-entry';
import schemaEntryType from '../../types/schema-entry';
import {paginationQueryArgs, paginateQuery, searchQuery} from '../../query-pagination';
export default {
type: new GraphQLList(schemaEntryType),
args: {
schemaId: {
name: 'schemaId',
type: GraphQLID
},
...paginationQueryArgs
},
async resolve (root, params, options) {
authorize(root);
const Model = await schemaEntryModel(params.schemaId);
const projection = getProjection(options.fieldASTs[0]);
const query = Model.find(searchQuery({}, params));
paginateQuery(query, params);
return await query.select(projection).exec();
}
};
================================================
FILE: lib/server/graphql/queries/schemas/index.js
================================================
import schemas from './schemas';
import schemasCount from './schemas-count';
import schema, {validateSchemaSlug} from './schema';
export default {
schemas,
schemasCount,
schema,
validateSchemaSlug
};
================================================
FILE: lib/server/graphql/queries/schemas/schema.js
================================================
import getProjection from 'helpers/get-projection';
import {
GraphQLString,
GraphQLBoolean,
GraphQLNonNull,
GraphQLID
} from 'graphql';
import authorize from '../../authorize';
import schemaType from '../../types/schema';
import SchemaModel from '../../../models/schema';
export default {
type: schemaType,
args: {
_id: {
name: '_id',
type: GraphQLID
},
slug: {
name: 'slug',
type: GraphQLString
}
},
async resolve (root, params, options) {
const projection = getProjection(options.fieldASTs[0]);
return await SchemaModel.findOne(params).select(projection).exec();
}
};
export const validateSchemaSlug = {
type: GraphQLBoolean,
args: {
slug: {
name: 'slug',
type: new GraphQLNonNull(GraphQLString)
},
schemaId: {
name: 'schemaId',
type: GraphQLID
}
},
async resolve (root, {slug, schemaId}) {
authorize(root);
return await SchemaModel.count({
slug,
_id: {
$ne: schemaId
}
}) === 0;
}
};
================================================
FILE: lib/server/graphql/queries/schemas/schemas-count.js
================================================
import {GraphQLInt} from 'graphql';
import authorize from '../../authorize';
import SchemaModel from '../../../models/schema';
export default {
type: GraphQLInt,
args: {},
async resolve (root) {
authorize(root);
return await SchemaModel.count();
}
};
================================================
FILE: lib/server/graphql/queries/schemas/schemas.js
================================================
import getProjection from 'helpers/get-projection';
import {
GraphQLList
} from 'graphql';
import authorize from '../../authorize';
import schemaType from '../../types/schema';
import SchemaModel from '../../../models/schema';
import {paginationQueryArgs, paginateQuery, searchQuery} from '../../query-pagination';
export default {
type: new GraphQLList(schemaType),
args: {
...paginationQueryArgs
},
resolve (root, params, options) {
authorize(root);
const projection = getProjection(options.fieldASTs[0]);
const query = SchemaModel.find(searchQuery({}, params));
paginateQuery(query, params);
return query.select(projection).exec();
}
};
================================================
FILE: lib/server/graphql/queries/settings/index.js
================================================
import settings from './settings';
export default {
settings
};
================================================
FILE: lib/server/graphql/queries/settings/settings.js
================================================
import getProjection from 'helpers/get-projection';
import {
GraphQLList,
GraphQLString
} from 'graphql';
import authorize from '../../authorize';
import settingType from '../../types/setting';
import SettingModel from '../../../models/setting';
export default {
type: new GraphQLList(settingType),
args: {
ids: {
name: 'ids',
type: new GraphQLList(GraphQLString)
}
},
resolve: (root, params, options) => {
authorize(root);
const projection = getProjection(options.fieldASTs[0]);
return SettingModel
.find({
_id: {$in: params.ids}
})
.select(projection)
.exec();
}
};
================================================
FILE: lib/server/graphql/queries/style/index.js
================================================
import styles from './styles';
export default {
styles
};
================================================
FILE: lib/server/graphql/queries/style/styles.js
================================================
import getProjection from 'helpers/get-projection';
import {
GraphQLList
} from 'graphql';
import styleType from '../../types/style';
import StyleModel from '../../../models/style';
export default {
type: new GraphQLList(styleType),
args: {},
resolve (root, params, options) {
const projection = getProjection(options.fieldASTs[0]);
return StyleModel.find().select(projection).exec();
}
};
================================================
FILE: lib/server/graphql/queries/symbol/index.js
================================================
import symbol from './symbol';
import symbols from './symbols';
export default {
symbol,
symbols
};
================================================
FILE: lib/server/graphql/queries/symbol/symbol.js
================================================
import getProjection from 'helpers/get-projection';
import {GraphQLID} from 'graphql';
import {Types} from 'mongoose';
import symbolType from '../../types/symbol';
import SymbolModel from '../../../models/symbol';
export default {
type: symbolType,
args: {
id: {
name: 'id',
type: GraphQLID
}
},
resolve (root, params, options) {
const projection = getProjection(options.fieldASTs[0]);
const _id = new Types.ObjectId(params.id);
return SymbolModel.findById(_id).select(projection).exec();
}
};
================================================
FILE: lib/server/graphql/queries/symbol/symbols.js
================================================
import getProjection from 'helpers/get-projection';
import {GraphQLList} from 'graphql';
import symbolType from '../../types/symbol';
import SymbolModel from '../../../models/symbol';
export default {
type: new GraphQLList(symbolType),
args: {},
resolve (root, params, options) {
const projection = getProjection(options.fieldASTs[0]);
return SymbolModel.find().select(projection).exec();
}
};
================================================
FILE: lib/server/graphql/queries/tab/index.js
================================================
import tabs from './tabs';
export default {
tabs
};
================================================
FILE: lib/server/graphql/queries/tab/tabs.js
================================================
import getProjection from 'helpers/get-projection';
import {GraphQLList} from 'graphql';
import authorize from '../../authorize';
import tabType from '../../types/tab';
import TabModel from '../../../models/tab';
export default {
type: new GraphQLList(tabType),
args: {},
resolve (root, params, options) {
authorize(root);
const _userId = root.user._id;
const projection = getProjection(options.fieldASTs[0]);
return TabModel
.find({_userId})
.select(projection)
.exec();
}
};
================================================
FILE: lib/server/graphql/queries/user/index.js
================================================
import session from './session';
import user from './user';
import users from './users';
import usersCount from './users-count';
export default {
user,
users,
usersCount,
session
};
================================================
FILE: lib/server/graphql/queries/user/session.js
================================================
import {GraphQLBoolean} from 'graphql';
export default {
type: GraphQLBoolean,
resolve (root) {
return root.isAuthenticated;
}
};
================================================
FILE: lib/server/graphql/queries/user/user.js
================================================
import getProjection from 'helpers/get-projection';
import {GraphQLID} from 'graphql';
import authorize from '../../authorize';
import userType from '../../types/user';
import UserModel from '../../../models/user';
export default {
type: userType,
args: {
id: {
name: 'username',
type: GraphQLID
}
},
resolve (root, params, options) {
authorize(root);
const projection = getProjection(options.fieldASTs[0]);
let id = params.id;
if (!id) {
id = root.user._id;
}
return UserModel
.findById(id)
.select(projection)
.exec();
}
};
================================================
FILE: lib/server/graphql/queries/user/users-count.js
================================================
import {GraphQLInt} from 'graphql';
import authorize from '../../authorize';
import UserModel from '../../../models/user';
export default {
type: GraphQLInt,
args: {},
async resolve (root) {
authorize(root);
return await UserModel.count();
}
};
================================================
FILE: lib/server/graphql/queries/user/users.js
================================================
import getProjection from 'helpers/get-projection';
import {GraphQLList} from 'graphql';
import authorize from '../../authorize';
import userType from '../../types/user';
import UserModel from '../../../models/user';
import {paginationQueryArgs, paginateQuery, searchQuery} from '../../query-pagination';
export default {
type: new GraphQLList(userType),
args: {
...paginationQueryArgs
},
resolve (root, params, options) {
authorize(root);
const projection = getProjection(options.fieldASTs[0]);
const query = UserModel.find(searchQuery({}, params));
paginateQuery(query, params);
return query.select(projection).exec();
}
};
================================================
FILE: lib/server/graphql/query-pagination.js
================================================
import forEach from 'lodash.foreach';
import {
GraphQLString,
GraphQLInt,
GraphQLList
} from 'graphql';
import filterType from './types/filter';
export const paginationQueryArgs = {
sort: {
name: 'sort',
type: GraphQLString
},
order: {
name: 'order',
type: GraphQLString
},
limit: {
name: 'limit',
type: GraphQLInt
},
filters: {
name: 'filters',
type: new GraphQLList(filterType)
},
page: {
name: 'page',
type: GraphQLInt
},
search: {
name: 'search',
type: GraphQLString
},
s: {
name: 's',
type: GraphQLString
}
};
function parseFilterOperation (op) {
const result = {};
forEach(op, (value, key) => {
result[`$${key}`] = value;
});
return result;
}
export function searchQuery (find, params) {
const and = [];
// Search
if (params.search && params.s) {
and.push({
[params.search]: new RegExp(`.*${params.s}`, 'i')
});
}
// Filters
if (params.filters && params.filters.constructor === Array) {
forEach(params.filters, (filter) => {
and.push({
[filter.property]: parseFilterOperation(filter.op)
});
});
}
// apply and operator with all the filters
if (and.length > 0) {
Object.assign(find, {
$and: and
});
}
return find;
}
export function paginateQuery (query, params) {
if (params.sort) {
query.sort({
[params.sort]: params.order || 'asc'
});
}
if (params.page && params.limit) {
query.skip((params.page - 1) * params.limit);
}
if (params.limit) {
query.limit(params.limit);
}
}
================================================
FILE: lib/server/graphql/types/color-input.js
================================================
import {
GraphQLInputObjectType,
GraphQLString,
GraphQLID
} from 'graphql';
const colorInputType = new GraphQLInputObjectType({
name: 'ColorInput',
fields: {
_id: {type: GraphQLID},
label: {type: GraphQLString},
value: {type: GraphQLString}
}
});
export default colorInputType;
================================================
FILE: lib/server/graphql/types/color.js
================================================
import {
GraphQLObjectType,
GraphQLNonNull,
GraphQLString,
GraphQLID
} from 'graphql';
const colorType = new GraphQLObjectType({
name: 'Color',
fields: {
_id: {type: new GraphQLNonNull(GraphQLID)},
label: {type: GraphQLString},
value: {type: GraphQLString}
}
});
export default colorType;
================================================
FILE: lib/server/graphql/types/count.js
================================================
import {
GraphQLObjectType,
GraphQLInt
} from 'graphql';
const countType = new GraphQLObjectType({
name: 'Count',
fields: {
count: {type: GraphQLInt}
}
});
export default countType;
================================================
FILE: lib/server/graphql/types/custom-font.js
================================================
import {
GraphQLObjectType,
GraphQLString,
GraphQLNonNull
} from 'graphql';
const customFontType = new GraphQLObjectType({
name: 'CustomFont',
fields: {
family: {
type: new GraphQLNonNull(GraphQLString)
},
id: {
type: new GraphQLNonNull(GraphQLString)
},
files: {
type: new GraphQLObjectType({
name: 'CustomFontFiles',
fields: {
eot: {type: new GraphQLNonNull(GraphQLString)},
woff2: {type: GraphQLString},
woff: {type: new GraphQLNonNull(GraphQLString)},
ttf: {type: new GraphQLNonNull(GraphQLString)}
}
})
}
}
});
export default customFontType;
================================================
FILE: lib/server/graphql/types/draft-id-input.js
================================================
import {
GraphQLInputObjectType,
GraphQLString
} from 'graphql';
export default new GraphQLInputObjectType({
name: 'DraftIdInput',
fields: {
_id: {
type: GraphQLString
},
_userId: {
type: GraphQLString
}
}
});
================================================
FILE: lib/server/graphql/types/draft-id.js
================================================
import {
GraphQLObjectType,
GraphQLNonNull,
GraphQLString
} from 'graphql';
export default new GraphQLObjectType({
name: 'DraftId',
fields: {
_id: {
type: new GraphQLNonNull(GraphQLString)
},
_userId: {
type: new GraphQLNonNull(GraphQLString)
}
}
});
================================================
FILE: lib/server/graphql/types/draft-input.js
================================================
import {
GraphQLInputObjectType,
GraphQLString,
GraphQLInt
} from 'graphql';
import draftIdInputType from './draft-id-input';
const draftInputType = new GraphQLInputObjectType({
name: 'DraftInput',
fields: {
_id: {
type: draftIdInputType
},
__v: {
type: GraphQLInt
},
data: {
type: GraphQLString
},
actions: {
type: GraphQLString
},
schemaLinks: {
type: GraphQLString
}
}
});
export default draftInputType;
================================================
FILE: lib/server/graphql/types/draft.js
================================================
import {
GraphQLObjectType,
GraphQLNonNull,
GraphQLString,
GraphQLInt
} from 'graphql';
import draftIdType from './draft-id';
export default new GraphQLObjectType({
name: 'Draft',
fields: {
_id: {
type: new GraphQLNonNull(draftIdType)
},
__v: {
type: GraphQLInt
},
data: {
type: GraphQLString,
resolve: (draft) => JSON.stringify(draft.data)
},
actions: {
type: GraphQLString,
resolve: (draft) => JSON.stringify(draft.actions)
},
schemaLinks: {
type: GraphQLString,
resolve: (draft) => JSON.stringify(draft.schemaLinks)
}
}
});
================================================
FILE: lib/server/graphql/types/filter.js
================================================
import {
GraphQLInputObjectType,
GraphQLNonNull,
GraphQLString,
GraphQLList
} from 'graphql';
const filterType = new GraphQLInputObjectType({
name: 'Filter',
fields: {
property: {
type: new GraphQLNonNull(GraphQLString)
},
op: {
type: new GraphQLInputObjectType({
name: 'FilterOp',
fields: {
eq: {type: GraphQLString},
in: {type: new GraphQLList(GraphQLString)}
}
})
}
}
});
export default filterType;
================================================
FILE: lib/server/graphql/types/generators/schema-entry-input.js
================================================
import forEach from 'lodash.foreach';
import {
GraphQLInputObjectType,
GraphQLNonNull,
GraphQLString,
GraphQLInt,
GraphQLID
} from 'graphql';
import {TypesNativeGraphQL} from 'helpers/data-types/native';
export default (schema) => {
const propertiesFields = {};
forEach(schema.properties, (property) => {
if (TypesNativeGraphQL[property.type]) {
const native = TypesNativeGraphQL[property.type];
propertiesFields[property.id] = Object.assign({}, native);
}
});
return new GraphQLInputObjectType({
name: `rlx_${schema.slug}_input`,
fields: {
_id: {type: new GraphQLNonNull(GraphQLID)},
title: {type: GraphQLString},
slug: {type: GraphQLString},
__v: {type: GraphQLInt},
state: {type: GraphQLString},
date: {
type: GraphQLInt,
resolve: () => Date.now()
},
updatedDate: {
type: GraphQLInt,
resolve: () => Date.now()
},
updatedBy: {type: GraphQLID},
createdBy: {type: GraphQLID},
data: {type: GraphQLString},
...propertiesFields
}
});
};
================================================
FILE: lib/server/graphql/types/generators/schema-entry.js
================================================
import forEach from 'lodash.foreach';
import {
GraphQLObjectType,
GraphQLNonNull,
GraphQLString,
GraphQLInt,
GraphQLID
} from 'graphql';
import {TypesNativeGraphQL} from 'helpers/data-types/native';
import userType from '../user';
import UserModel from '../../../models/user';
export default (schema) => {
const propertiesFields = {};
forEach(schema.properties, (property) => {
if (TypesNativeGraphQL[property.type]) {
const native = TypesNativeGraphQL[property.type];
propertiesFields[property.id] = Object.assign({}, native);
}
});
return new GraphQLObjectType({
name: `rlx_${schema.slug}`,
fields: {
_id: {type: new GraphQLNonNull(GraphQLID)},
title: {type: GraphQLString},
slug: {type: new GraphQLNonNull(GraphQLString)},
__v: {type: GraphQLInt},
state: {type: GraphQLString},
date: {
type: GraphQLInt,
resolve ({date}) {
return date && date.getTime();
}
},
updatedDate: {
type: GraphQLInt,
resolve ({updatedDate}) {
return updatedDate && updatedDate.getTime();
}
},
updatedBy: {
type: userType,
async resolve (schemaEntry) {
return await UserModel.findById(schemaEntry.updatedBy).exec();
}
},
createdBy: {
type: userType,
async resolve (schemaEntry) {
return await UserModel.findById(schemaEntry.createdBy).exec();
}
},
data: {
type: GraphQLString,
resolve (schemaEntry) {
return JSON.stringify(schemaEntry.data);
}
},
...propertiesFields
}
});
};
================================================
FILE: lib/server/graphql/types/media-input.js
================================================
import {
GraphQLInputObjectType,
GraphQLString,
GraphQLNonNull
} from 'graphql';
const mediaInputType = new GraphQLInputObjectType({
name: 'MediaInput',
fields: {
file: {
type: new GraphQLInputObjectType({
name: 'MediaInputFile',
fields: {
file: {type: new GraphQLNonNull(GraphQLString)},
filename: {type: new GraphQLNonNull(GraphQLString)}
}
})
}
}
});
export default mediaInputType;
================================================
FILE: lib/server/graphql/types/media.js
================================================
import {
GraphQLObjectType,
GraphQLNonNull,
GraphQLString,
GraphQLInt,
GraphQLFloat,
GraphQLID
} from 'graphql';
const mediaType = new GraphQLObjectType({
name: 'Media',
fields: {
_id: {type: new GraphQLNonNull(GraphQLID)},
name: {type: new GraphQLNonNull(GraphQLString)},
fileName: {type: new GraphQLNonNull(GraphQLString)},
type: {type: new GraphQLNonNull(GraphQLString)},
size: {type: new GraphQLNonNull(GraphQLString)},
filesize: {type: new GraphQLNonNull(GraphQLString)},
dimension: {
type: new GraphQLObjectType({
name: 'MediaDimension',
fields: {
width: {type: GraphQLInt},
height: {type: GraphQLInt}
}
})
},
url: {type: new GraphQLNonNull(GraphQLString)},
absoluteUrl: {type: new GraphQLNonNull(GraphQLString)},
date: {
type: GraphQLFloat,
resolve: ({date}) => (date && date.getTime())
},
thumbnail: {type: GraphQLString},
variations: {
type: GraphQLString,
resolve (media) {
return JSON.stringify(media.variations);
}
}
}
});
export default mediaType;
================================================
FILE: lib/server/graphql/types/menu-data.js
================================================
import getProjection from 'helpers/get-projection';
import {
GraphQLObjectType,
GraphQLString,
GraphQLID,
GraphQLList
} from 'graphql';
import pageType from './page';
import PageModel from '../../models/page';
const menuDataType = new GraphQLObjectType({
name: 'MenuData',
fields: () => ({
id: {type: GraphQLID},
type: {type: GraphQLString},
page: {
type: pageType,
resolve (menuData, params, options) {
const projection = getProjection(options.fieldASTs[0]);
return PageModel
.findById(menuData.page)
.select(projection)
.exec();
}
},
link: {
type: new GraphQLObjectType({
name: 'MenuDataLink',
fields: {
url: {type: GraphQLString},
label: {type: GraphQLString}
}
})
},
children: {
type: new GraphQLList(menuDataType)
}
})
});
export default menuDataType;
================================================
FILE: lib/server/graphql/types/menu-input.js
================================================
import {
GraphQLInputObjectType,
GraphQLString,
GraphQLFloat,
GraphQLID
} from 'graphql';
const menuInputType = new GraphQLInputObjectType({
name: 'MenuInput',
fields: {
_id: {type: GraphQLID},
title: {type: GraphQLString},
date: {
type: GraphQLFloat,
resolve: () => Date.now()
},
updatedDate: {
type: GraphQLFloat,
resolve: () => Date.now()
},
updatedBy: {type: GraphQLString},
createdBy: {type: GraphQLString},
data: {type: GraphQLString}
}
});
export default menuInputType;
================================================
FILE: lib/server/graphql/types/menu.js
================================================
import {
GraphQLObjectType,
GraphQLNonNull,
GraphQLString,
GraphQLFloat,
GraphQLID
} from 'graphql';
import userType from './user';
import UserModel from '../../models/user';
const menuType = new GraphQLObjectType({
name: 'Menu',
fields: {
_id: {type: new GraphQLNonNull(GraphQLID)},
title: {type: GraphQLString},
date: {
type: GraphQLFloat,
resolve ({date}) {
return date && date.getTime();
}
},
updatedDate: {
type: GraphQLFloat,
resolve ({updatedDate}) {
return updatedDate && updatedDate.getTime();
}
},
updatedBy: {
type: userType,
resolve (menu) {
return UserModel.findById(menu.updatedBy).exec();
}
},
createdBy: {
type: userType,
resolve (menu) {
return UserModel.findById(menu.createdBy).exec();
}
},
data: {
type: GraphQLString,
resolve ({data}) {
// TODO fetch needed data from nodes
return JSON.stringify(data);
}
}
}
});
export default menuType;
================================================
FILE: lib/server/graphql/types/page-input.js
================================================
import {
GraphQLInputObjectType,
GraphQLString,
GraphQLInt,
GraphQLFloat,
GraphQLID
} from 'graphql';
const pageInputType = new GraphQLInputObjectType({
name: 'PageInput',
fields: {
_id: {type: GraphQLID},
slug: {type: GraphQLString},
__v: {type: GraphQLInt},
state: {type: GraphQLString},
date: {
type: GraphQLFloat,
resolve: () => Date.now()
},
updatedDate: {
type: GraphQLFloat,
resolve: () => Date.now()
},
title: {type: GraphQLString},
data: {type: GraphQLString},
updatedBy: {type: GraphQLID},
createdBy: {type: GraphQLID}
}
});
export default pageInputType;
================================================
FILE: lib/server/graphql/types/page.js
================================================
import {
GraphQLObjectType,
GraphQLNonNull,
GraphQLString,
GraphQLInt,
GraphQLFloat,
GraphQLID
} from 'graphql';
import userType from './user';
import UserModel from '../../models/user';
const pageType = new GraphQLObjectType({
name: 'Page',
fields: {
_id: {type: new GraphQLNonNull(GraphQLID)},
slug: {type: new GraphQLNonNull(GraphQLString)},
__v: {type: GraphQLInt},
state: {type: GraphQLString},
date: {
type: GraphQLFloat,
resolve ({date}) {
return date && date.getTime();
}
},
updatedDate: {
type: GraphQLFloat,
resolve ({updatedDate}) {
return updatedDate && updatedDate.getTime();
}
},
title: {type: GraphQLString},
data: {
type: GraphQLString,
resolve (page) {
return JSON.stringify(page.data);
}
},
updatedBy: {
type: userType,
async resolve (page) {
return await UserModel.findById(page.updatedBy).exec();
}
},
createdBy: {
type: userType,
async resolve (page) {
return await UserModel.findById(page.createdBy).exec();
}
}
}
});
export default pageType;
================================================
FILE: lib/server/graphql/types/revision.js
================================================
import {
GraphQLObjectType,
GraphQLNonNull,
GraphQLString,
GraphQLInt,
GraphQLFloat,
GraphQLID
} from 'graphql';
import userType from './user';
import UserModel from '../../models/user';
const revisionType = new GraphQLObjectType({
name: 'Revision',
fields: {
_id: {
type: new GraphQLObjectType({
name: 'RevisionId',
fields: {
_id: {type: new GraphQLNonNull(GraphQLID)},
__v: {type: new GraphQLNonNull(GraphQLInt)}
}
})
},
date: {
type: GraphQLFloat,
resolve ({date}) {
return date && date.getTime();
}
},
doc: {
type: new GraphQLNonNull(GraphQLString),
resolve (revision) {
return JSON.stringify(revision.doc);
}
},
user: {
type: userType,
async resolve (revision) {
return await UserModel.findById(revision.user).exec();
}
}
}
});
export default revisionType;
================================================
FILE: lib/server/graphql/types/schema-entry-input.js
================================================
import {
GraphQLInputObjectType,
GraphQLString,
GraphQLInt,
GraphQLFloat,
GraphQLID
} from 'graphql';
export default new GraphQLInputObjectType({
name: 'SchemaEntryInput',
fields: {
_id: {type: GraphQLID},
title: {type: GraphQLString},
slug: {type: GraphQLString},
__v: {type: GraphQLInt},
state: {type: GraphQLString},
date: {
type: GraphQLFloat,
resolve: () => Date.now()
},
updatedDate: {
type: GraphQLFloat,
resolve: () => Date.now()
},
updatedBy: {type: GraphQLID},
createdBy: {type: GraphQLID},
data: {type: GraphQLString},
properties: {type: GraphQLString}
}
});
================================================
FILE: lib/server/graphql/types/schema-entry.js
================================================
import {
GraphQLObjectType,
GraphQLNonNull,
GraphQLString,
GraphQLInt,
GraphQLFloat,
GraphQLID
} from 'graphql';
import userType from './user';
import UserModel from '../../models/user';
export default new GraphQLObjectType({
name: 'SchemaEntry',
fields: {
_id: {type: new GraphQLNonNull(GraphQLID)},
title: {type: GraphQLString},
slug: {type: new GraphQLNonNull(GraphQLString)},
__v: {type: GraphQLInt},
state: {type: GraphQLString},
date: {
type: GraphQLFloat,
resolve ({date}) {
return date && date.getTime();
}
},
publishedDate: {
type: GraphQLFloat,
resolve ({publishedDate}) {
return publishedDate && publishedDate.getTime();
}
},
updatedDate: {
type: GraphQLFloat,
resolve ({updatedDate}) {
return updatedDate && updatedDate.getTime();
}
},
updatedBy: {
type: userType,
async resolve (schemaEntry) {
return await UserModel.findById(schemaEntry.updatedBy).exec();
}
},
createdBy: {
type: userType,
async resolve (schemaEntry) {
return await UserModel.findById(schemaEntry.createdBy).exec();
}
},
data: {
type: GraphQLString,
resolve (schemaEntry) {
return JSON.stringify(schemaEntry.data);
}
},
properties: {
type: GraphQLString,
resolve (schemaEntry) {
return JSON.stringify(schemaEntry.properties);
}
}
}
});
================================================
FILE: lib/server/graphql/types/schema-input.js
================================================
import {
GraphQLInputObjectType,
GraphQLString,
GraphQLInt,
GraphQLFloat,
GraphQLID
} from 'graphql';
const schemaInputType = new GraphQLInputObjectType({
name: 'SchemaInput',
fields: {
_id: {type: GraphQLString},
__v: {type: GraphQLInt},
title: {type: GraphQLString},
slug: {type: GraphQLString},
type: {type: GraphQLString},
date: {
type: GraphQLFloat,
resolve: () => Date.now()
},
updatedDate: {
type: GraphQLFloat,
resolve: () => Date.now()
},
data: {type: GraphQLString},
schemaLinks: {type: GraphQLString},
updatedBy: {type: GraphQLID},
createdBy: {type: GraphQLID},
properties: {type: GraphQLString}
}
});
export default schemaInputType;
================================================
FILE: lib/server/graphql/types/schema.js
================================================
import {
GraphQLObjectType,
GraphQLNonNull,
GraphQLString,
GraphQLInt,
GraphQLFloat,
GraphQLID
} from 'graphql';
import userType from './user';
import UserModel from '../../models/user';
const schemaType = new GraphQLObjectType({
name: 'Schema',
fields: {
_id: {
type: new GraphQLNonNull(GraphQLID)
},
title: {
type: GraphQLString
},
slug: {
type: new GraphQLNonNull(GraphQLString)
},
type: {
type: GraphQLString
},
__v: {
type: GraphQLInt
},
date: {
type: GraphQLFloat,
resolve: ({date}) => (date && date.getTime())
},
updatedDate: {
type: GraphQLFloat,
resolve: ({updatedDate}) => (updatedDate && updatedDate.getTime())
},
data: {
type: GraphQLString,
resolve: (schema) => JSON.stringify(schema.data)
},
schemaLinks: {
type: GraphQLString,
resolve: (schema) => JSON.stringify(schema.schemaLinks)
},
updatedBy: {
type: userType,
resolve: (schema) => UserModel.findById(schema.updatedBy).exec()
},
createdBy: {
type: userType,
resolve: (schema) => UserModel.findById(schema.createdBy).exec()
},
properties: {
type: GraphQLString,
resolve: (schema) => JSON.stringify(schema.properties)
}
}
});
export default schemaType;
================================================
FILE: lib/server/graphql/types/setting-input.js
================================================
import {
GraphQLInputObjectType,
GraphQLString
} from 'graphql';
const settingInputType = new GraphQLInputObjectType({
name: 'SettingInput',
fields: {
_id: {type: GraphQLString},
value: {type: GraphQLString}
}
});
export default settingInputType;
================================================
FILE: lib/server/graphql/types/setting.js
================================================
import {
GraphQLObjectType,
GraphQLNonNull,
GraphQLString
} from 'graphql';
const settingType = new GraphQLObjectType({
name: 'Setting',
fields: {
_id: {type: new GraphQLNonNull(GraphQLString)},
value: {type: GraphQLString}
}
});
export default settingType;
================================================
FILE: lib/server/graphql/types/style-input.js
================================================
import {
GraphQLInputObjectType,
GraphQLString,
GraphQLID
} from 'graphql';
const styleInputType = new GraphQLInputObjectType({
name: 'StyleInput',
fields: {
_id: {type: GraphQLID},
title: {type: GraphQLString},
type: {type: GraphQLString},
options: {type: GraphQLString},
displayOptions: {type: GraphQLString}
}
});
export default styleInputType;
================================================
FILE: lib/server/graphql/types/style.js
================================================
import {
GraphQLObjectType,
GraphQLNonNull,
GraphQLString,
GraphQLID
} from 'graphql';
const styleType = new GraphQLObjectType({
name: 'Style',
fields: {
_id: {type: new GraphQLNonNull(GraphQLID)},
type: {type: new GraphQLNonNull(GraphQLString)},
title: {type: GraphQLString},
options: {
type: GraphQLString,
resolve (style) {
return JSON.stringify(style.options);
}
},
displayOptions: {
type: GraphQLString,
resolve (style) {
return JSON.stringify(style.displayOptions);
}
}
}
});
export default styleType;
================================================
FILE: lib/server/graphql/types/symbol-input.js
================================================
import {
GraphQLInputObjectType,
GraphQLString,
GraphQLID
} from 'graphql';
const symbolInputType = new GraphQLInputObjectType({
name: 'SymbolInput',
fields: {
_id: {type: GraphQLID},
title: {type: GraphQLString},
data: {type: GraphQLString}
}
});
export default symbolInputType;
================================================
FILE: lib/server/graphql/types/symbol.js
================================================
import {
GraphQLObjectType,
GraphQLNonNull,
GraphQLString,
GraphQLID
} from 'graphql';
const symbolType = new GraphQLObjectType({
name: 'Symbol',
fields: {
_id: {type: new GraphQLNonNull(GraphQLID)},
title: {type: GraphQLString},
data: {
type: GraphQLString,
resolve (symbol) {
return JSON.stringify(symbol.data);
}
}
}
});
export default symbolType;
================================================
FILE: lib/server/graphql/types/tab-item.js
================================================
import {
GraphQLObjectType,
GraphQLNonNull,
GraphQLString
} from 'graphql';
export default new GraphQLObjectType({
name: 'TabItem',
fields: {
_id: {
type: new GraphQLNonNull(GraphQLString)
},
title: {
type: GraphQLString
}
}
});
================================================
FILE: lib/server/graphql/types/tab.js
================================================
import {
GraphQLObjectType,
GraphQLNonNull,
GraphQLID,
GraphQLString
} from 'graphql';
import tabItemType from './tab-item';
import PageModel from '../../models/page';
export default new GraphQLObjectType({
name: 'Tab',
fields: {
_id: {
type: new GraphQLNonNull(GraphQLID)
},
_userId: {
type: GraphQLID
},
type: {
type: new GraphQLNonNull(GraphQLString)
},
item: {
type: tabItemType,
async resolve ({type, item}) {
let result = null;
if (type === 'page') {
result = await PageModel.findById(item).exec();
}
return result;
}
}
}
});
================================================
FILE: lib/server/graphql/types/uploaded-input.js
================================================
import {
GraphQLInputObjectType,
GraphQLString,
GraphQLInt
} from 'graphql';
const uploadedInputType = new GraphQLInputObjectType({
name: 'UploadedFileInput',
fields: {
originalname: {type: GraphQLString},
mimetype: {type: GraphQLString},
destination: {type: GraphQLString},
filename: {type: GraphQLString},
path: {type: GraphQLString},
size: {type: GraphQLInt}
}
});
export default uploadedInputType;
================================================
FILE: lib/server/graphql/types/uploaded.js
================================================
import {
GraphQLObjectType,
GraphQLString,
GraphQLInt
} from 'graphql';
const uploadedType = new GraphQLObjectType({
name: 'UploadedFile',
fields: {
originalname: {type: GraphQLString},
mimetype: {type: GraphQLString},
destination: {type: GraphQLString},
filename: {type: GraphQLString},
path: {type: GraphQLString},
size: {type: GraphQLInt}
}
});
export default uploadedType;
================================================
FILE: lib/server/graphql/types/user-input.js
================================================
import {
GraphQLInputObjectType,
GraphQLString,
GraphQLNonNull
} from 'graphql';
const userInputType = new GraphQLInputObjectType({
name: 'UserInput',
fields: {
_id: {type: GraphQLString},
username: {type: new GraphQLNonNull(GraphQLString)},
name: {type: GraphQLString},
password: {type: GraphQLString},
email: {type: GraphQLString},
date: {type: GraphQLString}
}
});
export default userInputType;
================================================
FILE: lib/server/graphql/types/user.js
================================================
import {
GraphQLObjectType,
GraphQLNonNull,
GraphQLString
} from 'graphql';
const userType = new GraphQLObjectType({
name: 'User',
fields: {
_id: {type: new GraphQLNonNull(GraphQLString)},
username: {type: new GraphQLNonNull(GraphQLString)},
name: {type: GraphQLString},
email: {type: GraphQLString},
date: {type: GraphQLString}
}
});
export default userType;
================================================
FILE: lib/server/index.js
================================================
import bodyParser from 'body-parser';
import connectMongo from 'connect-mongo';
import express from 'express';
import graphqlHTTP from 'express-graphql';
import mongoose from 'mongoose';
import morgan from 'morgan';
import multer from 'multer';
import parseSettings from 'helpers/parse-settings';
import passport from 'passport';
import path from 'path';
import safeHtmlString from 'helpers/safe-html-string';
import session from 'express-session';
import config from '../../config';
import middleware from './middleware';
import routers from './routers';
import schema from './schema';
import SettingModel from './models/setting';
const app = express();
app.use(morgan('short'));
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json({limit: 100000000}));
// View engine
app.set('views', path.join(__dirname, 'components'));
// session
const MongoStore = connectMongo(session);
app.use(session({
secret: 'Is very secret',
store: new MongoStore({mongooseConnection: mongoose.connection})
}));
// Passport
app.use(passport.initialize());
app.use(passport.session());
// Static files
app.use(express.static('./public'));
app.use(['favicon.ico', '/images*', '/media*', '/css*', '/fonts*', '/js*'], (req, res) => {
res.status(404).end();
});
// Multer
app.use('/graphql', multer({dest: './uploads/'}).single('file'));
// GraphqQL server
app.use('/graphql', graphqlHTTP(req => ({
schema: schema.getSchema(),
rootValue: {
isAuthenticated: req.isAuthenticated(),
user: req.user,
file: req.file
},
graphiql: true
})));
app.use(async (req, res, next) => {
const settingsArr = await SettingModel
.find({
_id: {$in: ['title', 'favicon']}
})
.exec();
const settings = parseSettings(settingsArr);
res.locals.header = [
{
tag: 'title',
content: settings.title && safeHtmlString(settings.title) || 'Relax CMS'
}
];
if (process.env.NODE_ENV !== 'production') {
res.baseScriptsURL = `http://localhost:${config.devPort}`;
res.locals.header.push({
tag: 'script',
props: {
src: `${res.baseScriptsURL}/webpack-dev-server.js`
}
});
} else {
res.baseScriptsURL = '';
}
// footer
res.locals.footer = [{
tag: 'script',
props: {
src: `${res.baseScriptsURL}/js/common.js`
}
}];
next();
});
app.use(middleware.fonts);
app.use(middleware.googleAnalytics);
app.use(routers.authRouter);
app.use(routers.adminRouter);
app.use(routers.publicRouter);
app.use((req, res) => {
res.status(404).end();
});
app.use((error, req, res) => {
const statusCode = error.statusCode || 500;
const err = {
error: statusCode,
message: error.message
};
if (!res.headersSent) {
res.status(statusCode).send(err);
}
});
export default app;
================================================
FILE: lib/server/logger.js
================================================
import winston from 'winston';
export default new winston.Logger({
transports: [
new winston.transports.Console({
level: 'debug',
handleExceptions: true,
json: false,
colorize: true
})
],
exitOnError: false
});
================================================
FILE: lib/server/middleware/fonts.js
================================================
import forEach from 'lodash.foreach';
import SettingModel from '../models/setting';
export default async (req, res, next) => {
res.locals.header.push({
tag: 'script',
props: {
src: '//ajax.googleapis.com/ajax/libs/webfont/1.5.10/webfont.js'
}
});
try {
const fontsSetting = await SettingModel.findOne({_id: 'fonts'});
if (fontsSetting && fontsSetting.value) {
const fonts = JSON.parse(fontsSetting.value);
if (fonts.customFonts) {
let css = '';
forEach(fonts.customFonts, (customFont) => {
const family = customFont.family;
const map = customFont.files;
const location = `/fonts/${customFont.id}/`;
css += `@font-face {
font-family: "${family}";
src: url("${location}${map.eot}");
src:
`;
if (map.woff2) {
css += `url("${location}${map.woff2}"), `;
}
css += `
url("${location}${map.woff}"),
url("${location}${map.ttf}");
}
`;
});
if (css !== '') {
res.locals.header.push({
tag: 'style',
props: {
type: 'text/css'
},
content: css
});
}
}
if (fonts.webfontloader) {
res.locals.header.push({
tag: 'script',
content: `WebFont.load(${JSON.stringify(fonts.webfontloader)});`
});
}
}
next();
} catch (err) {
next();
}
};
================================================
FILE: lib/server/middleware/google-analytics.js
================================================
import utils from 'helpers/utils';
import SettingModel from '../models/setting';
export default async (req, res, next) => {
res.locals.header.push({
tag: 'script',
props: {
src: '//ajax.googleapis.com/ajax/libs/webfont/1.5.10/webfont.js'
}
});
const googleAnalyticsSetting = await SettingModel
.findById('googleAnalytics')
.exec();
if (googleAnalyticsSetting &&
googleAnalyticsSetting.value &&
utils.validateGATrackingId(googleAnalyticsSetting.value)) {
res.locals.header.push({
tag: 'script',
content: `
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', '${googleAnalyticsSetting.value}', 'auto');
`
});
next();
} else {
next();
}
};
================================================
FILE: lib/server/middleware/index.js
================================================
import fonts from './fonts';
import googleAnalytics from './google-analytics';
export default {
fonts,
googleAnalytics
};
================================================
FILE: lib/server/migrate.js
================================================
import q from 'q';
import semver from 'semver';
import {readdirSync} from 'fs';
import {basename, extname, join} from 'path';
import logger from './logger';
import MigrationModel from './models/migration';
const migrationsPath = './migrations';
function saveMigration (path) {
return new MigrationModel({_id: path}).save();
}
function runMigration (path) {
const migration = require(join(migrationsPath, path));
return migration()
.then(() => saveMigration(path))
.then(() => logger.info(`migration ${path} was applied`));
}
export default function migrate () {
return q()
.then(() => {
let promise = q();
readdirSync(migrationsPath)
.map((path) => (extname(path) === '.js' ? basename(path) : false))
.filter((path) => path && semver.valid(path.split('-')[0]))
.sort((a, b) => semver.compare(a.split('-')[0], b.split('-')[0]))
.forEach((path) => {
promise = promise
.then(() => MigrationModel.findOne({_id: path}).exec())
.then((migration) => !migration && runMigration(path));
});
return promise;
});
}
================================================
FILE: lib/server/models/color.js
================================================
import mongoose from 'mongoose';
const colorSchema = new mongoose.Schema({
label: {
type: String,
required: true
},
value: {
type: String,
required: true
}
});
export default mongoose.model('Color', colorSchema);
================================================
FILE: lib/server/models/draft.js
================================================
import mongoose from 'mongoose';
const draftSchema = new mongoose.Schema({
_id: {
_id: {
type: mongoose.Schema.Types.ObjectId
},
_userId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
},
data: {
type: mongoose.Schema.Types.Mixed,
default: {}
},
actions: {
type: Array,
default: []
},
schemaLinks: {
type: mongoose.Schema.Types.Mixed,
default: {}
}
});
export default mongoose.model('Draft', draftSchema);
================================================
FILE: lib/server/models/index.js
================================================
import color from './color';
import draft from './draft';
import media from './media';
import menu from './menu';
import page from './page';
import revision from './revision';
import schema from './schema';
import setting from './setting';
import style from './style';
import tab from './tab';
import user from './user';
export default [
color,
draft,
media,
menu,
page,
revision,
schema,
setting,
style,
tab,
user
];
================================================
FILE: lib/server/models/media.js
================================================
import mongoose from 'mongoose';
const mediaSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
fileName: {
type: String,
required: true
},
type: {
type: String,
required: true
},
size: {
type: String,
required: true
},
filesize: {
type: Number,
required: true
},
dimension: {
width: {
type: Number
},
height: {
type: Number
}
},
url: {
type: String,
required: true,
unique: true
},
absoluteUrl: {
type: String,
required: true,
unique: true
},
date: {
type: Date,
default: Date.now
},
thumbnail: {
type: String
},
variations: {
type: Array
}
});
export default mongoose.model('Media', mediaSchema);
================================================
FILE: lib/server/models/menu.js
================================================
import mongoose from 'mongoose';
const menuSchema = new mongoose.Schema({
title: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
},
updatedDate: {
type: Date,
default: Date.now
},
createdBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
updatedBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
data: {}
}, {minimize: false});
export default mongoose.model('Menu', menuSchema);
================================================
FILE: lib/server/models/migration.js
================================================
import mongoose from 'mongoose';
const migrationSchema = new mongoose.Schema({
_id: {
type: String
},
when: {
type: Date,
default: Date.now
}
});
export default mongoose.model('Migration', migrationSchema);
================================================
FILE: lib/server/models/page.js
================================================
import mongoose from 'mongoose';
const pageSchema = new mongoose.Schema({
title: {
type: String,
required: true
},
slug: {
type: String,
required: true,
unique: true
},
state: {
type: String,
default: 'draft'
},
date: {
type: Date,
default: Date.now
},
updatedDate: {
type: Date,
default: Date.now
},
data: {
type: mongoose.Schema.Types.Mixed,
default: {}
},
createdBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
updatedBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
});
export default mongoose.model('Page', pageSchema);
================================================
FILE: lib/server/models/revision.js
================================================
import mongoose from 'mongoose';
const schema = new mongoose.Schema({
_id: {
_id: {
type: mongoose.Schema.Types.ObjectId,
required: true
},
__v: {
type: Number,
required: true
}
},
date: {
type: Date,
default: Date.now
},
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
doc: {
type: mongoose.Schema.Types.Mixed,
required: true
}
});
export default mongoose.model('Revision', schema);
================================================
FILE: lib/server/models/schema-entry.js
================================================
import forEach from 'lodash.foreach';
import mongoose from 'mongoose';
import {TypesNative} from 'helpers/data-types/native';
import SchemaModel from './schema';
// import tabsStore from '../stores/tabs';
// import revisionsStore from '../stores/revisions';
const models = {};
export default async (schemaId) => {
if (models[schemaId]) {
return models[schemaId];
}
const schema = await SchemaModel.findById(schemaId).exec();
const properties = {};
forEach(schema.properties, (property) => {
if (TypesNative[property.type]) {
const native = TypesNative[property.type];
properties[property.id] = {
type: native,
required: property.required
};
}
});
const mongooseSchema = {
title: {
type: String,
required: true
},
slug: {
type: String,
required: true,
unique: true
},
state: {
type: String,
default: 'draft'
},
date: {
type: Date,
default: Date.now
},
publishedDate: {
type: Date,
default: Date.now
},
updatedDate: {
type: Date,
default: Date.now
},
data: {
type: Array
},
schemaLinks: {
type: mongoose.Schema.Types.Mixed
},
overlap: {
type: Boolean,
default: false
},
createdBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
updatedBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
properties
};
const entrySchema = new mongoose.Schema(mongooseSchema, {collection: schema.slug});
// entrySchema.post('remove', (schemaEntry) => {
// tabsStore.removeMultiple({
// '_id._id': schemaEntry._id
// });
// revisionsStore.removeMultiple({
// '_id._id': schemaEntry._id
// });
// });
const model = mongoose.model(schema.slug, entrySchema);
models[schemaId] = model;
return model;
};
================================================
FILE: lib/server/models/schema.js
================================================
import mongoose from 'mongoose';
// import tabsStore from '../stores/tabs';
// import revisionsStore from '../stores/revisions';
const schemaSchema = new mongoose.Schema({
title: {
type: String,
required: true
},
slug: {
type: String,
required: true,
unique: true
},
type: {
type: String,
required: true
},
data: {
type: Array,
default: []
},
schemaLinks: {
type: mongoose.Schema.Types.Mixed,
default: {}
},
date: {
type: Date,
default: Date.now
},
updatedDate: {
type: Date,
default: Date.now
},
createdBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
updatedBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
properties: [
{
id: {
type: String,
required: true
},
title: {
type: String,
required: true
},
type: {
type: String,
required: true
},
props: {
type: mongoose.Schema.Types.Mixed,
required: false
},
default: {},
required: {
type: Boolean,
required: true,
default: false
},
dependencies: {
type: Array,
required: false
}
}
]
});
// schemaSchema.post('remove', (schema) => {
// tabsStore.removeMultiple({
// '_id._id': schema._id
// });
//
// revisionsStore.removeMultiple({
// '_id._id': schema._id
// });
// });
export default mongoose.model('Schema', schemaSchema);
================================================
FILE: lib/server/models/setting.js
================================================
import mongoose from 'mongoose';
const settingSchema = new mongoose.Schema({
_id: {
type: String
},
value: {
type: mongoose.Schema.Types.Mixed,
required: true
}
});
export default mongoose.model('Setting', settingSchema);
================================================
FILE: lib/server/models/style.js
================================================
import mongoose from 'mongoose';
const styleSchema = new mongoose.Schema({
type: {
type: String,
required: true
},
title: {
type: String,
required: true
},
options: {
type: mongoose.Schema.Types.Mixed,
required: true
},
displayOptions: {
type: mongoose.Schema.Types.Mixed
}
});
export default mongoose.model('Style', styleSchema);
================================================
FILE: lib/server/models/symbol.js
================================================
import mongoose from 'mongoose';
const symbolSchema = new mongoose.Schema({
title: {
type: String,
required: true
},
data: {
type: mongoose.Schema.Types.Mixed,
required: true
}
});
export default mongoose.model('Symbol', symbolSchema);
================================================
FILE: lib/server/models/tab.js
================================================
import mongoose from 'mongoose';
const tabSchema = new mongoose.Schema({
_userId: {
type: mongoose.Schema.Types.ObjectId
},
type: {
type: String
},
item: {
type: mongoose.Schema.Types.ObjectId
}
});
export default mongoose.model('Tab', tabSchema);
================================================
FILE: lib/server/models/user.js
================================================
import mongoose from 'mongoose';
import passport from 'passport';
import passportLocalMongoose from 'passport-local-mongoose';
import {Strategy} from 'passport-local';
const userSchema = new mongoose.Schema({
username: {
type: String,
required: true,
unique: true
},
name: {
type: String,
required: true
},
password: {
type: String
},
email: {
type: String,
unique: true,
trim: true,
required: true
},
date: {
type: Date,
default: Date.now
}
});
userSchema.plugin(passportLocalMongoose);
const UserModel = mongoose.model('User', userSchema);
passport.use(new Strategy(UserModel.authenticate()));
passport.serializeUser(UserModel.serializeUser());
passport.deserializeUser(UserModel.deserializeUser());
export default UserModel;
================================================
FILE: lib/server/routers/admin.js
================================================
import getDefaultFavicon from 'helpers/default-favicon';
import getMarkup from 'helpers/get-markup';
import routeHandler from 'helpers/route-handler';
import routes from 'routers/admin';
import {Router} from 'express';
const adminRouter = new Router();
// Restrict from here onwards
adminRouter.get('/admin*', (req, res, next) => {
if (req.isAuthenticated()) {
res.locals.footer.push({
tag: 'link',
props: {
rel: 'stylesheet',
type: 'text/css',
href: 'https://fonts.googleapis.com/css?family=Open+Sans:400,600,700'
}
});
res.locals.header.push(getDefaultFavicon(res));
if (process.env.NODE_ENV === 'production') {
res.locals.header.push({
tag: 'link',
props: {
rel: 'stylesheet',
type: 'text/css',
href: '/css/admin.css'
}
});
}
res.locals.footer.push({
tag: 'script',
props: {
src: `${res.baseScriptsURL}/js/admin.js`
}
});
next();
} else {
res.redirect('/admin/login');
}
});
adminRouter.get('/admin*', (req, res, next) => {
if (req.isAuthenticated()) {
routeHandler(routes, req, res, next);
} else {
next();
}
});
adminRouter.get('/admin*', async (req, res, next) => {
if (req.isAuthenticated() && req.routerState) {
// const AdminContainer = req.routerState.components[0];
// const PanelContainer = req.routerState.components[1];
//
// const {panelSettings, defaultQuery} = PanelContainer;
// const queryVariables = Object.assign({}, defaultQuery, req.query);
//
// const paginateQuery = getQueryVariables(queryVariables);
//
// const {query, variables} = AdminContainer.getQueryAndVariables(
// {
// params: req.routerState.params,
// queryVariables: {
// ...paginateQuery
// }
// },
// {
// ...panelSettings
// }
// );
// const username = req.session.passport.user;
// const user = await UserModel
// .findOne({username})
// .select({
// _id: 1,
// username: 1,
// name: 1,
// email: 1
// })
// .exec();
// const data = await graphql(
// schema.getSchema(),
// query,
// {
// isAuthenticated: true,
// user
// },
// variables
// );
// await req.store.dispatch({
// type: graphqlActionType,
// ...data
// });
res.status(200).send(getMarkup(req.store, res));
} else {
next();
}
});
export default adminRouter;
================================================
FILE: lib/server/routers/auth.js
================================================
import getDefaultFavicon from 'helpers/default-favicon';
import getMarkup from 'helpers/get-markup';
import passport from 'passport';
import routeHandler from 'helpers/route-handler';
import routes from 'routers/auth';
import {Router} from 'express';
import UserModel from '../models/user';
const authRouter = new Router();
function injectScript (req, res, next) {
res.locals.header.push({
tag: 'link',
props: {
rel: 'stylesheet',
type: 'text/css',
href: 'https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700'
}
});
if (process.env.NODE_ENV === 'production') {
res.locals.header.push({
tag: 'link',
props: {
rel: 'stylesheet',
type: 'text/css',
href: '/css/auth.css'
}
});
}
res.locals.header.push(getDefaultFavicon(res));
res.locals.footer.push({
tag: 'script',
props: {
src: `${res.baseScriptsURL}/js/auth.js`
}
});
next();
}
authRouter.get(/^\/admin\/(login|init)$/, (req, res, next) => {
if (req.isAuthenticated()) {
res.redirect('/admin');
} else {
routeHandler(routes, req, res, next);
}
});
// Logout
authRouter.get('/admin/logout', (req, res) => {
req.logout();
res.redirect('/admin/login');
});
// Register
authRouter.get('/admin/init', injectScript, async (req, res, next) => {
try {
const count = await UserModel.count().exec();
if (count === 0) {
res.status(200).send(getMarkup(req.store, res));
} else {
next();
}
} catch (error) {
next(error);
}
});
// Login
authRouter.get('/admin/login', injectScript, (req, res) => {
if (req.isAuthenticated()) {
res.redirect('/admin');
} else {
res.status(200).send(getMarkup(req.store, res));
}
});
authRouter.post('/admin/login', (req, res, next) => {
passport.authenticate('local', (err, user) => {
if (err) {
res.status(500).send({
error: 500,
message: err.message
});
} else if (!user) {
res.status(403).send({
error: 403,
message: 'Invalid username and password combination'
});
} else {
req.logIn(user, (error) => {
if (error) {
res.status(500).send({
error: 500,
message: error.message
});
} else {
res.status(200).end();
}
});
}
})(req, res, next);
});
export default authRouter;
================================================
FILE: lib/server/routers/index.js
================================================
import adminRouter from './admin';
import authRouter from './auth';
import publicRouter from './public';
export default {
adminRouter,
authRouter,
publicRouter
};
================================================
FILE: lib/server/routers/public.js
================================================
import find from 'lodash.find';
import forEach from 'lodash.foreach';
import getDefaultFavicon from 'helpers/default-favicon';
import getMarkup from 'helpers/get-markup';
import nodemailer from 'nodemailer';
import parseSettings from 'helpers/parse-settings';
import path from 'path';
import resizeImage from 'helpers/resize-image';
import routeHandler from 'helpers/route-handler';
import routes from 'routers/public';
import {graphql as graphqlActionType} from 'actions';
import {Router} from 'express';
import {graphql} from 'graphql';
import schema from '../schema';
import MediaModel from '../models/media';
import SettingModel from '../models/setting';
const publicRouter = new Router();
publicRouter.get('/api/media/resize/:mediaId/:width/:height', async (req, res, next) => {
try {
const {mediaId: id} = req.params;
let {width, height} = req.params;
width = parseInt(width, 10);
height = parseInt(height, 10);
const media = await MediaModel
.findById(id)
.select({
dimension: 1,
variations: 1,
fileName: 1,
absoluteUrl: 1
})
.exec();
if (!media) {
throw new Error('Media not found');
}
if (!media.dimension) {
throw new Error('Media file is not an image');
}
const relativePath = path.join('media', id);
const mediaPath = path.join('.', 'public', relativePath);
const originalRatio = media.dimension.width / media.dimension.height;
let resultWidth = Math.ceil(width / 100) * 100;
let resultHeight = resultWidth / originalRatio;
if (resultHeight < height) {
resultHeight = Math.ceil(height / 100) * 100;
resultWidth = resultHeight * originalRatio;
}
resultWidth = Math.round(resultWidth);
resultHeight = Math.round(resultHeight);
const filename = `${resultWidth}x${resultHeight}-${media.fileName}`;
const filePath = path.join(mediaPath, filename);
let variation;
// Check if variation already exists
forEach(media.variations, (_variation) => {
const {dimension: {width: _width, height: _height}} = _variation;
if (_width === resultWidth && _height === resultHeight) {
variation = _variation;
return false;
}
});
if (!variation) {
await resizeImage(media.absoluteUrl, filePath, {
width: resultWidth,
height: resultHeight,
quality: 100
});
variation = {
url: path.join(relativePath, filename),
absoluteUrl: path.join(mediaPath, filename),
dimension: {
width: resultWidth,
height: resultHeight
}
};
media.variations.push(variation);
await media.save();
}
res.sendFile(variation.absoluteUrl, {root: '.'});
} catch (error) {
next(error);
}
});
publicRouter.post('/send-email', async (req, res) => {
const settingsIds = [
'mailService',
'mailUser',
'mailPass',
'mailTo'
];
const settingsArr = await SettingModel
.find({
_id: {
$in: settingsIds
}
})
.exec();
const settings = parseSettings(settingsArr);
const formData = req.body;
let allSetup = true;
forEach(settingsIds, (id) => {
if (!settings[id]) {
allSetup = false;
return false;
}
});
if (allSetup) {
const transporter = nodemailer.createTransport({
service: settings.mailService,
auth: {
user: settings.mailUser,
pass: settings.mailPass
}
});
const mailOptions = {
from: formData.from,
to: settings.mailTo,
subject: formData.subject,
html: formData.message
};
try {
await transporter.sendMail(mailOptions);
res.status(200).send();
} catch (err) {
res.status(500).send('Error sending email');
}
} else {
res.status(500).send('Admin: setup not concluded');
}
});
publicRouter.use('/', (req, res, next) => {
res.locals.footer.push({
tag: 'script',
props: {
src: `${res.baseScriptsURL}/js/public.js`
}
});
res.locals.header.push({
tag: 'link',
props: {
rel: 'stylesheet',
type: 'text/css',
href: '/css/public.css'
}
});
routeHandler(routes, req, res, next);
});
publicRouter.use('/', async (req, res, next) => {
if (req.routerState) {
const settingsArr = await SettingModel
.find({
_id: {$in: ['favicon', 'webclip']}
})
.exec();
const settings = parseSettings(settingsArr);
let iconLink = getDefaultFavicon(res);
if (settings.favicon) {
const favicon = await MediaModel
.findById(settings.favicon)
.select('type url')
.exec();
if (favicon) {
iconLink = {
tag: 'link',
props: {
rel: 'icon',
type: favicon.type,
href: `${res.baseScriptsURL}/${favicon.url}`
}
};
}
}
res.locals.header.push(iconLink);
if (settings.webclip) {
const webclip = await MediaModel
.findById(settings.webclip)
.select('url')
.exec();
if (webclip) {
res.locals.header.push({
tag: 'link',
props: {
rel: 'apple-touch-icon',
href: `${res.baseScriptsURL}/${webclip.url}`
}
});
}
}
const PageContainer = req.routerState.components[0];
const {query, variables} = PageContainer.getQueryAndVariables(
{
params: req.routerState.params
}
);
const data = await graphql(
schema.getSchema(),
query,
{
isAuthenticated: false,
user: null
},
variables
);
if (data && data.data && data.data.page && data.data.page.title) {
const titleTag = find(res.locals.header, 'tag', 'title');
titleTag.content += ` - ${data.data.page.title}`;
}
await req.store.dispatch({
type: graphqlActionType,
...data
});
res.status(200).send(getMarkup(req.store, res));
} else {
next();
}
});
export default publicRouter;
================================================
FILE: lib/server/schema.js
================================================
import clone from 'lodash.clone';
import forEach from 'lodash.foreach';
import {
GraphQLObjectType,
GraphQLSchema
} from 'graphql';
import mutations from './graphql/mutations';
import queries from './graphql/queries';
import SchemaModel from './models/schema';
// import schemaEntryInputType from './graphql/types/generators/schema-entry-input';
// import schemaEntryType from './graphql/types/generators/schema-entry';
// import schemaListCountQuery from './graphql/queries/generators/schema-list-count';
// import schemaListQuery from './graphql/queries/generators/schema-list';
class SchemaManager {
constructor () {
this.init();
}
async init () {
this.queryFields = clone(queries);
this.mutationFields = clone(mutations);
const schemas = await SchemaModel.find().exec();
forEach(schemas, (schema) => {
this.processSchema(schema);
});
this.createRoot();
}
processSchema (/* schema */) {
// const type = schemaEntryType(schema);
// const inputType = schemaEntryInputType(schema);
//
// const schemaQueries = {
// ['rlx_' + schema.slug]: schemaListQuery(type, schema),
// ['rlx_' + schema.slug + '_count']: schemaListCountQuery(type, schema)
// };
//
// // TODO create mutations
//
// Object.assign(this.queryFields, schemaQueries);
}
createRoot () {
this.rootQuery = new GraphQLObjectType({
name: 'Query',
fields: () => (this.queryFields)
});
this.rootMutation = new GraphQLObjectType({
name: 'Mutation',
fields: () => (this.mutationFields)
});
}
getSchema () {
const schema = {
query: this.rootQuery
};
if (Object.keys(this.mutationFields).length) {
schema.mutation = this.rootMutation;
}
return new GraphQLSchema(schema);
}
}
export default new SchemaManager();
================================================
FILE: lib/server/shared/components/html.jsx
================================================
import React, {PropTypes} from 'react';
export default class Html extends React.Component {
static propTypes = {
locals: PropTypes.object,
props: PropTypes.any,
body: PropTypes.any
};
render () {
return (
<html>
<head>
{this.renderHeader()}
<meta name='viewport' content='width=device-width, initial-scale=1.0' />
</head>
<body>
<div id='view' dangerouslySetInnerHTML={{__html: this.props.body}} />
<script dangerouslySetInnerHTML={{__html: `window.__initialState = ${this.props.props};`}} />
{this.renderFooter()}
</body>
</html>
);
}
renderHeader () {
if (this.props.locals && this.props.locals.header) {
return this.props.locals.header.map(this.renderTag, this);
}
}
renderFooter () {
if (this.props.locals && this.props.locals.footer) {
return this.props.locals.footer.map(this.renderTag, this);
}
}
renderTag (tag) {
const tagProps = Object.assign({}, tag.props || {});
if (tag.content) {
tagProps.dangerouslySetInnerHTML = {__html: tag.content};
}
return (
<tag.tag {...tagProps} />
);
}
}
================================================
FILE: lib/server/shared/helpers/create-image-thumbnail.js
================================================
import path from 'path';
import sharp from 'sharp';
import {fcall, ninvoke} from 'q';
const defaultOptions = {
width: 100,
height: 100,
quality: 100
};
export default async function createImageThumbnail (imagePath, destPath, options = defaultOptions) {
const {quality, width, height} = options;
const image = await fcall(sharp, imagePath);
const metadata = await ninvoke(image, 'metadata');
const thumbnailPath = `thumbnail.${metadata.format}`;
await image
.quality(quality)
.resize(width, height)
.toFile(path.join(destPath, thumbnailPath));
return {
thumbnailPath,
metadata
};
}
================================================
FILE: lib/server/shared/helpers/default-favicon.js
================================================
export default function getDefaultIcon (res) {
return {
tag: 'link',
props: {
rel: 'shortcut icon',
type: 'image/vnd.microsoft.icon',
href: `${res.baseScriptsURL}/images/admin/favicon.ico`
}
};
}
================================================
FILE: lib/server/shared/helpers/file-mimetype.js
================================================
export default function fileMimetype (file) {
const fileData = file.file;
return fileData.substring(fileData.indexOf(':') + 1, fileData.indexOf(';'));
}
================================================
FILE: lib/server/shared/helpers/get-markup.js
================================================
import serialize from 'serialize-javascript';
import Html from 'components/html';
import React from 'react';
import {renderToString} from 'react-dom/server';
import {Provider} from 'react-redux';
import {ReduxRouter} from 'redux-router';
export default function getMarkup (store, res) {
const state = store.getState();
const initialState = serialize(state);
const markup = renderToString(
<Provider store={store}>
<ReduxRouter />
</Provider>
);
const htmlMarkup = renderToString(
<Html
body={markup}
props={initialState}
locals={res.locals}
/>
);
return htmlMarkup;
}
================================================
FILE: lib/server/shared/helpers/get-projection.js
================================================
export default function getProjection (fieldASTs) {
return fieldASTs.selectionSet.selections.reduce((projections, selection) => {
projections[selection.name.value] = 1;
return projections;
}, {});
}
================================================
FILE: lib/server/shared/helpers/get-unique-slug.js
================================================
import slugify from 'slug';
async function check (Model, slug) {
const exists = await Model.count({slug});
return {
exists,
slug
};
}
export default async (Model, str) => {
const generatedSlug = slugify(str).toLowerCase();
let result = await check(Model, generatedSlug);
if (result.exists) {
let counter = 1;
do {
result = await check(Model, `${generatedSlug}-${counter}`);
counter++;
} while (result.exists);
}
return result.slug;
};
================================================
FILE: lib/server/shared/helpers/resize-image.js
================================================
import sharp from 'sharp';
import {fcall} from 'q';
const defaultOptions = {
width: 100,
height: 100,
quality: 100
};
export default async function resizeImage (imagePath, destPath, options = defaultOptions) {
const {quality, width, height} = options;
const image = await fcall(sharp, imagePath);
image.quality(quality).resize(width, height);
await image.toFile(destPath);
}
================================================
FILE: lib/server/shared/helpers/route-handler.js
================================================
import configureStore from 'helpers/configure-store';
import {createMemoryHistory} from 'history';
import {match, reduxReactRouter} from 'redux-router/server';
export default function routeHandler (routes, req, res, next) {
const store = configureStore(reduxReactRouter({
createHistory: createMemoryHistory,
routes
}));
const url = req.originalUrl;
store.dispatch(match(url, async (error, redirectLocation, routerState) => {
if (error) {
next(error);
} else if (redirectLocation) {
res.redirect(302, redirectLocation.pathname + redirectLocation.search);
} else if (routerState) {
req.routerState = routerState;
req.store = store;
next();
} else {
res.status(404).send('Not found');
}
}));
}
================================================
FILE: lib/server/shared/helpers/safe-html-string.js
================================================
export default function safeHtmlString (str) {
return str.replace(/<\/?[^>]+(>|$)/g, '');
}
================================================
FILE: lib/server/shared/helpers/write-file.js
================================================
import fs from 'fs';
import mkdirp from 'mkdirp';
import path from 'path';
import {nfcall} from 'q';
export default async function writeFile (file, _destPath) {
let fileData = file.file;
fileData = fileData.substring(fileData.indexOf(',') + 1);
const destPath = path.join(_destPath, file.filename);
try {
await nfcall(mkdirp, _destPath);
await nfcall(fs.writeFile, destPath, fileData, 'base64');
} catch (ex) {
throw ex;
}
return {
filename: file.filename,
size: fileData.length,
destPath
};
}
================================================
FILE: lib/shared/actions/admin-menu.js
================================================
import actionTypes from 'actions';
export function openAdminMenu () {
return {
type: actionTypes.openAdminMenu
};
}
export function closeAdminMenu () {
return {
type: actionTypes.closeAdminMenu
};
}
================================================
FILE: lib/shared/actions/colors.js
================================================
import {mutation} from 'relate-js';
export function updateColor (data) {
return mutation({
fragments: {
updateColor: {
_id: 1,
label: 1,
value: 1
}
},
variables: {
updateColor: {
data: {
value: data,
type: 'ColorInput!'
}
}
}
});
}
export function addColor (data) {
return mutation({
fragments: {
addColor: {
_id: 1,
label: 1,
value: 1
}
},
variables: {
addColor: {
data: {
value: data,
type: 'ColorInput!'
}
}
}
});
}
export function duplicateColor (id) {
return mutation({
fragments: {
duplicateColor: {
_id: 1,
label: 1,
value: 1
}
},
variables: {
duplicateColor: {
id: {
value: id,
type: 'ID!'
}
}
}
});
}
export function removeColor (id) {
return mutation({
fragments: {
removeColor: {
_id: 1
}
},
variables: {
removeColor: {
id: {
value: id,
type: 'ID!'
}
}
},
type: 'REMOVE'
});
}
================================================
FILE: lib/shared/actions/display.js
================================================
import actionTypes from 'actions';
export function changeDisplay (value) {
return {
type: actionTypes.changeDisplay,
value
};
}
================================================
FILE: lib/shared/actions/dnd.js
================================================
import actionTypes from 'actions';
export function startDragging (draggingData, dragInfo) {
return {
type: actionTypes.startDragging,
draggingData,
dragInfo
};
}
export function onDroppable (dropInfo) {
return {
type: actionTypes.onDroppable,
dropInfo
};
}
export function outDroppable (id) {
return {
type: actionTypes.outDroppable,
id
};
}
export function stopDragging () {
return {
type: actionTypes.stopDragging
};
}
================================================
FILE: lib/shared/actions/draft.js
================================================
import actionTypes from 'actions';
import request from 'helpers/request';
import {mutation} from 'relate-js';
import {fragmentToQL} from 'relax-fragments';
export function saveDraft () {
return (dispatch, getState) => {
const pageBuilder = getState().pageBuilder;
const draftInput = Object.assign({}, {
data: JSON.stringify(pageBuilder.data),
actions: JSON.stringify(pageBuilder.actions)
});
return mutation({
fragments: {
updateDraft: {
_id: {
_id: 1,
_userId: 1
}
}
},
variables: {
updateDraft: {
id: {
type: 'ID!',
value: getState().router.params.id
},
data: {
type: 'DraftInput!',
value: draftInput
}
}
}
})(dispatch, getState);
};
}
export function dropDraft (fragments, id) {
return (dispatch) => (
request({
dispatch,
type: actionTypes.dropDraft,
query: `
mutation dropDraft ($id: String!) {
dropDraft (id: $id) {
${fragmentToQL(fragments.draft)}
}
}
`,
variables: {
id
}
})
);
}
================================================
FILE: lib/shared/actions/elements.js
================================================
import actionTypes from 'actions';
import request from 'helpers/request';
export function getElementData (elementId, {query, variables}) {
return (dispatch) => request({
dispatch,
type: actionTypes.getElementData,
query,
variables,
params: {
elementId
}
});
}
================================================
FILE: lib/shared/actions/fonts.js
================================================
import actionTypes from 'actions';
import loadFontsAsync from 'helpers/load-fonts';
import request from 'helpers/request';
export function changeFontsPreviewText (value) {
return {
type: actionTypes.changeFontsPreviewText,
value
};
}
export function changeFontsPreviewLayout (value) {
return {
type: actionTypes.changeFontsPreviewLayout,
value
};
}
export function changeFontInput (tab, value) {
return {
type: actionTypes.changeFontInput,
tab,
value
};
}
export function loadFonts () {
return (dispatch, getState) => (
loadFontsAsync({
dispatch,
webfontloader: getState().fonts.data.webfontloader,
type: actionTypes.loadFonts
})
);
}
export function saveFonts () {
return (dispatch, getState) => (
request({
dispatch,
type: actionTypes.saveFonts,
query: `
mutation saveSettings ($data: [SettingInput]!) {
saveSettings (data: $data) {
_id,
value
}
}
`,
variables: {
data: [{
_id: 'fonts',
value: JSON.stringify(getState().fonts.data)
}]
}
})
);
}
export function changeFontInputAndUpdate (tab, value) {
return {
types: [
'UPDATE_FONTS_START',
'UPDATE_FONTS_SUCCESS',
'UPDATE_FONTS_ERROR'
],
payload: [changeFontInput.bind(null, tab, value), loadFonts, saveFonts],
sequence: true
};
}
function _includeCustomFont () {
return (dispatch, getState) => {
const newCustom = getState().fonts.newCustom;
if (newCustom) {
const id = newCustom.id;
const map = newCustom.files;
let css = `
@font-face {
font-family: "${newCustom.family}";
src: url('/fonts/${id}/${map.eot}');
src:
`;
if (map.woff2) {
css += `url('/fonts/${id}/${map.woff2}'), `;
}
css += `
url('/fonts/${id}/${map.woff}'),
url('/fonts/${id}/${map.ttf}');
}
`;
const styleTag = document.createElement('style');
styleTag.type = 'text/css';
document.getElementsByTagName('head')[0].appendChild(styleTag);
if (styleTag.styleSheet) {
styleTag.styleSheet.cssText = css;
} else {
styleTag.appendChild(document.createTextNode(css));
}
}
dispatch({
type: actionTypes.customFontIncluded
});
};
}
function _submitCustomFont (name, files, types) {
return (dispatch) => (
request({
dispatch,
type: actionTypes.submitCustomFont,
query: `
mutation submitCustomFont ($name: String!, $files: [UploadedFileInput]!, $types: [String]!) {
submitCustomFont (name: $name, files: $files, types: $types) {
family,
id,
files {
eot,
woff2,
woff,
ttf
}
}
}
`,
variables: {
name,
files,
types
}
})
);
}
export function submitCustomFont (name, files, types) {
return {
types: [
'SUBMIT_CUSTOM_FONT_START',
'SUBMIT_CUSTOM_FONT_SUCCESS',
'SUBMIT_CUSTOM_FONT_ERROR'
],
payload: [_submitCustomFont.bind(null, name, files, types), _includeCustomFont, loadFonts, saveFonts],
sequence: true
};
}
export function _removeCustomFont (id) {
return (dispatch) => (
request({
dispatch,
type: actionTypes.removeCustomFont,
query: `
mutation removeCustomFont ($id: String!) {
removeCustomFont (id: $id) {
id
}
}
`,
variables: {
id
}
})
);
}
export function removeCustomFont (id) {
return {
types: [
'REMOVE_CUSTOM_FONT_START',
'REMOVE_CUSTOM_FONT_SUCCESS',
'REMOVE_CUSTOM_FONT_ERROR'
],
payload: [_removeCustomFont.bind(null, id), loadFonts, saveFonts],
sequence: true
};
}
================================================
FILE: lib/shared/actions/graphql.js
================================================
import actionTypes from 'actions';
import request from 'helpers/request';
export function graphql ({query, variables}, connectors) {
return (dispatch) => request({
dispatch,
type: actionTypes.graphql,
query,
variables,
params: {
connectors
}
});
}
export function removeConnector (id) {
return {
type: actionTypes.removeConnector,
id
};
}
================================================
FILE: lib/shared/actions/index.js
================================================
export default {
// Session
authenticate: 'AUTHENTICATE',
// Admin menu
openAdminMenu: 'OPEN_ADMIN_MENU',
closeAdminMenu: 'CLOSE_ADMIN_MENU',
// Colors
updateColor: 'UPDATE_COLOR',
addColor: 'ADD_COLOR',
removeColor: 'REMOVE_COLOR',
// Display
changeDisplay: 'CHANGE_DISPLAY',
// Fonts
changeFontsPreviewText: 'CHANGE_FONTS_PREVIEW_TEXT',
changeFontsPreviewLayout: 'CHANGE_FONTS_PREVIEW_LAYOUT',
changeFontInput: 'CHANGE_FONT_INPUT',
loadFonts: 'LOAD_FONTS',
saveFonts: 'SAVE_FONTS',
submitCustomFont: 'SUBMIT_CUSTOM_FONT',
removeCustomFont: 'REMOVE_CUSTOM_FONT',
customFontIncluded: 'CUSTOM_FONT_INCLUDED',
// Media
changeMediaDisplay: 'CHANGE_MEDIA_DISPLAY',
addFilesToUpload: 'ADD_MEDIA_FILES_TO_UPLOAD',
uploadingMedia: 'UPLOADING_MEDIA',
mediaUploadSuccess: 'UPLOAD_MEDIA_SUCCESS',
mediaUploadError: 'UPLOAD_MEDIA_ERROR',
addMedia: 'ADD_MEDIA',
removeMedia: 'REMOVE_MEDIA',
removeMediaItem: 'REMOVE_MEDIA_ITEM',
// Menu
addMenu: 'ADD_MENU',
addMenuItem: 'ADD_MENU_ITEM',
moveMenuItem: 'MOVE_MENU_ITEM',
removeMenu: 'REMOVE_MENU',
// Page
getPage: 'GET_PAGE',
updatePage: 'UPDATE_PAGE',
addPage: 'ADD_PAGE',
changePageFields: 'CHANGE_FIELDS',
changePageToDefault: 'CHANGE_TO_DEFAULT',
validatePageSlug: 'VALIDATE_PAGE_SLUG',
restorePage: 'RESTORE_PAGE',
savePageFromDraft: 'SAVE_PAGE_FROM_DRAFT',
// Pages
removePage: 'REMOVE_PAGE',
duplicatePage: 'DUPLICATE_PAGE',
// Schema
changeSchemaType: 'CHANGE_SCHEMA_TYPE',
changeSchemaTitle: 'CHANGE_SCHEMA_TITLE',
schemaStepBack: 'SCHEMA_STEP_BACK',
schemaStepForward: 'SCHEMA_STEP_FORWARD',
schemaAddProperty: 'SCHEMA_ADD_PROPERTY',
schemaToggleProperty: 'SCHEMA_TOGGLE_PROPERTY',
schemaChangePropertySetting: 'SCHEMA_CHANGE_PROPERTY_SETTING',
changeSchemaToDefault: 'CHANGE_SCHEMA_TO_DEFAULT',
updateSchema: 'UPDATE_SCHEMA',
addSchema: 'ADD_SCHEMA',
restoreSchema: 'RESTORE_SCHEMA',
validateSchemaSlug: 'VALIDATE_SCHEMA_SLUG',
// Schemas
removeSchema: 'REMOVE_SCHEMA',
// Schema List
removeSchemaEntry: 'REMOVE_SCHEMA_ENTRY',
// Schema entry
addSchemaEntry: 'ADD_SCHEMA_ENTRY',
updateSchemaEntry: 'UPDATE_SCHEMA_ENTRY',
restoreSchemaEntry: 'RESTORE_SCHEMA_ENTRY',
validateSchemaEntrySlug: 'VALIDATE_SCHEMA_ENTRY_SLUG',
changeSchemaEntryFields: 'CHANGE_SCHEMA_ENTRY_FIELDS',
changeSchemaEntryProperty: 'CHANGE_SCHEMA_ENTRY_PROPERTY',
changeSchemaEntryToDefault: 'CHANGE_SCHEMA_ENTRY_TO_DEFAULT',
// Settings
changeSettingValue: 'CHANGE_SETTING_VALUE',
saveSettings: 'SAVE_SETTINGS',
// Users
removeUser: 'REMOVE_USER',
addUser: 'ADD_USER',
// DND
startDragging: 'START_DRAGGING',
onDroppable: 'ON_DROPPABLE',
outDroppable: 'OUT_DROPPABLE',
stopDragging: 'STOP_DRAGGING',
// Page builder
pbToggleEditing: 'PB_TOGGLE_EDITING',
pbSetMenuOpened: 'PB_SET_MENU_OPENED',
pbSetMenuSide: 'PB_SET_MENU_SIDE',
pbSetMenuTab: 'PB_SET_MENU_TAB',
pbOpenElementsMenu: 'PB_OPEN_ELEMENTS_MENU',
pbCloseElementsMenu: 'PB_CLOSE_ELEMENTS_MENU',
pbToggleExpandElement: 'PB_TOGGLE_EXPAND_ELEMENT',
pbExpandAll: 'PB_EXPAND_ALL',
pbCollapseAll: 'PB_COLLAPSE_ALL',
pbToggleCategory: 'PB_TOGGLE_CATEGORY',
pbOverElement: 'PB_OVER_ELEMENT',
pbOutElement: 'PB_OUT_ELEMENT',
pbSelectElement: 'PB_SELECT_ELEMENT',
pbDoAction: 'PB_DO_ACTION',
pbUndoAction: 'PB_UNDO_ACTION',
pbRedoAction: 'PB_REDO_ACTION',
pbLinkDataMode: 'PB_LINK_DATA_MODE',
pbCloseLinkDataMode: 'PB_CLOSE_LINK_DATA_MODE',
pbLinkFormDataMode: 'PB_LINK_FORM_DATA_MODE',
pbCloseLinkFormDataMode: 'PB_CLOSE_LINK_FORM_DATA_MODE',
// Symbols
makeElementSymbol: 'MAKE_ELEMENT_SYMBOL',
getSymbol: 'GET_SYMBOL',
// Elements
getElementData: 'GET_ELEMENT_DATA',
// Revisions
getRevisions: 'GET_REVISIONS',
// Draft
saveDraft: 'SAVE_DRAFT',
dropDraft: 'DROP_DRAFT',
// Tabs
removeTab: 'REMOVE_TAB',
// styles
saveStyle: 'SAVE_STYLE',
updateSty
gitextract_vwl5em8h/
├── .eslintrc
├── .gitignore
├── .npmignore
├── .relaxrc.sample
├── LICENSE
├── README.md
├── ROADMAP.md
├── app.js
├── assets/
│ └── fonts/
│ └── FontAwesome.otf
├── config.js
├── lib/
│ ├── client/
│ │ ├── admin.js
│ │ ├── auth.js
│ │ ├── helpers/
│ │ │ └── render-routes.js
│ │ └── public.js
│ ├── server/
│ │ ├── graphql/
│ │ │ ├── authorize.js
│ │ │ ├── mutations/
│ │ │ │ ├── color/
│ │ │ │ │ ├── add.js
│ │ │ │ │ ├── duplicate.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── remove.js
│ │ │ │ │ └── update.js
│ │ │ │ ├── draft/
│ │ │ │ │ ├── drop.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── update.js
│ │ │ │ ├── fonts/
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── remove-custom.js
│ │ │ │ │ ├── submit-custom.js
│ │ │ │ │ └── upload.js
│ │ │ │ ├── index.js
│ │ │ │ ├── media/
│ │ │ │ │ ├── add.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── remove.js
│ │ │ │ ├── menu/
│ │ │ │ │ ├── add.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── remove.js
│ │ │ │ │ └── update.js
│ │ │ │ ├── page/
│ │ │ │ │ ├── add.js
│ │ │ │ │ ├── duplicate.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── remove.js
│ │ │ │ │ ├── restore.js
│ │ │ │ │ └── update.js
│ │ │ │ ├── schema-entry/
│ │ │ │ │ ├── add.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── remove.js
│ │ │ │ │ ├── restore.js
│ │ │ │ │ └── update.js
│ │ │ │ ├── schemas/
│ │ │ │ │ ├── add.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── remove.js
│ │ │ │ │ ├── restore.js
│ │ │ │ │ └── update.js
│ │ │ │ ├── settings/
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── save.js
│ │ │ │ ├── style/
│ │ │ │ │ ├── add.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── parsable-fields.js
│ │ │ │ │ ├── remove.js
│ │ │ │ │ └── update.js
│ │ │ │ ├── symbol/
│ │ │ │ │ ├── add.js
│ │ │ │ │ └── index.js
│ │ │ │ ├── tab/
│ │ │ │ │ ├── add.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── remove.js
│ │ │ │ └── user/
│ │ │ │ ├── add.js
│ │ │ │ ├── index.js
│ │ │ │ └── remove.js
│ │ │ ├── queries/
│ │ │ │ ├── color/
│ │ │ │ │ ├── colors.js
│ │ │ │ │ └── index.js
│ │ │ │ ├── draft/
│ │ │ │ │ ├── draft.js
│ │ │ │ │ └── index.js
│ │ │ │ ├── generators/
│ │ │ │ │ ├── schema-list-count.js
│ │ │ │ │ └── schema-list.js
│ │ │ │ ├── index.js
│ │ │ │ ├── media/
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── media-count.js
│ │ │ │ │ └── media.js
│ │ │ │ ├── menu/
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── menu.js
│ │ │ │ │ ├── menus-count.js
│ │ │ │ │ └── menus.js
│ │ │ │ ├── page/
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── page.js
│ │ │ │ │ ├── pages-count.js
│ │ │ │ │ └── pages.js
│ │ │ │ ├── revision/
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── revisions.js
│ │ │ │ ├── schema-entry/
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── schema-entry.js
│ │ │ │ │ ├── schema-list-count.js
│ │ │ │ │ └── schema-list.js
│ │ │ │ ├── schemas/
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── schema.js
│ │ │ │ │ ├── schemas-count.js
│ │ │ │ │ └── schemas.js
│ │ │ │ ├── settings/
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── settings.js
│ │ │ │ ├── style/
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── styles.js
│ │ │ │ ├── symbol/
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── symbol.js
│ │ │ │ │ └── symbols.js
│ │ │ │ ├── tab/
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── tabs.js
│ │ │ │ └── user/
│ │ │ │ ├── index.js
│ │ │ │ ├── session.js
│ │ │ │ ├── user.js
│ │ │ │ ├── users-count.js
│ │ │ │ └── users.js
│ │ │ ├── query-pagination.js
│ │ │ └── types/
│ │ │ ├── color-input.js
│ │ │ ├── color.js
│ │ │ ├── count.js
│ │ │ ├── custom-font.js
│ │ │ ├── draft-id-input.js
│ │ │ ├── draft-id.js
│ │ │ ├── draft-input.js
│ │ │ ├── draft.js
│ │ │ ├── filter.js
│ │ │ ├── generators/
│ │ │ │ ├── schema-entry-input.js
│ │ │ │ └── schema-entry.js
│ │ │ ├── media-input.js
│ │ │ ├── media.js
│ │ │ ├── menu-data.js
│ │ │ ├── menu-input.js
│ │ │ ├── menu.js
│ │ │ ├── page-input.js
│ │ │ ├── page.js
│ │ │ ├── revision.js
│ │ │ ├── schema-entry-input.js
│ │ │ ├── schema-entry.js
│ │ │ ├── schema-input.js
│ │ │ ├── schema.js
│ │ │ ├── setting-input.js
│ │ │ ├── setting.js
│ │ │ ├── style-input.js
│ │ │ ├── style.js
│ │ │ ├── symbol-input.js
│ │ │ ├── symbol.js
│ │ │ ├── tab-item.js
│ │ │ ├── tab.js
│ │ │ ├── uploaded-input.js
│ │ │ ├── uploaded.js
│ │ │ ├── user-input.js
│ │ │ └── user.js
│ │ ├── index.js
│ │ ├── logger.js
│ │ ├── middleware/
│ │ │ ├── fonts.js
│ │ │ ├── google-analytics.js
│ │ │ └── index.js
│ │ ├── migrate.js
│ │ ├── models/
│ │ │ ├── color.js
│ │ │ ├── draft.js
│ │ │ ├── index.js
│ │ │ ├── media.js
│ │ │ ├── menu.js
│ │ │ ├── migration.js
│ │ │ ├── page.js
│ │ │ ├── revision.js
│ │ │ ├── schema-entry.js
│ │ │ ├── schema.js
│ │ │ ├── setting.js
│ │ │ ├── style.js
│ │ │ ├── symbol.js
│ │ │ ├── tab.js
│ │ │ └── user.js
│ │ ├── routers/
│ │ │ ├── admin.js
│ │ │ ├── auth.js
│ │ │ ├── index.js
│ │ │ └── public.js
│ │ ├── schema.js
│ │ └── shared/
│ │ ├── components/
│ │ │ └── html.jsx
│ │ └── helpers/
│ │ ├── create-image-thumbnail.js
│ │ ├── default-favicon.js
│ │ ├── file-mimetype.js
│ │ ├── get-markup.js
│ │ ├── get-projection.js
│ │ ├── get-unique-slug.js
│ │ ├── resize-image.js
│ │ ├── route-handler.js
│ │ ├── safe-html-string.js
│ │ └── write-file.js
│ └── shared/
│ ├── actions/
│ │ ├── admin-menu.js
│ │ ├── colors.js
│ │ ├── display.js
│ │ ├── dnd.js
│ │ ├── draft.js
│ │ ├── elements.js
│ │ ├── fonts.js
│ │ ├── graphql.js
│ │ ├── index.js
│ │ ├── media.js
│ │ ├── menu.js
│ │ ├── page-builder.js
│ │ ├── page.js
│ │ ├── revisions.js
│ │ ├── schema-entry.js
│ │ ├── schema-list.js
│ │ ├── schema.js
│ │ ├── schemas.js
│ │ ├── session.js
│ │ ├── settings.js
│ │ ├── styles.js
│ │ ├── symbols.js
│ │ ├── tabs.js
│ │ └── users.js
│ ├── components/
│ │ ├── a.jsx
│ │ ├── animate-props.jsx
│ │ ├── animate.jsx
│ │ ├── background-image.jsx
│ │ ├── button/
│ │ │ ├── index.jsx
│ │ │ └── index.less
│ │ ├── component.jsx
│ │ ├── dnd/
│ │ │ ├── draggable/
│ │ │ │ ├── draggable.jsx
│ │ │ │ └── index.js
│ │ │ ├── dragger/
│ │ │ │ ├── dragger.jsx
│ │ │ │ ├── dragger.less
│ │ │ │ └── index.js
│ │ │ └── droppable/
│ │ │ ├── add-ballon.jsx
│ │ │ ├── add-ballon.less
│ │ │ ├── droppable.jsx
│ │ │ ├── droppable.less
│ │ │ ├── index.js
│ │ │ ├── marker.jsx
│ │ │ └── marker.less
│ │ ├── image.jsx
│ │ ├── medium-editor/
│ │ │ ├── index.jsx
│ │ │ └── index.less
│ │ └── portal.jsx
│ ├── decorators/
│ │ ├── bind.js
│ │ ├── debounce.js
│ │ └── query-props.jsx
│ ├── elements/
│ │ ├── button/
│ │ │ ├── classes.js
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ ├── settings.js
│ │ │ └── style.js
│ │ ├── column/
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ └── settings.js
│ │ ├── columns/
│ │ │ ├── classes.js
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ └── settings.js
│ │ ├── component.jsx
│ │ ├── container/
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ ├── settings.js
│ │ │ └── style.js
│ │ ├── counter/
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ └── settings.js
│ │ ├── date/
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.jsx
│ │ │ └── settings.js
│ │ ├── dynamic-list/
│ │ │ ├── classes.js
│ │ │ ├── container.jsx
│ │ │ ├── index.jsx
│ │ │ ├── list.jsx
│ │ │ ├── props-schema.js
│ │ │ └── settings.js
│ │ ├── element/
│ │ │ ├── context-menu/
│ │ │ │ ├── context-menu.jsx
│ │ │ │ ├── context-menu.less
│ │ │ │ └── index.js
│ │ │ ├── element.jsx
│ │ │ ├── empty.jsx
│ │ │ ├── empty.less
│ │ │ ├── highlight.jsx
│ │ │ ├── highlight.less
│ │ │ └── index.js
│ │ ├── form/
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ └── settings.js
│ │ ├── gap/
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ └── settings.js
│ │ ├── google-maps/
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ └── settings.js
│ │ ├── icon/
│ │ │ ├── classes.js
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ ├── settings.js
│ │ │ └── style.js
│ │ ├── image/
│ │ │ ├── classes.js
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ └── settings.js
│ │ ├── index.js
│ │ ├── line-divider/
│ │ │ ├── classes.js
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ ├── settings.js
│ │ │ └── style.js
│ │ ├── menu/
│ │ │ ├── classes.js
│ │ │ ├── entry.jsx
│ │ │ ├── index.jsx
│ │ │ ├── menu.jsx
│ │ │ ├── props-schema.js
│ │ │ ├── settings.js
│ │ │ └── style.js
│ │ ├── music-player/
│ │ │ ├── classes.js
│ │ │ ├── container.jsx
│ │ │ ├── index.jsx
│ │ │ ├── player.jsx
│ │ │ ├── props-schema.js
│ │ │ ├── settings.js
│ │ │ └── style.js
│ │ ├── section/
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ ├── settings.js
│ │ │ └── style.js
│ │ ├── symbol/
│ │ │ ├── classes.js
│ │ │ ├── container.jsx
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ └── settings.js
│ │ ├── text-box/
│ │ │ ├── classes.js
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ ├── settings.js
│ │ │ └── style.js
│ │ ├── text-input/
│ │ │ ├── classes.js
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ ├── settings.js
│ │ │ └── style.js
│ │ ├── textarea/
│ │ │ ├── classes.js
│ │ │ ├── index.jsx
│ │ │ ├── props-schema.js
│ │ │ └── settings.js
│ │ └── video/
│ │ ├── index.jsx
│ │ ├── props-schema.js
│ │ └── settings.js
│ ├── helpers/
│ │ ├── colors.js
│ │ ├── configure-store.js
│ │ ├── data-types/
│ │ │ ├── index.js
│ │ │ └── native.js
│ │ ├── displays.js
│ │ ├── ga-send.js
│ │ ├── get-element-position.js
│ │ ├── get-element-props.js
│ │ ├── get-element-style-values.js
│ │ ├── get-gravatar-image.js
│ │ ├── icons.js
│ │ ├── load-fonts.js
│ │ ├── mime-types.js
│ │ ├── parse-fields.js
│ │ ├── parse-settings.js
│ │ ├── request.js
│ │ ├── schema-filter-default-options.js
│ │ ├── schema-link-actions.js
│ │ ├── schema-static-properties.js
│ │ ├── stringify-fields.js
│ │ ├── styles-manager.js
│ │ ├── stylesheet.js
│ │ └── utils.js
│ ├── reducers/
│ │ ├── admin-menu.js
│ │ ├── display.js
│ │ ├── dnd.js
│ │ ├── fonts.js
│ │ ├── index.js
│ │ ├── media.js
│ │ ├── menu.js
│ │ ├── page-builder-actions/
│ │ │ ├── add.js
│ │ │ ├── change-animation.js
│ │ │ ├── change-children.js
│ │ │ ├── change-content.js
│ │ │ ├── change-display.js
│ │ │ ├── change-label.js
│ │ │ ├── change-position.js
│ │ │ ├── change-prop.js
│ │ │ ├── change-style.js
│ │ │ ├── duplicate.js
│ │ │ ├── element-add-schema-link.js
│ │ │ ├── element-change-schema-link-action.js
│ │ │ ├── element-remove-schema-link.js
│ │ │ ├── helpers/
│ │ │ │ ├── clone-children.js
│ │ │ │ ├── get-id.js
│ │ │ │ └── remove-children.js
│ │ │ ├── index.js
│ │ │ ├── make-dynamic.js
│ │ │ ├── move.js
│ │ │ ├── new.js
│ │ │ └── remove.js
│ │ ├── page-builder.js
│ │ ├── revisions.js
│ │ ├── schema-entry.js
│ │ ├── schema.js
│ │ ├── session.js
│ │ ├── settings.js
│ │ ├── styles.js
│ │ └── symbols.js
│ ├── routers/
│ │ ├── admin.js
│ │ ├── auth.js
│ │ └── public.js
│ ├── screens/
│ │ ├── admin/
│ │ │ ├── components/
│ │ │ │ ├── admin/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── loading/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── menu/
│ │ │ │ │ ├── content-types.jsx
│ │ │ │ │ ├── content-types.less
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── menu.jsx
│ │ │ │ │ ├── menu.less
│ │ │ │ │ ├── user.jsx
│ │ │ │ │ └── user.less
│ │ │ │ └── top-bar/
│ │ │ │ ├── actions/
│ │ │ │ │ ├── actions.jsx
│ │ │ │ │ ├── actions.less
│ │ │ │ │ ├── back.jsx
│ │ │ │ │ ├── back.less
│ │ │ │ │ ├── display.jsx
│ │ │ │ │ ├── display.less
│ │ │ │ │ ├── displays.jsx
│ │ │ │ │ ├── displays.less
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── right-menu.jsx
│ │ │ │ │ ├── right-menu.less
│ │ │ │ │ ├── statuses.jsx
│ │ │ │ │ └── statuses.less
│ │ │ │ ├── index.jsx
│ │ │ │ ├── index.less
│ │ │ │ └── tabs/
│ │ │ │ ├── index.js
│ │ │ │ ├── tab.jsx
│ │ │ │ ├── tab.less
│ │ │ │ ├── tabs.jsx
│ │ │ │ └── tabs.less
│ │ │ ├── index.js
│ │ │ ├── screens/
│ │ │ │ ├── colors/
│ │ │ │ │ ├── components/
│ │ │ │ │ │ ├── colors.jsx
│ │ │ │ │ │ ├── entry.jsx
│ │ │ │ │ │ ├── entry.less
│ │ │ │ │ │ └── list.jsx
│ │ │ │ │ └── index.js
│ │ │ │ ├── fonts/
│ │ │ │ │ ├── components/
│ │ │ │ │ │ ├── entry.jsx
│ │ │ │ │ │ ├── entry.less
│ │ │ │ │ │ ├── fonts.jsx
│ │ │ │ │ │ ├── list.jsx
│ │ │ │ │ │ ├── manage/
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ ├── manage.jsx
│ │ │ │ │ │ │ └── manage.less
│ │ │ │ │ │ ├── preview-text.jsx
│ │ │ │ │ │ └── preview-text.less
│ │ │ │ │ └── index.js
│ │ │ │ ├── media/
│ │ │ │ │ ├── components/
│ │ │ │ │ │ ├── entry.jsx
│ │ │ │ │ │ ├── entry.less
│ │ │ │ │ │ ├── list.jsx
│ │ │ │ │ │ ├── media.jsx
│ │ │ │ │ │ ├── media.less
│ │ │ │ │ │ ├── menu.jsx
│ │ │ │ │ │ ├── menu.less
│ │ │ │ │ │ ├── sorting.jsx
│ │ │ │ │ │ ├── sorting.less
│ │ │ │ │ │ └── uploading/
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── item.jsx
│ │ │ │ │ │ ├── item.less
│ │ │ │ │ │ ├── uploading.jsx
│ │ │ │ │ │ └── uploading.less
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── menu.js
│ │ │ │ ├── menus/
│ │ │ │ │ ├── components/
│ │ │ │ │ │ ├── content.jsx
│ │ │ │ │ │ ├── content.less
│ │ │ │ │ │ ├── entry.jsx
│ │ │ │ │ │ ├── entry.less
│ │ │ │ │ │ ├── list.jsx
│ │ │ │ │ │ ├── menu.jsx
│ │ │ │ │ │ ├── menu.less
│ │ │ │ │ │ └── new/
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ └── new.jsx
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── menu.js
│ │ │ │ │ └── screens/
│ │ │ │ │ └── menu/
│ │ │ │ │ ├── components/
│ │ │ │ │ │ ├── menu-builder/
│ │ │ │ │ │ │ ├── builder.jsx
│ │ │ │ │ │ │ ├── builder.less
│ │ │ │ │ │ │ ├── collapsable.jsx
│ │ │ │ │ │ │ ├── collapsable.less
│ │ │ │ │ │ │ ├── entry.jsx
│ │ │ │ │ │ │ ├── entry.less
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ ├── link/
│ │ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ │ ├── link.jsx
│ │ │ │ │ │ │ │ └── link.less
│ │ │ │ │ │ │ ├── menu/
│ │ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ │ ├── menu.jsx
│ │ │ │ │ │ │ │ └── menu.less
│ │ │ │ │ │ │ └── pages/
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ ├── pages.jsx
│ │ │ │ │ │ │ └── pages.less
│ │ │ │ │ │ ├── menu.jsx
│ │ │ │ │ │ ├── menu.less
│ │ │ │ │ │ ├── state.jsx
│ │ │ │ │ │ └── state.less
│ │ │ │ │ └── index.js
│ │ │ │ ├── pages/
│ │ │ │ │ ├── components/
│ │ │ │ │ │ ├── entry.jsx
│ │ │ │ │ │ ├── entry.less
│ │ │ │ │ │ ├── list.jsx
│ │ │ │ │ │ ├── menu.jsx
│ │ │ │ │ │ ├── menu.less
│ │ │ │ │ │ ├── new/
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ └── new.jsx
│ │ │ │ │ │ ├── pages.jsx
│ │ │ │ │ │ └── pages.less
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── menu.js
│ │ │ │ │ └── screens/
│ │ │ │ │ └── page/
│ │ │ │ │ ├── components/
│ │ │ │ │ │ ├── info/
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ ├── info.jsx
│ │ │ │ │ │ │ ├── info.less
│ │ │ │ │ │ │ ├── item.jsx
│ │ │ │ │ │ │ └── item.less
│ │ │ │ │ │ ├── page.jsx
│ │ │ │ │ │ ├── page.less
│ │ │ │ │ │ └── revisions/
│ │ │ │ │ │ └── index.js
│ │ │ │ │ └── index.js
│ │ │ │ ├── schemas/
│ │ │ │ │ └── screens/
│ │ │ │ │ ├── new/
│ │ │ │ │ │ ├── components/
│ │ │ │ │ │ │ └── builder/
│ │ │ │ │ │ │ ├── builder.jsx
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ ├── model.jsx
│ │ │ │ │ │ │ ├── model.less
│ │ │ │ │ │ │ ├── name.jsx
│ │ │ │ │ │ │ ├── name.less
│ │ │ │ │ │ │ ├── properties/
│ │ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ │ ├── properties.jsx
│ │ │ │ │ │ │ │ ├── properties.less
│ │ │ │ │ │ │ │ ├── property-options.jsx
│ │ │ │ │ │ │ │ ├── property-options.less
│ │ │ │ │ │ │ │ ├── property.jsx
│ │ │ │ │ │ │ │ └── property.less
│ │ │ │ │ │ │ ├── type.jsx
│ │ │ │ │ │ │ ├── type.less
│ │ │ │ │ │ │ ├── types.jsx
│ │ │ │ │ │ │ └── types.less
│ │ │ │ │ │ └── index.js
│ │ │ │ │ └── schema/
│ │ │ │ │ ├── components/
│ │ │ │ │ │ ├── entry.jsx
│ │ │ │ │ │ ├── entry.less
│ │ │ │ │ │ ├── list.jsx
│ │ │ │ │ │ ├── menu.jsx
│ │ │ │ │ │ ├── menu.less
│ │ │ │ │ │ ├── new/
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ └── new.jsx
│ │ │ │ │ │ ├── schema.jsx
│ │ │ │ │ │ └── schema.less
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── menu.js
│ │ │ │ ├── settings/
│ │ │ │ │ ├── components/
│ │ │ │ │ │ ├── menu.jsx
│ │ │ │ │ │ └── menu.less
│ │ │ │ │ ├── menu.js
│ │ │ │ │ ├── screens/
│ │ │ │ │ │ ├── analytics/
│ │ │ │ │ │ │ ├── components/
│ │ │ │ │ │ │ │ └── analytics.jsx
│ │ │ │ │ │ │ └── index.js
│ │ │ │ │ │ ├── data/
│ │ │ │ │ │ │ ├── components/
│ │ │ │ │ │ │ │ └── data.jsx
│ │ │ │ │ │ │ └── index.js
│ │ │ │ │ │ ├── email/
│ │ │ │ │ │ │ ├── components/
│ │ │ │ │ │ │ │ └── email.jsx
│ │ │ │ │ │ │ └── index.js
│ │ │ │ │ │ └── general/
│ │ │ │ │ │ ├── components/
│ │ │ │ │ │ │ └── general.jsx
│ │ │ │ │ │ └── index.js
│ │ │ │ │ └── shared/
│ │ │ │ │ └── components/
│ │ │ │ │ └── settings-content/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ └── users/
│ │ │ │ ├── components/
│ │ │ │ │ ├── entry.jsx
│ │ │ │ │ ├── entry.less
│ │ │ │ │ ├── list.jsx
│ │ │ │ │ ├── new/
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ └── new.jsx
│ │ │ │ │ └── users.jsx
│ │ │ │ └── index.js
│ │ │ └── shared/
│ │ │ ├── components/
│ │ │ │ ├── balloon/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── content/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── content-displays/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── content-header/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── content-header-actions/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── content-loading/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── content-new/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── content-search/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── content-sidebar/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── editable-title/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── input-options/
│ │ │ │ │ ├── border/
│ │ │ │ │ │ ├── index.jsx
│ │ │ │ │ │ └── index.less
│ │ │ │ │ ├── border-style/
│ │ │ │ │ │ ├── index.jsx
│ │ │ │ │ │ └── index.less
│ │ │ │ │ ├── box-shadow/
│ │ │ │ │ │ ├── edit.jsx
│ │ │ │ │ │ ├── index.jsx
│ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ ├── shadow.jsx
│ │ │ │ │ │ └── shadow.less
│ │ │ │ │ ├── button/
│ │ │ │ │ │ └── index.js
│ │ │ │ │ ├── checkbox/
│ │ │ │ │ │ ├── index.jsx
│ │ │ │ │ │ └── index.less
│ │ │ │ │ ├── color/
│ │ │ │ │ │ ├── color-palette-picker.jsx
│ │ │ │ │ │ ├── color-palette-picker.less
│ │ │ │ │ │ ├── color-picker.jsx
│ │ │ │ │ │ ├── color-picker.less
│ │ │ │ │ │ ├── color.jsx
│ │ │ │ │ │ ├── color.less
│ │ │ │ │ │ ├── colors-collection.jsx
│ │ │ │ │ │ ├── colors-collection.less
│ │ │ │ │ │ ├── edit.jsx
│ │ │ │ │ │ ├── edit.less
│ │ │ │ │ │ ├── gradient-points.jsx
│ │ │ │ │ │ ├── gradient-points.less
│ │ │ │ │ │ ├── hue.jsx
│ │ │ │ │ │ ├── hue.less
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── input.jsx
│ │ │ │ │ │ ├── input.less
│ │ │ │ │ │ ├── inputs.jsx
│ │ │ │ │ │ ├── inputs.less
│ │ │ │ │ │ ├── linear-gradient.jsx
│ │ │ │ │ │ ├── linear-gradient.less
│ │ │ │ │ │ ├── opacity.jsx
│ │ │ │ │ │ ├── opacity.less
│ │ │ │ │ │ ├── radial-gradient.jsx
│ │ │ │ │ │ ├── radial-gradient.less
│ │ │ │ │ │ ├── radial-radius.jsx
│ │ │ │ │ │ ├── radial-radius.less
│ │ │ │ │ │ ├── sat-light.jsx
│ │ │ │ │ │ ├── sat-light.less
│ │ │ │ │ │ ├── types.jsx
│ │ │ │ │ │ └── types.less
│ │ │ │ │ ├── columns/
│ │ │ │ │ │ ├── column.jsx
│ │ │ │ │ │ ├── column.less
│ │ │ │ │ │ ├── columns-manager.jsx
│ │ │ │ │ │ ├── columns-manager.less
│ │ │ │ │ │ └── index.js
│ │ │ │ │ ├── combobox/
│ │ │ │ │ │ ├── index.jsx
│ │ │ │ │ │ └── index.less
│ │ │ │ │ ├── corners/
│ │ │ │ │ │ └── index.jsx
│ │ │ │ │ ├── filters/
│ │ │ │ │ │ ├── edit.jsx
│ │ │ │ │ │ ├── filter.jsx
│ │ │ │ │ │ ├── filters.jsx
│ │ │ │ │ │ └── index.js
│ │ │ │ │ ├── font/
│ │ │ │ │ │ ├── dropdown.jsx
│ │ │ │ │ │ ├── dropdown.less
│ │ │ │ │ │ ├── font-picker.jsx
│ │ │ │ │ │ ├── font-picker.less
│ │ │ │ │ │ ├── font.jsx
│ │ │ │ │ │ ├── font.less
│ │ │ │ │ │ └── index.js
│ │ │ │ │ ├── icon/
│ │ │ │ │ │ ├── icon-picker.jsx
│ │ │ │ │ │ └── index.js
│ │ │ │ │ ├── image/
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── picker.jsx
│ │ │ │ │ │ └── picker.less
│ │ │ │ │ ├── input/
│ │ │ │ │ │ ├── index.jsx
│ │ │ │ │ │ └── index.less
│ │ │ │ │ ├── menu/
│ │ │ │ │ │ └── index.js
│ │ │ │ │ ├── number/
│ │ │ │ │ │ ├── index.jsx
│ │ │ │ │ │ └── index.less
│ │ │ │ │ ├── optional/
│ │ │ │ │ │ ├── index.jsx
│ │ │ │ │ │ └── index.less
│ │ │ │ │ ├── page/
│ │ │ │ │ │ └── index.js
│ │ │ │ │ ├── rich-text/
│ │ │ │ │ │ └── index.jsx
│ │ │ │ │ ├── schema/
│ │ │ │ │ │ └── index.js
│ │ │ │ │ ├── section/
│ │ │ │ │ │ ├── index.jsx
│ │ │ │ │ │ └── index.less
│ │ │ │ │ ├── shadow-position/
│ │ │ │ │ │ ├── index.jsx
│ │ │ │ │ │ └── index.less
│ │ │ │ │ ├── sorts/
│ │ │ │ │ │ ├── edit.jsx
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── sort.jsx
│ │ │ │ │ │ └── sorts.jsx
│ │ │ │ │ ├── spacing/
│ │ │ │ │ │ ├── index.jsx
│ │ │ │ │ │ └── index.less
│ │ │ │ │ └── text-shadow/
│ │ │ │ │ ├── edit.jsx
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ ├── index.less
│ │ │ │ │ ├── shadow.jsx
│ │ │ │ │ └── shadow.less
│ │ │ │ ├── list-header/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── list-search-sort/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── media-item-preview/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── media-selector/
│ │ │ │ │ ├── entry.jsx
│ │ │ │ │ ├── entry.less
│ │ │ │ │ ├── filters.jsx
│ │ │ │ │ ├── filters.less
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── list.jsx
│ │ │ │ │ ├── list.less
│ │ │ │ │ ├── media-selector.jsx
│ │ │ │ │ ├── media-selector.less
│ │ │ │ │ ├── mock-entry.jsx
│ │ │ │ │ ├── mock-entry.less
│ │ │ │ │ ├── selected/
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── selected.jsx
│ │ │ │ │ │ └── selected.less
│ │ │ │ │ ├── sidebar.jsx
│ │ │ │ │ ├── sidebar.less
│ │ │ │ │ ├── top-bar.jsx
│ │ │ │ │ └── top-bar.less
│ │ │ │ ├── menu-button/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── menu-sub-button/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── modal/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── modal-delete/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── modal-input/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── modal-new/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── options-list/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── options-menu/
│ │ │ │ │ └── index.jsx
│ │ │ │ ├── page-builder/
│ │ │ │ │ ├── canvas/
│ │ │ │ │ │ ├── canvas.jsx
│ │ │ │ │ │ ├── canvas.less
│ │ │ │ │ │ ├── empty.jsx
│ │ │ │ │ │ ├── empty.less
│ │ │ │ │ │ └── index.js
│ │ │ │ │ ├── elements-menu/
│ │ │ │ │ │ ├── autocomplete.jsx
│ │ │ │ │ │ ├── autocomplete.less
│ │ │ │ │ │ ├── elements-menu.jsx
│ │ │ │ │ │ ├── elements-menu.less
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── list.jsx
│ │ │ │ │ │ ├── list.less
│ │ │ │ │ │ ├── search.jsx
│ │ │ │ │ │ └── search.less
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── page-builder.jsx
│ │ │ │ │ └── page-builder.less
│ │ │ │ ├── page-builder-menu/
│ │ │ │ │ ├── breadcrumbs/
│ │ │ │ │ │ ├── breadcrumbs.jsx
│ │ │ │ │ │ ├── breadcrumbs.less
│ │ │ │ │ │ ├── entry.jsx
│ │ │ │ │ │ ├── entry.less
│ │ │ │ │ │ └── index.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── menu.jsx
│ │ │ │ │ ├── menu.less
│ │ │ │ │ └── tabs/
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── layers/
│ │ │ │ │ │ ├── entry.jsx
│ │ │ │ │ │ ├── entry.less
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── layers.jsx
│ │ │ │ │ │ └── layers.less
│ │ │ │ │ ├── settings/
│ │ │ │ │ │ ├── animation.jsx
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── position.jsx
│ │ │ │ │ │ ├── props.jsx
│ │ │ │ │ │ ├── props.less
│ │ │ │ │ │ ├── settings.jsx
│ │ │ │ │ │ └── settings.less
│ │ │ │ │ ├── style/
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── style-picker/
│ │ │ │ │ │ │ ├── edit.jsx
│ │ │ │ │ │ │ ├── edit.less
│ │ │ │ │ │ │ ├── entry.jsx
│ │ │ │ │ │ │ ├── entry.less
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ ├── style-picker.jsx
│ │ │ │ │ │ │ └── style-picker.less
│ │ │ │ │ │ ├── style.jsx
│ │ │ │ │ │ └── style.less
│ │ │ │ │ ├── tab-button.jsx
│ │ │ │ │ ├── tab-button.less
│ │ │ │ │ ├── tabs.jsx
│ │ │ │ │ └── tabs.less
│ │ │ │ ├── scrollable/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── spinner/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ ├── stick/
│ │ │ │ │ ├── index.jsx
│ │ │ │ │ └── index.less
│ │ │ │ └── upload/
│ │ │ │ ├── index.jsx
│ │ │ │ └── index.less
│ │ │ └── helpers/
│ │ │ └── input-options-map.js
│ │ └── auth/
│ │ ├── components/
│ │ │ └── logo/
│ │ │ ├── index.jsx
│ │ │ └── index.less
│ │ ├── index.css
│ │ ├── index.jsx
│ │ ├── screens/
│ │ │ ├── init/
│ │ │ │ ├── components/
│ │ │ │ │ └── init.jsx
│ │ │ │ └── index.js
│ │ │ └── login/
│ │ │ ├── components/
│ │ │ │ └── login.jsx
│ │ │ └── index.js
│ │ └── shared/
│ │ └── styles/
│ │ └── auth.less
│ └── styles/
│ ├── colors.less
│ ├── element.less
│ ├── normalize.less
│ ├── nucleo/
│ │ ├── index.less
│ │ ├── mini/
│ │ │ └── less/
│ │ │ ├── icons.less
│ │ │ ├── mixins.less
│ │ │ ├── nucleo-mini.less
│ │ │ └── variables.less
│ │ └── outline/
│ │ └── less/
│ │ ├── icons.less
│ │ ├── mixins.less
│ │ ├── nucleo-outline.less
│ │ └── variables.less
│ └── sizes.less
├── migrations/
│ └── .gitempty
├── package.json
├── uploads/
│ └── .gitignore
└── webpack/
├── webpack.browser.config.js
└── webpack.node.config.js
SYMBOL INDEX (1708 symbols across 440 files)
FILE: lib/client/helpers/render-routes.js
function renderRoutes (line 8) | function renderRoutes (routes) {
FILE: lib/server/graphql/authorize.js
function authorize (line 1) | function authorize (root) {
FILE: lib/server/graphql/mutations/color/add.js
method resolve (line 18) | async resolve (root, params) {
FILE: lib/server/graphql/mutations/color/duplicate.js
method resolve (line 18) | async resolve (root, params) {
FILE: lib/server/graphql/mutations/color/remove.js
method resolve (line 19) | async resolve (root, params, options) {
FILE: lib/server/graphql/mutations/color/update.js
method resolve (line 19) | async resolve (root, params, options) {
FILE: lib/server/graphql/mutations/draft/drop.js
method resolve (line 21) | async resolve (root, params, options) {
FILE: lib/server/graphql/mutations/draft/update.js
method resolve (line 25) | resolve (root, params, options) {
FILE: lib/server/graphql/mutations/fonts/remove-custom.js
method resolve (line 25) | resolve (root, params) {
FILE: lib/server/graphql/mutations/fonts/submit-custom.js
method resolve (line 33) | resolve (root, params) {
FILE: lib/server/graphql/mutations/fonts/upload.js
method resolve (line 6) | resolve (root) {
FILE: lib/server/graphql/mutations/media/add.js
method resolve (line 25) | async resolve (root, params) {
FILE: lib/server/graphql/mutations/media/remove.js
method resolve (line 25) | async resolve (root, params) {
method resolve (line 57) | async resolve (root, params, options) {
FILE: lib/server/graphql/mutations/menu/add.js
method resolve (line 18) | async resolve (root, params) {
FILE: lib/server/graphql/mutations/menu/remove.js
method resolve (line 18) | resolve (root, params) {
FILE: lib/server/graphql/mutations/menu/update.js
method resolve (line 19) | resolve (root, params, options) {
FILE: lib/server/graphql/mutations/page/add.js
method resolve (line 19) | async resolve (root, params) {
FILE: lib/server/graphql/mutations/page/duplicate.js
function getUniqueSlug (line 10) | function getUniqueSlug (slug, it) {
method resolve (line 35) | async resolve (root, params) {
FILE: lib/server/graphql/mutations/page/remove.js
method resolve (line 20) | async resolve (root, params) {
FILE: lib/server/graphql/mutations/page/restore.js
method resolve (line 24) | async resolve (root, params, options) {
FILE: lib/server/graphql/mutations/page/update.js
method resolve (line 20) | async resolve (root, params, options) {
FILE: lib/server/graphql/mutations/schema-entry/add.js
method resolve (line 27) | async resolve (root, params) {
FILE: lib/server/graphql/mutations/schema-entry/remove.js
method resolve (line 22) | async resolve (root, params) {
FILE: lib/server/graphql/mutations/schema-entry/restore.js
method resolve (line 28) | async resolve (root, params, options) {
FILE: lib/server/graphql/mutations/schema-entry/update.js
method resolve (line 28) | async resolve (root, params, options) {
FILE: lib/server/graphql/mutations/schemas/add.js
method resolve (line 19) | async resolve (root, params) {
FILE: lib/server/graphql/mutations/schemas/remove.js
method resolve (line 18) | async resolve (root, params) {
FILE: lib/server/graphql/mutations/schemas/restore.js
method resolve (line 24) | async resolve (root, params, options) {
FILE: lib/server/graphql/mutations/schemas/update.js
method resolve (line 20) | async resolve (root, params, options) {
FILE: lib/server/graphql/mutations/settings/save.js
method resolve (line 24) | resolve (root, params, options) {
FILE: lib/server/graphql/mutations/style/add.js
method resolve (line 20) | async resolve (root, params) {
FILE: lib/server/graphql/mutations/style/remove.js
method resolve (line 19) | async resolve (root, params, options) {
FILE: lib/server/graphql/mutations/style/update.js
method resolve (line 21) | async resolve (root, params, options) {
FILE: lib/server/graphql/mutations/symbol/add.js
method resolve (line 18) | async resolve (root, params) {
FILE: lib/server/graphql/mutations/tab/add.js
method resolve (line 23) | async resolve (root, params) {
FILE: lib/server/graphql/mutations/tab/remove.js
method resolve (line 19) | async resolve (root, params, options) {
FILE: lib/server/graphql/mutations/user/add.js
function registerUser (line 10) | async function registerUser (user, password) {
method resolve (line 29) | async resolve (root, params) {
FILE: lib/server/graphql/mutations/user/remove.js
method resolve (line 19) | resolve (root, params) {
FILE: lib/server/graphql/queries/color/colors.js
method resolve (line 12) | resolve (root, params, options) {
FILE: lib/server/graphql/queries/draft/draft.js
method resolve (line 20) | async resolve (root, params, options) {
FILE: lib/server/graphql/queries/generators/schema-list-count.js
method resolve (line 8) | async resolve (root) {
FILE: lib/server/graphql/queries/generators/schema-list.js
method resolve (line 15) | async resolve (root, params, options) {
FILE: lib/server/graphql/queries/media/media-count.js
method resolve (line 9) | async resolve (root) {
FILE: lib/server/graphql/queries/media/media.js
method resolve (line 18) | async resolve (root, params, options) {
method resolve (line 38) | async resolve (root, params, options) {
FILE: lib/server/graphql/queries/menu/menu.js
method resolve (line 21) | async resolve (root, params, options) {
method resolve (line 41) | async resolve (root, {slug, menuId}) {
FILE: lib/server/graphql/queries/menu/menus-count.js
method resolve (line 9) | async resolve (root) {
FILE: lib/server/graphql/queries/page/page.js
method resolve (line 26) | async resolve (root, params, options) {
method resolve (line 55) | async resolve (root, {slug, pageId}) {
FILE: lib/server/graphql/queries/page/pages-count.js
method resolve (line 8) | async resolve () {
FILE: lib/server/graphql/queries/page/pages.js
method resolve (line 16) | resolve (root, params, options) {
FILE: lib/server/graphql/queries/revision/revisions.js
method resolve (line 20) | async resolve (root, params, options) {
FILE: lib/server/graphql/queries/schema-entry/schema-entry.js
method resolve (line 25) | async resolve (root, {schemaId, id}, options) {
method resolve (line 49) | async resolve (root, {slug, schemaId, schemaEntryId}) {
FILE: lib/server/graphql/queries/schema-entry/schema-list-count.js
method resolve (line 17) | async resolve (root, params) {
FILE: lib/server/graphql/queries/schema-entry/schema-list.js
method resolve (line 21) | async resolve (root, params, options) {
FILE: lib/server/graphql/queries/schemas/schema.js
method resolve (line 25) | async resolve (root, params, options) {
method resolve (line 43) | async resolve (root, {slug, schemaId}) {
FILE: lib/server/graphql/queries/schemas/schemas-count.js
method resolve (line 9) | async resolve (root) {
FILE: lib/server/graphql/queries/schemas/schemas.js
method resolve (line 16) | resolve (root, params, options) {
FILE: lib/server/graphql/queries/style/styles.js
method resolve (line 12) | resolve (root, params, options) {
FILE: lib/server/graphql/queries/symbol/symbol.js
method resolve (line 16) | resolve (root, params, options) {
FILE: lib/server/graphql/queries/symbol/symbols.js
method resolve (line 10) | resolve (root, params, options) {
FILE: lib/server/graphql/queries/tab/tabs.js
method resolve (line 11) | resolve (root, params, options) {
FILE: lib/server/graphql/queries/user/session.js
method resolve (line 5) | resolve (root) {
FILE: lib/server/graphql/queries/user/user.js
method resolve (line 16) | resolve (root, params, options) {
FILE: lib/server/graphql/queries/user/users-count.js
method resolve (line 9) | async resolve (root) {
FILE: lib/server/graphql/queries/user/users.js
method resolve (line 14) | resolve (root, params, options) {
FILE: lib/server/graphql/query-pagination.js
function parseFilterOperation (line 41) | function parseFilterOperation (op) {
function searchQuery (line 49) | function searchQuery (find, params) {
function paginateQuery (line 78) | function paginateQuery (query, params) {
FILE: lib/server/graphql/types/generators/schema-entry.js
method resolve (line 33) | resolve ({date}) {
method resolve (line 39) | resolve ({updatedDate}) {
method resolve (line 45) | async resolve (schemaEntry) {
method resolve (line 51) | async resolve (schemaEntry) {
method resolve (line 57) | resolve (schemaEntry) {
FILE: lib/server/graphql/types/media.js
method resolve (line 37) | resolve (media) {
FILE: lib/server/graphql/types/menu-data.js
method resolve (line 19) | resolve (menuData, params, options) {
FILE: lib/server/graphql/types/menu.js
method resolve (line 19) | resolve ({date}) {
method resolve (line 25) | resolve ({updatedDate}) {
method resolve (line 31) | resolve (menu) {
method resolve (line 37) | resolve (menu) {
method resolve (line 43) | resolve ({data}) {
FILE: lib/server/graphql/types/page.js
method resolve (line 22) | resolve ({date}) {
method resolve (line 28) | resolve ({updatedDate}) {
method resolve (line 35) | resolve (page) {
method resolve (line 41) | async resolve (page) {
method resolve (line 47) | async resolve (page) {
FILE: lib/server/graphql/types/revision.js
method resolve (line 27) | resolve ({date}) {
method resolve (line 33) | resolve (revision) {
method resolve (line 39) | async resolve (revision) {
FILE: lib/server/graphql/types/schema-entry.js
method resolve (line 23) | resolve ({date}) {
method resolve (line 29) | resolve ({publishedDate}) {
method resolve (line 35) | resolve ({updatedDate}) {
method resolve (line 41) | async resolve (schemaEntry) {
method resolve (line 47) | async resolve (schemaEntry) {
method resolve (line 53) | resolve (schemaEntry) {
method resolve (line 59) | resolve (schemaEntry) {
FILE: lib/server/graphql/types/style.js
method resolve (line 16) | resolve (style) {
method resolve (line 22) | resolve (style) {
FILE: lib/server/graphql/types/symbol.js
method resolve (line 15) | resolve (symbol) {
FILE: lib/server/graphql/types/tab.js
method resolve (line 25) | async resolve ({type, item}) {
FILE: lib/server/migrate.js
function saveMigration (line 11) | function saveMigration (path) {
function runMigration (line 15) | function runMigration (path) {
function migrate (line 22) | function migrate () {
FILE: lib/server/routers/auth.js
function injectScript (line 12) | function injectScript (req, res, next) {
FILE: lib/server/schema.js
class SchemaManager (line 17) | class SchemaManager {
method constructor (line 18) | constructor () {
method init (line 22) | async init () {
method processSchema (line 34) | processSchema (/* schema */) {
method createRoot (line 48) | createRoot () {
method getSchema (line 59) | getSchema () {
FILE: lib/server/shared/components/html.jsx
class Html (line 3) | class Html extends React.Component {
method render (line 10) | render () {
method renderHeader (line 26) | renderHeader () {
method renderFooter (line 32) | renderFooter () {
method renderTag (line 38) | renderTag (tag) {
FILE: lib/server/shared/helpers/create-image-thumbnail.js
function createImageThumbnail (line 11) | async function createImageThumbnail (imagePath, destPath, options = defa...
FILE: lib/server/shared/helpers/default-favicon.js
function getDefaultIcon (line 1) | function getDefaultIcon (res) {
FILE: lib/server/shared/helpers/file-mimetype.js
function fileMimetype (line 1) | function fileMimetype (file) {
FILE: lib/server/shared/helpers/get-markup.js
function getMarkup (line 8) | function getMarkup (store, res) {
FILE: lib/server/shared/helpers/get-projection.js
function getProjection (line 1) | function getProjection (fieldASTs) {
FILE: lib/server/shared/helpers/get-unique-slug.js
function check (line 3) | async function check (Model, slug) {
FILE: lib/server/shared/helpers/resize-image.js
function resizeImage (line 10) | async function resizeImage (imagePath, destPath, options = defaultOption...
FILE: lib/server/shared/helpers/route-handler.js
function routeHandler (line 5) | function routeHandler (routes, req, res, next) {
FILE: lib/server/shared/helpers/safe-html-string.js
function safeHtmlString (line 1) | function safeHtmlString (str) {
FILE: lib/server/shared/helpers/write-file.js
function writeFile (line 6) | async function writeFile (file, _destPath) {
FILE: lib/shared/actions/admin-menu.js
function openAdminMenu (line 3) | function openAdminMenu () {
function closeAdminMenu (line 9) | function closeAdminMenu () {
FILE: lib/shared/actions/colors.js
function updateColor (line 3) | function updateColor (data) {
function addColor (line 23) | function addColor (data) {
function duplicateColor (line 43) | function duplicateColor (id) {
function removeColor (line 63) | function removeColor (id) {
FILE: lib/shared/actions/display.js
function changeDisplay (line 3) | function changeDisplay (value) {
FILE: lib/shared/actions/dnd.js
function startDragging (line 3) | function startDragging (draggingData, dragInfo) {
function onDroppable (line 11) | function onDroppable (dropInfo) {
function outDroppable (line 18) | function outDroppable (id) {
function stopDragging (line 25) | function stopDragging () {
FILE: lib/shared/actions/draft.js
function saveDraft (line 6) | function saveDraft () {
function dropDraft (line 39) | function dropDraft (fragments, id) {
FILE: lib/shared/actions/elements.js
function getElementData (line 4) | function getElementData (elementId, {query, variables}) {
FILE: lib/shared/actions/fonts.js
function changeFontsPreviewText (line 5) | function changeFontsPreviewText (value) {
function changeFontsPreviewLayout (line 12) | function changeFontsPreviewLayout (value) {
function changeFontInput (line 19) | function changeFontInput (tab, value) {
function loadFonts (line 27) | function loadFonts () {
function saveFonts (line 37) | function saveFonts () {
function changeFontInputAndUpdate (line 60) | function changeFontInputAndUpdate (tab, value) {
function _includeCustomFont (line 72) | function _includeCustomFont () {
function _submitCustomFont (line 112) | function _submitCustomFont (name, files, types) {
function submitCustomFont (line 140) | function submitCustomFont (name, files, types) {
function _removeCustomFont (line 152) | function _removeCustomFont (id) {
function removeCustomFont (line 171) | function removeCustomFont (id) {
FILE: lib/shared/actions/graphql.js
function graphql (line 4) | function graphql ({query, variables}, connectors) {
function removeConnector (line 16) | function removeConnector (id) {
FILE: lib/shared/actions/media.js
function changeMediaDisplay (line 6) | function changeMediaDisplay (display) {
function getMediaItem (line 13) | function getMediaItem (fragments, id) {
function uploadMedia (line 32) | function uploadMedia (fragments, file) {
function addingMedia (line 56) | function addingMedia (fileInfo) {
function addMedia (line 63) | function addMedia (fragments, file, fileInfo) {
function checkUploadQueue (line 81) | function checkUploadQueue (dispatch, getState) {
function uploadMediaFiles (line 156) | function uploadMediaFiles (files) {
function removeMediaItems (line 170) | function removeMediaItems (ids) {
function removeMediaItem (line 189) | function removeMediaItem (id) {
FILE: lib/shared/actions/menu.js
function addMenu (line 5) | function addMenu (data, redirect = false) {
function removeMenu (line 29) | function removeMenu (id, redirect) {
function updateMenuTitle (line 52) | function updateMenuTitle (_id, title) {
function updateMenuData (line 71) | function updateMenuData (_id) {
function draggedMenuItem (line 93) | function draggedMenuItem (dragInfo, dropInfo) {
FILE: lib/shared/actions/page-builder.js
function toggleEditing (line 6) | function toggleEditing () {
function setMenuOpened (line 12) | function setMenuOpened (value) {
function setMenuSide (line 19) | function setMenuSide (value) {
function setMenuTab (line 26) | function setMenuTab (value) {
function openElementsMenu (line 33) | function openElementsMenu (options) {
function closeElementsMenu (line 40) | function closeElementsMenu () {
function toggleCategory (line 46) | function toggleCategory (category) {
function toggleExpandElement (line 53) | function toggleExpandElement (elementId) {
function collapseAll (line 60) | function collapseAll () {
function expandAll (line 66) | function expandAll () {
function overElement (line 72) | function overElement (elementId) {
function outElement (line 79) | function outElement (elementId) {
function selectElement (line 86) | function selectElement (elementId) {
function duplicateElement (line 93) | function duplicateElement (elementId) {
function removeElement (line 103) | function removeElement (elementId) {
function toggleElementVisibleOn (line 113) | function toggleElementVisibleOn (elementId, display) {
function changeElementAnimation (line 124) | function changeElementAnimation (elementId, property, value) {
function changeElementPosition (line 136) | function changeElementPosition (elementId, property, value) {
function changeElementLabel (line 152) | function changeElementLabel (elementId, value) {
function changeElementStyle (line 163) | function changeElementStyle (elementId, property, value) {
function changeElementProperty (line 179) | function changeElementProperty (elementId, property, value) {
function changeElementContent (line 195) | function changeElementContent (elementId, value) {
function changeElementChildren (line 206) | function changeElementChildren (elementId, children) {
function elementAddSchemaLink (line 217) | function elementAddSchemaLink (elementId, propertyId, linkElementId, act...
function elementRemoveSchemaLink (line 230) | function elementRemoveSchemaLink (elementId, propertyId, index) {
function elementChangeSchemaLinkAction (line 242) | function elementChangeSchemaLinkAction (elementId, propertyId, index, va...
function undoAction (line 255) | function undoAction () {
function redoAction (line 261) | function redoAction () {
function addElementAt (line 267) | function addElementAt (element, destination) {
function makeElementDynamic (line 278) | function makeElementDynamic (elementId) {
function draggedComponent (line 288) | function draggedComponent (dragInfo, dropInfo) {
function linkFormDataMode (line 318) | function linkFormDataMode (elementId) {
function closeLinkFormDataMode (line 325) | function closeLinkFormDataMode (elementId) {
function linkDataMode (line 332) | function linkDataMode (elementId) {
function closeLinkDataMode (line 339) | function closeLinkDataMode () {
function extractChildren (line 345) | function extractChildren (children, data, draftData) {
function makeElementSymbol (line 354) | function makeElementSymbol (elementId, title) {
FILE: lib/shared/actions/page.js
function updatePage (line 7) | function updatePage (fragments, data) {
function publishPage (line 28) | function publishPage (_id) {
function unpublishPage (line 47) | function unpublishPage (_id) {
function updatePageTitle (line 66) | function updatePageTitle (_id, title) {
function updatePageSlug (line 85) | function updatePageSlug (_id, slug) {
function savePageFromDraft (line 104) | function savePageFromDraft (fragments, publish = false) {
function addPage (line 141) | function addPage (fragments, data, redirect = false) {
function removePage (line 168) | function removePage (id, redirect = false) {
function duplicatePage (line 191) | function duplicatePage (fragments, data) {
function restorePage (line 210) | function restorePage (fragments, pageId, version) {
function validatePageSlug (line 230) | function validatePageSlug ({slug, pageId}) {
function changePageFields (line 248) | function changePageFields (values) {
function changePageToDefault (line 255) | function changePageToDefault () {
FILE: lib/shared/actions/revisions.js
function getRevisions (line 6) | function getRevisions (fragments, id) {
FILE: lib/shared/actions/schema-entry.js
function addSchemaEntry (line 10) | function addSchemaEntry (schemaId, data, redirect = false) {
function updateSchemaEntry (line 41) | function updateSchemaEntry (fragments, schemaId, data) {
function restoreSchemaEntry (line 59) | function restoreSchemaEntry (fragments, schemaId, schemaEntryId, version) {
function validateSchemaEntrySlug (line 80) | function validateSchemaEntrySlug ({slug, schemaId, schemaEntryId}) {
function changeSchemaEntryFields (line 99) | function changeSchemaEntryFields (values) {
function changeSchemaEntryProperty (line 106) | function changeSchemaEntryProperty (key, value) {
function changeSchemaEntryToDefault (line 114) | function changeSchemaEntryToDefault () {
FILE: lib/shared/actions/schema-list.js
function removeSchemaEntry (line 5) | function removeSchemaEntry (fragments, schemaId, id) {
FILE: lib/shared/actions/schema.js
function changeSchemaType (line 10) | function changeSchemaType (schemaType) {
function changeSchemaTitle (line 17) | function changeSchemaTitle (title) {
function schemaStepBack (line 24) | function schemaStepBack () {
function schemaStepForward (line 30) | function schemaStepForward () {
function changeSchemaToDefault (line 36) | function changeSchemaToDefault () {
function addProperty (line 42) | function addProperty () {
function toggleProperty (line 48) | function toggleProperty (id) {
function changePropertySetting (line 55) | function changePropertySetting (id, settingId, value) {
function addSchema (line 64) | function addSchema (data, redirect = true) {
function updateSchema (line 89) | function updateSchema (fragments, data) {
function restoreSchema (line 108) | function restoreSchema (fragments, schemaId, version) {
function validateSchemaSlug (line 128) | function validateSchemaSlug ({slug, schemaId}) {
FILE: lib/shared/actions/schemas.js
function removeSchema (line 5) | function removeSchema (fragments, id) {
FILE: lib/shared/actions/session.js
function authenticate (line 4) | function authenticate (dispatch) {
FILE: lib/shared/actions/settings.js
function changeSettingValue (line 6) | function changeSettingValue (id, value) {
function saveSettings (line 14) | function saveSettings (fragments, data) {
FILE: lib/shared/actions/styles.js
function saveStyle (line 8) | function saveStyle (fragments, elementId, data) {
function changeStyleProp (line 31) | function changeStyleProp (styleId, property, value) {
function updateStyle (line 44) | function updateStyle (fragments, data) {
function removeStyle (line 63) | function removeStyle (styleId) {
FILE: lib/shared/actions/symbols.js
function getSymbol (line 5) | function getSymbol (symbolId, fragments) {
FILE: lib/shared/actions/tabs.js
function addTab (line 4) | function addTab (type, id) {
function removeTab (line 31) | function removeTab (id, redirect) {
FILE: lib/shared/actions/users.js
function removeUser (line 3) | function removeUser (id) {
function addUser (line 22) | function addUser (fragments, data) {
FILE: lib/shared/components/a.jsx
class A (line 6) | class A extends Component {
method onClick (line 14) | onClick (event) {
method render (line 24) | render () {
FILE: lib/shared/components/animate-props.jsx
class AnimateProps (line 6) | class AnimateProps extends Component {
method componentDidMount (line 18) | componentDidMount () {
method render (line 23) | render () {
FILE: lib/shared/components/animate.jsx
class Animate (line 6) | class Animate extends Component {
method componentDidMount (line 22) | componentDidMount () {
method componentWillReceiveProps (line 28) | componentWillReceiveProps (nextProps) {
method makeTransition (line 34) | makeTransition (props) {
method render (line 43) | render () {
FILE: lib/shared/components/background-image.jsx
class BackgroundImage (line 8) | class BackgroundImage extends Component {
method getInitState (line 26) | getInitState () {
method componentDidMount (line 32) | componentDidMount () {
method componentDidUpdate (line 36) | componentDidUpdate () {
method resize (line 40) | resize () {
method render (line 55) | render () {
FILE: lib/shared/components/button/index.jsx
class Button (line 8) | class Button extends Component {
method render (line 27) | render () {
FILE: lib/shared/components/component.jsx
class BaseComponent (line 3) | class BaseComponent extends React.Component {
method constructor (line 4) | constructor (props, context) {
method isClient (line 10) | isClient () {
FILE: lib/shared/components/dnd/draggable/draggable.jsx
constant LEFT_BUTTON (line 6) | const LEFT_BUTTON = 0;
class Draggable (line 8) | class Draggable extends Component {
method constructor (line 20) | constructor (props, children) {
method onMouseUp (line 26) | onMouseUp () {
method onMouseMove (line 31) | onMouseMove (event) {
method onMouseDown (line 58) | onMouseDown (event) {
method render (line 70) | render () {
FILE: lib/shared/components/dnd/draggable/index.js
class DraggableContainer (line 16) | class DraggableContainer extends Component {
method render (line 17) | render () {
FILE: lib/shared/components/dnd/dragger/dragger.jsx
class Dragger (line 10) | class Dragger extends Component {
method getInitState (line 25) | getInitState () {
method componentDidMount (line 33) | componentDidMount () {
method onMouseUp (line 55) | onMouseUp () {
method onMouseMove (line 65) | onMouseMove (event) {
method render (line 78) | render () {
FILE: lib/shared/components/dnd/dragger/index.js
class DraggerContainer (line 20) | class DraggerContainer extends Component {
method render (line 21) | render () {
FILE: lib/shared/components/dnd/droppable/add-ballon.jsx
class AddBallon (line 8) | class AddBallon extends Component {
method onClick (line 16) | onClick () {
method render (line 21) | render () {
FILE: lib/shared/components/dnd/droppable/droppable.jsx
class Droppable (line 13) | class Droppable extends Component {
method getInitState (line 56) | getInitState () {
method getChildContext (line 62) | getChildContext () {
method componentWillReceiveProps (line 83) | componentWillReceiveProps () {
method onMouseEnter (line 98) | @bind
method onMouseLeave (line 114) | @bind
method hasChildren (line 124) | hasChildren () {
method draggingSelf (line 137) | draggingSelf () {
method droppableHere (line 142) | droppableHere () {
method getEvents (line 172) | getEvents (droppableHere) {
method addSpotClick (line 182) | addSpotClick (position, dom) {
method render (line 193) | render () {
method renderDropMarkers (line 226) | renderDropMarkers (children) {
method renderAddMarkers (line 265) | renderAddMarkers (children) {
method renderMark (line 278) | renderMark (position) {
method renderPlaceholder (line 295) | renderPlaceholder () {
method renderDefaultPlaceholder (line 318) | renderDefaultPlaceholder () {
FILE: lib/shared/components/dnd/droppable/index.js
class DroppableContainer (line 36) | class DroppableContainer extends Component {
method render (line 41) | render () {
FILE: lib/shared/components/dnd/droppable/marker.jsx
class Marker (line 9) | class Marker extends Component {
method getInitState (line 17) | getInitState () {
method componentDidMount (line 23) | componentDidMount () {
method componentWillUnmount (line 28) | componentWillUnmount () {
method onMouseMove (line 32) | onMouseMove (event) {
method onMouseEnter (line 44) | onMouseEnter () {
method onMouseLeave (line 49) | onMouseLeave () {
method render (line 54) | render () {
FILE: lib/shared/components/image.jsx
class Image (line 5) | class Image extends Component {
method render (line 17) | render () {
FILE: lib/shared/components/medium-editor/index.jsx
class MediumEditorElement (line 8) | class MediumEditorElement extends Component {
method getInitState (line 21) | getInitState () {
method componentDidMount (line 28) | componentDidMount () {
method componentWillReceiveProps (line 33) | componentWillReceiveProps (nextProps) {
method componentWillUnmount (line 42) | componentWillUnmount () {
method onChange (line 46) | onChange () {
method render (line 52) | render () {
FILE: lib/shared/components/portal.jsx
class Portal (line 7) | class Portal extends Component {
method componentDidMount (line 13) | componentDidMount () {
method componentDidUpdate (line 21) | componentDidUpdate () {
method componentWillUnmount (line 25) | componentWillUnmount () {
method render (line 34) | render () {
FILE: lib/shared/decorators/bind.js
function bind (line 1) | function bind (target, key, {value: fn}) {
FILE: lib/shared/decorators/debounce.js
function debounce (line 1) | function debounce (delay = 300) {
FILE: lib/shared/decorators/query-props.jsx
function sanatizeQueryObject (line 7) | function sanatizeQueryObject (query) {
function getQueryVariables (line 17) | function getQueryVariables (query) {
function queryProps (line 69) | function queryProps (defaultQuery = _defaultQuery) {
FILE: lib/shared/elements/button/index.jsx
class Button (line 13) | class Button extends Component {
method componentWillReceiveProps (line 40) | componentWillReceiveProps (nextProps) {
method render (line 104) | render () {
method renderChildren (line 123) | renderChildren () {
FILE: lib/shared/elements/column/index.jsx
class Column (line 8) | class Column extends Component {
method render (line 27) | render () {
FILE: lib/shared/elements/columns/index.jsx
class Columns (line 11) | class Columns extends Component {
method render (line 32) | render () {
method renderChildren (line 40) | renderChildren () {
method renderColumn (line 136) | renderColumn (child, layout, left, right) {
method renderBlock (line 144) | renderBlock (child, layout, bottom) {
FILE: lib/shared/elements/component.jsx
class ElementComponent (line 7) | class ElementComponent extends Component {
method renderContent (line 13) | renderContent (customProps, children = this.props.children) {
method renderPlaceholder (line 40) | renderPlaceholder (options) {
FILE: lib/shared/elements/container/index.jsx
class Container (line 9) | class Container extends Component {
method render (line 20) | render () {
FILE: lib/shared/elements/counter/index.jsx
class Counter (line 10) | class Counter extends Component {
method getInitState (line 33) | getInitState () {
method onEnterScreen (line 39) | onEnterScreen () {
method render (line 45) | render () {
method renderCounter (line 66) | renderCounter () {
FILE: lib/shared/elements/date/index.jsx
class Counter (line 10) | class Counter extends Component {
method render (line 29) | render () {
FILE: lib/shared/elements/dynamic-list/container.jsx
class DynamicListContainer (line 22) | class DynamicListContainer extends Component {
method getInitState (line 51) | getInitState () {
method componentWillReceiveProps (line 56) | componentWillReceiveProps (nextProps) {
method fetchData (line 64) | fetchData (props) {
method render (line 84) | render () {
FILE: lib/shared/elements/dynamic-list/index.jsx
class DynamicList (line 8) | class DynamicList extends Component {
method render (line 18) | render () {
FILE: lib/shared/elements/dynamic-list/list.jsx
class List (line 9) | class List extends Component {
method isLinkingData (line 24) | isLinkingData () {
method render (line 29) | render () {
method renderRow (line 62) | renderRow (items, isLast) {
method renderItem (line 79) | renderItem (key, isFirst, isLast, dummy = false) {
FILE: lib/shared/elements/element/context-menu/context-menu.jsx
class ContextMenu (line 6) | class ContextMenu extends Component {
method saveSymbol (line 23) | saveSymbol (event) {
method makeDynamic (line 34) | makeDynamic (event) {
method duplicate (line 40) | duplicate (event) {
method remove (line 46) | remove (event) {
method render (line 52) | render () {
method renderOpened (line 57) | renderOpened () {
method renderClosed (line 62) | renderClosed () {
method renderAddingSymbol (line 70) | renderAddingSymbol () {
method renderActions (line 94) | renderActions () {
FILE: lib/shared/elements/element/context-menu/index.js
class ContextMenuContainer (line 18) | class ContextMenuContainer extends Component {
method getInitState (line 23) | getInitState () {
method openAddingSymbol (line 31) | openAddingSymbol () {
method closeAddingSymbol (line 37) | closeAddingSymbol () {
method onSymbolChange (line 43) | onSymbolChange (event) {
method open (line 49) | open () {
method close (line 55) | close () {
method render (line 61) | render () {
FILE: lib/shared/elements/element/element.jsx
class Element (line 13) | class Element extends Component {
method componentDidMount (line 43) | componentDidMount () {
method componentWillUnmount (line 57) | componentWillUnmount () {
method animate (line 69) | animate () {
method animationInit (line 79) | animationInit () {
method animationEditing (line 86) | animationEditing () {
method onScroll (line 93) | onScroll () {
method onElementClick (line 108) | onElementClick (event) {
method processAnimationStyle (line 114) | processAnimationStyle (style) {
method processPosition (line 121) | processPosition (style) {
method onMouseOver (line 155) | onMouseOver (event) {
method onMouseOut (line 166) | onMouseOut () {
method selectOut (line 173) | selectOut () {
method render (line 178) | render () {
method renderTag (line 207) | renderTag () {
method renderContent (line 235) | renderContent () {
method renderPlaceholder (line 261) | renderPlaceholder (options) {
method renderHighlight (line 268) | renderHighlight () {
FILE: lib/shared/elements/element/empty.jsx
class Empty (line 6) | class Empty extends Component {
method onClick (line 13) | onClick () {
method render (line 17) | render () {
FILE: lib/shared/elements/element/highlight.jsx
class Highlight (line 9) | class Highlight extends Component {
method componentDidMount (line 17) | componentDidMount () {
method componentWillUnmount (line 26) | componentWillUnmount () {
method onScroll (line 33) | onScroll () {
method onResize (line 38) | onResize () {
method updatePosition (line 43) | updatePosition () {
method getPosition (line 47) | getPosition () {
method render (line 57) | render () {
method renderContext (line 81) | renderContext () {
FILE: lib/shared/elements/element/index.js
class ElementContainer (line 24) | class ElementContainer extends Component {
method getInitState (line 34) | getInitState () {
method componentWillReceiveProps (line 43) | componentWillReceiveProps () {
method startAnimation (line 52) | startAnimation () {
method resetAnimation (line 59) | resetAnimation () {
method render (line 66) | render () {
FILE: lib/shared/elements/form/index.jsx
class Form (line 14) | class Form extends Component {
method sendEmail (line 26) | sendEmail (formData) {
method addToSchema (line 38) | addToSchema () {
method sendCustom (line 57) | sendCustom () {
method onSubmit (line 69) | onSubmit (event) {
method render (line 87) | render () {
FILE: lib/shared/elements/gap/index.jsx
class Gap (line 8) | class Gap extends Component {
method render (line 21) | render () {
FILE: lib/shared/elements/google-maps/index.jsx
class GoogleMapsElem (line 10) | class GoogleMapsElem extends Component {
method getInitState (line 39) | getInitState () {
method componentDidUpdate (line 45) | componentDidUpdate (prevProps) {
method loadAPI (line 51) | loadAPI () {
method onReady (line 81) | onReady () {
method render (line 87) | render () {
method renderMap (line 95) | renderMap () {
method renderMarker (line 155) | renderMarker () {
FILE: lib/shared/elements/icon/index.jsx
class Icon (line 11) | class Icon extends Component {
method render (line 30) | render () {
FILE: lib/shared/elements/image/index.jsx
class Image (line 15) | class Image extends Component {
method getInitState (line 47) | getInitState () {
method componentDidMount (line 53) | componentDidMount () {
method render (line 63) | render () {
method renderImage (line 98) | renderImage (imageStyle) {
method renderOverImage (line 124) | renderOverImage (imageStyle) {
FILE: lib/shared/elements/line-divider/index.jsx
class LineDivider (line 11) | class LineDivider extends Component {
method render (line 21) | render () {
FILE: lib/shared/elements/menu/entry.jsx
class Entry (line 7) | class Entry extends Component {
method getInitState (line 17) | getInitState () {
method componentWillUnmount (line 23) | componentWillUnmount () {
method onMouseOver (line 27) | onMouseOver () {
method onMouseOut (line 34) | onMouseOut () {
method close (line 38) | close () {
method render (line 44) | render () {
method renderEntryChildren (line 73) | renderEntryChildren () {
method renderEntry (line 89) | renderEntry (entry) {
method renderEntryLink (line 102) | renderEntryLink (href, label) {
FILE: lib/shared/elements/menu/index.jsx
class MenuContainer (line 34) | class MenuContainer extends Component {
method getInitState (line 55) | getInitState () {
method componentWillReceiveProps (line 60) | componentWillReceiveProps (nextProps) {
method fetchData (line 66) | fetchData (props) {
method render (line 82) | render () {
FILE: lib/shared/elements/menu/menu.jsx
class Menu (line 8) | class Menu extends Component {
method render (line 18) | render () {
method renderEntry (line 37) | renderEntry (entry) {
FILE: lib/shared/elements/music-player/container.jsx
constant CONSUMER_KEY (line 8) | const CONSUMER_KEY = '6c786345f5161898f1e1380802ce9226';
class PlayerContainer (line 10) | class PlayerContainer extends Component {
method getInitState (line 20) | getInitState () {
method componentDidUpdate (line 39) | componentDidUpdate () {
method componentWillUnmount (line 46) | componentWillUnmount () {
method loadSoundcloud (line 52) | loadSoundcloud () {
method soundcloudLoaded (line 59) | soundcloudLoaded (err, soundcloudInfo) {
method createSound (line 74) | createSound () {
method whileLoading (line 89) | whileLoading () {
method whilePlaying (line 108) | whilePlaying () {
method playingStatusChanged (line 132) | playingStatusChanged () {
method togglePlay (line 144) | togglePlay () {
method toggleMute (line 149) | toggleMute () {
method setVolume (line 162) | setVolume (perc) {
method goTo (line 177) | goTo (perc) {
method render (line 181) | render () {
FILE: lib/shared/elements/music-player/index.jsx
class MusicPlayer (line 10) | class MusicPlayer extends Component {
method render (line 24) | render () {
FILE: lib/shared/elements/music-player/player.jsx
class Player (line 9) | class Player extends Component {
method togglePlay (line 38) | togglePlay (event) {
method toggleMute (line 43) | toggleMute (event) {
method onProgressClick (line 48) | onProgressClick (event) {
method onVolumeClick (line 57) | onVolumeClick (event) {
method render (line 66) | render () {
method renderBackground (line 83) | renderBackground () {
method renderDivider (line 97) | renderDivider (classMap) {
method renderVolume (line 103) | renderVolume (classMap) {
method renderVolumeBar (line 120) | renderVolumeBar (classMap) {
method renderPlayback (line 136) | renderPlayback (classMap) {
method renderProgressBar (line 156) | renderProgressBar (classMap) {
method renderControls (line 179) | renderControls (classMap) {
FILE: lib/shared/elements/section/index.jsx
class Section (line 11) | class Section extends Component {
method render (line 35) | render () {
method renderBackground (line 62) | renderBackground () {
FILE: lib/shared/elements/symbol/container.jsx
class DynamicListContainer (line 17) | class DynamicListContainer extends Component {
method getInitState (line 33) | getInitState () {
method fetchSymbol (line 38) | fetchSymbol (props) {
method render (line 47) | render () {
FILE: lib/shared/elements/symbol/index.jsx
class Symbol (line 8) | class Symbol extends Component {
method render (line 13) | render () {
FILE: lib/shared/elements/text-box/index.jsx
class TextBox (line 13) | class TextBox extends Component {
method getStyle (line 39) | getStyle () {
method onChange (line 52) | onChange (value) {
method render (line 57) | render () {
method renderContent (line 72) | renderContent () {
FILE: lib/shared/elements/text-input/index.jsx
class TextInput (line 11) | class TextInput extends Component {
method render (line 23) | render () {
FILE: lib/shared/elements/textarea/index.jsx
class Textarea (line 10) | class Textarea extends Component {
method render (line 26) | render () {
FILE: lib/shared/elements/video/index.jsx
class Video (line 11) | class Video extends Component {
method getInitState (line 28) | getInitState () {
method componentDidMount (line 35) | componentDidMount () {
method componentWillUnmount (line 40) | componentWillUnmount () {
method onResize (line 44) | onResize () {
method render (line 54) | render () {
method renderIframe (line 62) | renderIframe () {
FILE: lib/shared/helpers/colors.js
function updateColors (line 8) | function updateColors (colors) {
function hexIsValid (line 12) | function hexIsValid (value) {
function getColor (line 16) | function getColor (colorObj, colors = colorsCollection) {
function getColorString (line 61) | function getColorString (colorObj, colors = colorsCollection) {
function applyBackground (line 75) | function applyBackground (style, colorObj, colors = colorsCollection) {
FILE: lib/shared/helpers/configure-store.js
function configureStore (line 16) | function configureStore (routerMiddleware, initialState) {
FILE: lib/shared/helpers/ga-send.js
function gaSend (line 1) | function gaSend () {
FILE: lib/shared/helpers/get-element-position.js
function getElementPosition (line 5) | function getElementPosition (element, display) {
FILE: lib/shared/helpers/get-element-props.js
function getElementProps (line 5) | function getElementProps (element, display) {
FILE: lib/shared/helpers/get-element-style-values.js
function getElementStyleValues (line 5) | function getElementStyleValues (defaults, options, displayOptions, displ...
FILE: lib/shared/helpers/load-fonts.js
function loadFonts (line 3) | function loadFonts (body) {
FILE: lib/shared/helpers/mime-types.js
constant IMAGE_MIME_TYPES (line 1) | const IMAGE_MIME_TYPES = [
constant ICON_MIME_TYPES (line 10) | const ICON_MIME_TYPES = ['image/vnd.microsoft.icon', 'image/x-icon'];
constant VIDEO_MIME_TYPES (line 11) | const VIDEO_MIME_TYPES = ['video/mp4', 'video/webm', 'video/ogg'];
constant AUDIO_MIME_TYPES (line 12) | const AUDIO_MIME_TYPES = ['audio/mp3', 'audio/mpeg', 'audio/ogg', 'audio...
function getMediaType (line 14) | function getMediaType (mimeType) {
function getMimeTypes (line 28) | function getMimeTypes (type) {
FILE: lib/shared/helpers/parse-fields.js
function parseFields (line 3) | function parseFields (data, keys) {
FILE: lib/shared/helpers/parse-settings.js
function parseSettings (line 3) | function parseSettings (_settings) {
FILE: lib/shared/helpers/request.js
function doRequest (line 4) | function doRequest (body) {
FILE: lib/shared/helpers/schema-filter-default-options.js
function getFilterDefaultOptions (line 1) | function getFilterDefaultOptions (type) {
FILE: lib/shared/helpers/stringify-fields.js
function stringifyFields (line 3) | function stringifyFields (data, keys) {
FILE: lib/shared/helpers/styles-manager.js
class StylesManager (line 7) | class StylesManager {
method constructor (line 8) | constructor () {
method changeStyle (line 13) | changeStyle (id, styleOptions, options, displayOptions, display, singl...
method getClassMap (line 36) | getClassMap (id, styleOptions, options, displayOptions, display, singl...
method getStyleOptions (line 54) | getStyleOptions (style, elements) {
method processElement (line 66) | processElement (element, elementProps, ElementClass, styles, elements,...
FILE: lib/shared/helpers/utils.js
method isPercentage (line 8) | isPercentage (str) {
method roundSnap (line 12) | roundSnap (value, snaps) {
method pointsDistance (line 22) | pointsDistance (p1, p2) {
method getPointInLineByPerc (line 28) | getPointInLineByPerc (pointA, pointB, perc) {
method validateGATrackingId (line 36) | validateGATrackingId (str) {
method makeBorder (line 40) | makeBorder (style, property, border) {
method applyBorders (line 46) | applyBorders (style, borderObj) {
method applyTextShadows (line 59) | applyTextShadows (style, shadows) {
method applyBoxShadows (line 66) | applyBoxShadows (style, shadows) {
method parseYoutubeURL (line 77) | parseYoutubeURL (url) {
method parseVimeoURL (line 89) | parseVimeoURL (url) {
method parseDailymotionURL (line 101) | parseDailymotionURL (url) {
method parseColumnsDisplay (line 113) | parseColumnsDisplay (value, numChildren, multiRows, idChanged = -1) {
method getOffsetRect (line 227) | getOffsetRect (elem) {
method limitNumber (line 250) | limitNumber (number, min, max) {
method hasClass (line 262) | hasClass (dom, className) {
method addClass (line 266) | addClass (dom, className) {
method removeClass (line 272) | removeClass (dom, className) {
method getBestImageVariation (line 279) | getBestImageVariation (variations, width, height = 0) {
method getBestImageUrl (line 293) | getBestImageUrl (imageId, width = 0, height = 0) {
method parseQueryUrl (line 303) | parseQueryUrl (url, query) {
method parseQueryString (line 315) | parseQueryString (queryString) {
method _getPropSchemaListIt (line 332) | _getPropSchemaListIt (propsSchema, list, defaultLabel = '') {
method getPropSchemaList (line 353) | getPropSchemaList (propsSchema) {
method filterFontFamily (line 359) | filterFontFamily (str) {
method filterFVD (line 364) | filterFVD (fvd) {
method getRGBA (line 388) | getRGBA (hex, opacity) {
method border (line 395) | border (arr, size, style, color, opacity) {
method isClient (line 401) | isClient () {
method rounded (line 405) | rounded (arr, corners) {
method backgroundRGBA (line 412) | backgroundRGBA (arr, color, opacity) {
method transition (line 416) | transition (arr, to, time, ease) {
method translate (line 424) | translate (arr, x, y) {
method padding (line 433) | padding (arr, top, right, bottom, left) {
method processFVD (line 438) | processFVD (style, fvd) {
method getElementsSchemaLinks (line 459) | getElementsSchemaLinks (schemaLinks) {
method alterSchemaElementProps (line 475) | alterSchemaElementProps (links, element, schemaEntry, elementProps = {}) {
FILE: lib/shared/reducers/admin-menu.js
function adminMenuReducer (line 5) | function adminMenuReducer (state = defaultState, action = {}) {
FILE: lib/shared/reducers/display.js
function displayReducer (line 5) | function displayReducer (state = defaultState, action = {}) {
FILE: lib/shared/reducers/dnd.js
function dndReducer (line 11) | function dndReducer (state = defaultState, action = {}) {
FILE: lib/shared/reducers/fonts.js
function parseSettings (line 40) | function parseSettings (_settings) {
function fontsReducer (line 50) | function fontsReducer (state = defaultState, action = {}) {
FILE: lib/shared/reducers/media.js
function changeUploadStatus (line 9) | function changeUploadStatus ({state, id, status}) {
function mediaReducer (line 22) | function mediaReducer (state = defaultState, action = {}) {
FILE: lib/shared/reducers/menu.js
function getLastId (line 7) | function getLastId (data) {
function menuReducer (line 14) | function menuReducer (state = defaultState, action = {}) {
FILE: lib/shared/reducers/page-builder-actions/helpers/clone-children.js
function cloneChildren (line 6) | function cloneChildren (children, data, changes, parentId) {
FILE: lib/shared/reducers/page-builder-actions/helpers/get-id.js
constant ID_COUNTER (line 1) | let ID_COUNTER = 0;
function getLastId (line 2) | function getLastId (data) {
FILE: lib/shared/reducers/page-builder-actions/helpers/remove-children.js
function removeChildren (line 3) | function removeChildren (children, copiedData) {
FILE: lib/shared/reducers/page-builder.js
function doAction (line 52) | function doAction (data, action) {
function getElementPath (line 78) | function getElementPath (selectedElement, data) {
function inPath (line 90) | function inPath (elementId, targetId, data) {
function checkOverAndSelected (line 104) | function checkOverAndSelected (state) {
function pageBuilderReducer (line 137) | function pageBuilderReducer (state = defaultState, action = {}) {
FILE: lib/shared/reducers/revisions.js
function colorsReducer (line 8) | function colorsReducer (state = defaultState, action = {}) {
FILE: lib/shared/reducers/schema-entry.js
function schemaEntryReducer (line 15) | function schemaEntryReducer (state = defaultState, action = {}) {
FILE: lib/shared/reducers/schema.js
function getUniqueId (line 15) | function getUniqueId (properties, idParam, count = 0) {
function findPropertyBydId (line 35) | function findPropertyBydId (properties, id) {
function schemaReducer (line 51) | function schemaReducer (state = defaultState, action = {}) {
FILE: lib/shared/reducers/session.js
function sessionReducer (line 7) | function sessionReducer (state = defaultState, action = {}) {
FILE: lib/shared/reducers/settings.js
function parseSettings (line 9) | function parseSettings (_settings) {
function settingsReducer (line 19) | function settingsReducer (state = defaultState, action = {}) {
FILE: lib/shared/reducers/styles.js
function stylesReducer (line 15) | function stylesReducer (state = defaultState, action = {}) {
FILE: lib/shared/reducers/symbols.js
function symbolsReducer (line 8) | function symbolsReducer (state = defaultState, action = {}) {
FILE: lib/shared/routers/admin.js
function authenticate (line 25) | function authenticate (nextState, replaceState, callback) {
FILE: lib/shared/screens/admin/components/admin/index.jsx
class Admin (line 12) | class Admin extends Component {
method getInitState (line 21) | getInitState () {
method componentWillReceiveProps (line 28) | componentWillReceiveProps (nextProps) {
method render (line 57) | render () {
method renderMenuContent (line 75) | renderMenuContent () {
FILE: lib/shared/screens/admin/components/loading/index.jsx
class Loading (line 7) | class Loading extends Component {
method render (line 8) | render () {
FILE: lib/shared/screens/admin/components/menu/content-types.jsx
class ContentTypes (line 9) | class ContentTypes extends Component {
method render (line 24) | render () {
method renderSchema (line 39) | renderSchema (schema) {
FILE: lib/shared/screens/admin/components/menu/index.js
class MenuContainer (line 29) | class MenuContainer extends Component {
method onActiveClick (line 96) | @bind
method render (line 101) | render () {
FILE: lib/shared/screens/admin/components/menu/menu.jsx
class Menu (line 13) | class Menu extends Component {
method getInitState (line 32) | getInitState () {
method componentWillReceiveProps (line 38) | componentWillReceiveProps (nextProps) {
method render (line 59) | render () {
method renderEntry (line 82) | renderEntry (entry, key) {
FILE: lib/shared/screens/admin/components/menu/user.jsx
class User (line 10) | class User extends Component {
method getInitState (line 23) | getInitState () {
method toggleOpened (line 29) | @bind
method render (line 36) | render () {
FILE: lib/shared/screens/admin/components/top-bar/actions/actions.jsx
class Actions (line 10) | class Actions extends Component {
method render (line 22) | render () {
method renderDisplay (line 34) | renderDisplay () {
method renderStatuses (line 41) | renderStatuses () {
method renderRightMenu (line 52) | renderRightMenu () {
FILE: lib/shared/screens/admin/components/top-bar/actions/back.jsx
class Back (line 7) | class Back extends Component {
method render (line 16) | render () {
FILE: lib/shared/screens/admin/components/top-bar/actions/display.jsx
class DisplayButton (line 8) | class DisplayButton extends Component {
method onClick (line 16) | @bind
method render (line 22) | render () {
FILE: lib/shared/screens/admin/components/top-bar/actions/displays.jsx
class Displays (line 8) | class Displays extends Component {
method render (line 34) | render () {
method renderButton (line 56) | renderButton ({display, icon}) {
FILE: lib/shared/screens/admin/components/top-bar/actions/index.js
class ActionsContainer (line 59) | class ActionsContainer extends Component {
method getInitState (line 71) | getInitState () {
method componentWillReceiveProps (line 84) | componentWillReceiveProps (nextProps) {
method componentWillUnmount (line 93) | componentWillUnmount () {
method preventNavigation (line 98) | preventNavigation (event) {
method saveDraft (line 106) | saveDraft () {
method autosave (line 114) | @bind
method outSuccess (line 219) | @bind
method render (line 240) | render () {
FILE: lib/shared/screens/admin/components/top-bar/actions/right-menu.jsx
class RightMenu (line 7) | class RightMenu extends Component {
method render (line 13) | render () {
FILE: lib/shared/screens/admin/components/top-bar/actions/statuses.jsx
class Statuses (line 9) | class Statuses extends Component {
method render (line 17) | render () {
method renderState (line 34) | renderState () {
method renderBehind (line 70) | renderBehind () {
method renderEditing (line 81) | renderEditing () {
method renderPublished (line 92) | renderPublished () {
FILE: lib/shared/screens/admin/components/top-bar/index.jsx
class TopBar (line 9) | class TopBar extends Component {
method componentWillReceiveProps (line 15) | componentWillReceiveProps (nextProps) {
method render (line 33) | render () {
FILE: lib/shared/screens/admin/components/top-bar/tabs/index.js
class TabsContainer (line 25) | class TabsContainer extends Component {
method render (line 37) | render () {
FILE: lib/shared/screens/admin/components/top-bar/tabs/tab.jsx
class Tab (line 9) | class Tab extends Component {
method onCloseTab (line 29) | @bind
method getLink (line 40) | getLink () {
method render (line 59) | render () {
FILE: lib/shared/screens/admin/components/top-bar/tabs/tabs.jsx
class Tabs (line 7) | class Tabs extends Component {
method render (line 18) | render () {
method renderTab (line 29) | renderTab (tab, key) {
FILE: lib/shared/screens/admin/index.js
class AdminContainer (line 20) | class AdminContainer extends Component {
method render (line 25) | render () {
FILE: lib/shared/screens/admin/screens/colors/components/colors.jsx
class Colors (line 11) | class Colors extends Component {
method render (line 22) | render () {
FILE: lib/shared/screens/admin/screens/colors/components/entry.jsx
class Entry (line 7) | class Entry extends Component {
method duplicate (line 22) | duplicate () {
method remove (line 27) | remove () {
method render (line 32) | render () {
FILE: lib/shared/screens/admin/screens/colors/components/list.jsx
class List (line 7) | class List extends Component {
method render (line 24) | render () {
method renderEntry (line 33) | renderEntry (color) {
FILE: lib/shared/screens/admin/screens/colors/index.js
class ColorsContainer (line 27) | class ColorsContainer extends Component {
method getInitState (line 38) | getInitState () {
method searchChange (line 44) | searchChange (search) {
method render (line 50) | render () {
FILE: lib/shared/screens/admin/screens/fonts/components/entry.jsx
class Entry (line 8) | class Entry extends Component {
method render (line 16) | render () {
FILE: lib/shared/screens/admin/screens/fonts/components/fonts.jsx
class Fonts (line 14) | class Fonts extends Component {
method render (line 29) | render () {
method renderManage (line 49) | renderManage () {
FILE: lib/shared/screens/admin/screens/fonts/components/list.jsx
class List (line 7) | class List extends Component {
method render (line 14) | render () {
FILE: lib/shared/screens/admin/screens/fonts/components/manage/index.js
class ManageContainer (line 33) | class ManageContainer extends Component {
method getInitState (line 34) | getInitState () {
method changeTab (line 40) | changeTab (tab) {
method render (line 46) | render () {
FILE: lib/shared/screens/admin/screens/fonts/components/manage/manage.jsx
class Manage (line 8) | class Manage extends Component {
method changeTab (line 18) | changeTab (tab) {
method render (line 22) | render () {
method renderTabButton (line 38) | renderTabButton (tabButton, index) {
method renderContent (line 51) | renderContent () {
FILE: lib/shared/screens/admin/screens/fonts/components/preview-text.jsx
class PreviewText (line 6) | class PreviewText extends Component {
method onChange (line 12) | onChange (event) {
method render (line 16) | render () {
FILE: lib/shared/screens/admin/screens/fonts/index.js
class FontsContainer (line 36) | class FontsContainer extends Component {
method getInitState (line 41) | getInitState () {
method changeDisplay (line 49) | changeDisplay (display) {
method changePreviewText (line 55) | changePreviewText (value) {
method openManage (line 61) | openManage () {
method closeManage (line 67) | closeManage () {
method render (line 73) | render () {
FILE: lib/shared/screens/admin/screens/media/components/entry.jsx
class MediaEntry (line 11) | class MediaEntry extends Component {
method onClick (line 32) | @bind
method render (line 38) | render () {
method renderExtraInfo (line 58) | renderExtraInfo () {
FILE: lib/shared/screens/admin/screens/media/components/list.jsx
class MediaList (line 6) | class MediaList extends Component {
method render (line 18) | render () {
method renderEntry (line 28) | renderEntry (mediaItem) {
FILE: lib/shared/screens/admin/screens/media/components/media.jsx
class Media (line 18) | class Media extends Component {
method render (line 47) | render () {
method renderContent (line 57) | renderContent () {
method renderNoContent (line 68) | renderNoContent () {
method renderHasContent (line 93) | renderHasContent () {
method renderSearchOrSelect (line 126) | renderSearchOrSelect () {
method renderDeleteConfirm (line 152) | renderDeleteConfirm () {
FILE: lib/shared/screens/admin/screens/media/components/menu.jsx
class MediaMenu (line 11) | class MediaMenu extends Component {
method getQuery (line 20) | getQuery (type) {
method render (line 31) | render () {
FILE: lib/shared/screens/admin/screens/media/components/sorting.jsx
class Sorting (line 8) | class Sorting extends Component {
method reverseOrder (line 15) | reverseOrder (order) {
method render (line 19) | render () {
method renderSort (line 30) | renderSort (label, property) {
FILE: lib/shared/screens/admin/screens/media/components/uploading/index.js
class UploadingContainer (line 13) | class UploadingContainer extends Component {
method getInitState (line 18) | getInitState () {
method toggleOpened (line 24) | @bind
method render (line 31) | render () {
FILE: lib/shared/screens/admin/screens/media/components/uploading/item.jsx
class UploadItem (line 9) | class UploadItem extends Component {
method render (line 15) | render () {
method renderStatus (line 25) | renderStatus () {
FILE: lib/shared/screens/admin/screens/media/components/uploading/uploading.jsx
class Uploading (line 10) | class Uploading extends Component {
method componentWillReceiveProps (line 17) | componentWillReceiveProps (nextProps) {
method render (line 32) | render () {
method renderUpload (line 59) | renderUpload (item) {
FILE: lib/shared/screens/admin/screens/media/index.js
class MediaContainer (line 78) | class MediaContainer extends Component {
method getInitState (line 97) | getInitState () {
method componentWillReceiveProps (line 105) | componentWillReceiveProps (nextProps) {
method updateMedia (line 114) | updateMedia (props) {
method toggleMediaSelection (line 143) | @bind
method unselectAll (line 161) | @bind
method searchChange (line 168) | @bind
method updateSearch (line 176) | @debounce(300)
method onRemoveSelected (line 185) | @bind
method cancelRemoveSelected (line 192) | @bind
method removeSelected (line 199) | @bind
method render (line 211) | render () {
FILE: lib/shared/screens/admin/screens/media/menu.js
class MediaMenuContainer (line 21) | class MediaMenuContainer extends Component {
method componentDidMount (line 29) | componentDidMount () {
method onBack (line 33) | @bind
method render (line 38) | render () {
FILE: lib/shared/screens/admin/screens/menus/components/content.jsx
class Content (line 7) | class Content extends Component {
method render (line 13) | render () {
method renderEmpty (line 27) | renderEmpty () {
method renderNoMenus (line 36) | renderNoMenus () {
FILE: lib/shared/screens/admin/screens/menus/components/entry.jsx
class MenuEntry (line 9) | class MenuEntry extends Component {
method render (line 24) | render () {
FILE: lib/shared/screens/admin/screens/menus/components/list.jsx
class MenusList (line 6) | class MenusList extends Component {
method render (line 17) | render () {
method renderEntry (line 25) | renderEntry (menu, key) {
FILE: lib/shared/screens/admin/screens/menus/components/menu.jsx
class Menu (line 45) | class Menu extends Component {
method render (line 62) | render () {
method renderNew (line 88) | renderNew () {
FILE: lib/shared/screens/admin/screens/menus/components/new/index.js
class NewMenuContainer (line 7) | class NewMenuContainer extends Component {
method getInitState (line 16) | getInitState () {
method changeTitle (line 23) | changeTitle (title) {
method submit (line 29) | submit () {
method render (line 44) | render () {
FILE: lib/shared/screens/admin/screens/menus/components/new/new.jsx
class NewMenu (line 6) | class NewMenu extends Component {
method render (line 14) | render () {
FILE: lib/shared/screens/admin/screens/menus/index.js
class MenusContainer (line 24) | class MenusContainer extends Component {
method render (line 30) | render () {
FILE: lib/shared/screens/admin/screens/menus/menu.js
class MenusMenuContainer (line 45) | class MenusMenuContainer extends Component {
method getInitState (line 60) | getInitState () {
method componentDidMount (line 66) | componentDidMount () {
method componentWillReceiveProps (line 70) | componentWillReceiveProps (nextProps) {
method onBack (line 83) | onBack () {
method onNew (line 87) | onNew () {
method closeNew (line 93) | closeNew () {
method render (line 99) | render () {
FILE: lib/shared/screens/admin/screens/menus/screens/menu/components/menu-builder/builder.jsx
class MenuBuilder (line 12) | class MenuBuilder extends Component {
method render (line 13) | render () {
FILE: lib/shared/screens/admin/screens/menus/screens/menu/components/menu-builder/collapsable.jsx
class Collapsable (line 8) | class Collapsable extends Component {
method getInitState (line 20) | getInitState () {
method onClick (line 26) | @bind
method render (line 33) | render () {
FILE: lib/shared/screens/admin/screens/menus/screens/menu/components/menu-builder/entry.jsx
class MenuEntry (line 11) | class MenuEntry extends Component {
method render (line 25) | render () {
method renderChildren (line 50) | renderChildren () {
method renderPlaceholder (line 68) | @bind
FILE: lib/shared/screens/admin/screens/menus/screens/menu/components/menu-builder/index.js
class MenuBuilderContainer (line 6) | class MenuBuilderContainer extends Component {
method render (line 7) | render () {
FILE: lib/shared/screens/admin/screens/menus/screens/menu/components/menu-builder/link/index.js
class LinkContainer (line 7) | class LinkContainer extends Component {
method getInitState (line 8) | getInitState () {
method changeLabel (line 15) | @bind
method changeUrl (line 22) | @bind
method render (line 29) | render () {
FILE: lib/shared/screens/admin/screens/menus/screens/menu/components/menu-builder/link/link.jsx
class Link (line 8) | class Link extends Component {
method render (line 16) | render () {
FILE: lib/shared/screens/admin/screens/menus/screens/menu/components/menu-builder/menu/index.js
class MenuContainer (line 31) | class MenuContainer extends Component {
method componentWillReceiveProps (line 36) | componentWillReceiveProps (nextProps) {
method render (line 46) | render () {
FILE: lib/shared/screens/admin/screens/menus/screens/menu/components/menu-builder/menu/menu.jsx
class Menu (line 12) | class Menu extends Component {
method render (line 27) | render () {
method renderChildren (line 51) | renderChildren (children) {
method renderEntry (line 55) | renderEntry (id, index) {
method renderPlaceholder (line 73) | @bind
method renderDragger (line 109) | renderDragger () {
FILE: lib/shared/screens/admin/screens/menus/screens/menu/components/menu-builder/pages/index.js
class MenuBuilderContainer (line 12) | class MenuBuilderContainer extends Component {
method render (line 21) | render () {
FILE: lib/shared/screens/admin/screens/menus/screens/menu/components/menu-builder/pages/pages.jsx
class PagesList (line 8) | class PagesList extends Component {
method render (line 21) | render () {
method renderPages (line 29) | renderPages () {
method renderPage (line 50) | renderPage (page) {
FILE: lib/shared/screens/admin/screens/menus/screens/menu/components/menu.jsx
class Menu (line 14) | class Menu extends Component {
method render (line 33) | render () {
method renderState (line 57) | renderState () {
method renderDeleteConfirm (line 62) | renderDeleteConfirm () {
FILE: lib/shared/screens/admin/screens/menus/screens/menu/components/state.jsx
class MenuState (line 9) | class MenuState extends Component {
method render (line 15) | render () {
FILE: lib/shared/screens/admin/screens/menus/screens/menu/index.js
class MenuContainer (line 30) | class MenuContainer extends Component {
method getInitState (line 39) | getInitState () {
method componentWillReceiveProps (line 45) | componentWillReceiveProps (nextProps) {
method onDelete (line 55) | @bind
method cancelDelete (line 62) | @bind
method confirmDelete (line 69) | @bind
method updateTitle (line 75) | @bind
method successOut (line 81) | @debounce(2000)
method saveMenu (line 88) | @bind
method render (line 106) | render () {
FILE: lib/shared/screens/admin/screens/pages/components/entry.jsx
class PagesEntry (line 9) | class PagesEntry extends Component {
method render (line 25) | render () {
FILE: lib/shared/screens/admin/screens/pages/components/list.jsx
class PagesList (line 6) | class PagesList extends Component {
method render (line 17) | render () {
method renderEntry (line 25) | renderEntry (page, key) {
FILE: lib/shared/screens/admin/screens/pages/components/menu.jsx
class PagesMenu (line 45) | class PagesMenu extends Component {
method render (line 62) | render () {
method renderNew (line 88) | renderNew () {
FILE: lib/shared/screens/admin/screens/pages/components/new/index.js
class NewPageContainer (line 7) | class NewPageContainer extends Component {
method getInitState (line 17) | getInitState () {
method changeTitle (line 24) | changeTitle (title) {
method submit (line 30) | submit () {
method render (line 45) | render () {
FILE: lib/shared/screens/admin/screens/pages/components/new/new.jsx
class NewPage (line 6) | class NewPage extends Component {
method render (line 14) | render () {
FILE: lib/shared/screens/admin/screens/pages/components/pages.jsx
class Pages (line 8) | class Pages extends Component {
method render (line 14) | render () {
method renderEmpty (line 28) | renderEmpty () {
method renderNoPages (line 37) | renderNoPages () {
FILE: lib/shared/screens/admin/screens/pages/index.js
class PagesContainer (line 14) | class PagesContainer extends Component {
method render (line 20) | render () {
FILE: lib/shared/screens/admin/screens/pages/menu.js
class PagesContainer (line 47) | class PagesContainer extends Component {
method getInitState (line 62) | getInitState () {
method componentDidMount (line 68) | componentDidMount () {
method componentWillReceiveProps (line 72) | componentWillReceiveProps (nextProps) {
method onBack (line 87) | onBack () {
method onNew (line 91) | onNew () {
method closeNew (line 97) | closeNew () {
method render (line 103) | render () {
FILE: lib/shared/screens/admin/screens/pages/screens/page/components/info/index.js
class PageInfoContainer (line 29) | class PageInfoContainer extends Component {
method onDelete (line 34) | @bind
method publishPage (line 40) | @bind
method unpublishPage (line 46) | @bind
method render (line 52) | render () {
FILE: lib/shared/screens/admin/screens/pages/screens/page/components/info/info.jsx
class PageInfo (line 9) | class PageInfo extends Component {
method render (line 40) | render () {
method renderStatus (line 66) | renderStatus () {
method renderDraftStatus (line 79) | renderDraftStatus () {
method renderPublishedStatus (line 92) | renderPublishedStatus () {
FILE: lib/shared/screens/admin/screens/pages/screens/page/components/info/item.jsx
class InfoItem (line 7) | class InfoItem extends Component {
method render (line 15) | render () {
FILE: lib/shared/screens/admin/screens/pages/screens/page/components/page.jsx
class Page (line 19) | class Page extends Component {
method getInitState (line 44) | getInitState () {
method componentWillReceiveProps (line 51) | componentWillReceiveProps (nextProps) {
method render (line 80) | render () {
method renderContent (line 97) | renderContent () {
method renderSidebar (line 138) | renderSidebar () {
method renderSidebarContent (line 148) | renderSidebarContent () {
FILE: lib/shared/screens/admin/screens/pages/screens/page/components/revisions/index.js
class PageRevisionsContainer (line 4) | class PageRevisionsContainer extends Component {
method render (line 5) | render () {
FILE: lib/shared/screens/admin/screens/pages/screens/page/index.js
class PageContainer (line 31) | class PageContainer extends Component {
method getInitState (line 40) | getInitState () {
method componentWillReceiveProps (line 47) | componentWillReceiveProps (nextProps) {
method processTab (line 66) | processTab (props) {
method updateTitle (line 73) | @bind
method updateSlug (line 79) | @bind
method togglePageInfo (line 85) | @bind
method togglePageRevisions (line 93) | @bind
method render (line 101) | render () {
FILE: lib/shared/screens/admin/screens/schemas/screens/new/components/builder/builder.jsx
class SchemaBuilder (line 14) | class SchemaBuilder extends Component {
method render (line 19) | render () {
FILE: lib/shared/screens/admin/screens/schemas/screens/new/components/builder/index.js
class SchemasBuilder (line 17) | class SchemasBuilder extends Component {
method render (line 18) | render () {
FILE: lib/shared/screens/admin/screens/schemas/screens/new/components/builder/model.jsx
class SchemaModel (line 10) | class SchemaModel extends Component {
method onDone (line 18) | @bind
method render (line 24) | render () {
method renderSchemaType (line 48) | renderSchemaType (type) {
FILE: lib/shared/screens/admin/screens/schemas/screens/new/components/builder/name.jsx
class SchemaName (line 8) | class SchemaName extends Component {
method render (line 16) | render () {
method renderSchemaType (line 44) | renderSchemaType (type) {
FILE: lib/shared/screens/admin/screens/schemas/screens/new/components/builder/properties/index.js
class SchemasBuilderPropertiesContainer (line 17) | class SchemasBuilderPropertiesContainer extends Component {
method render (line 18) | render () {
FILE: lib/shared/screens/admin/screens/schemas/screens/new/components/builder/properties/properties.jsx
class SchemaProperties (line 8) | class SchemaProperties extends Component {
method render (line 17) | render () {
method renderProperty (line 30) | renderProperty (property, key) {
FILE: lib/shared/screens/admin/screens/schemas/screens/new/components/builder/properties/property-options.jsx
class SchemaPropertyOptions (line 9) | class SchemaPropertyOptions extends Component {
method onChange (line 15) | @bind
method render (line 21) | render () {
FILE: lib/shared/screens/admin/screens/schemas/screens/new/components/builder/properties/property.jsx
class SchemaProperty (line 9) | class SchemaProperty extends Component {
method onToggle (line 17) | @bind
method render (line 23) | render () {
method renderIcon (line 42) | renderIcon () {
method renderOpened (line 62) | renderOpened () {
FILE: lib/shared/screens/admin/screens/schemas/screens/new/components/builder/type.jsx
class SchemaType (line 7) | class SchemaType extends Component {
method onClick (line 16) | @bind
method render (line 22) | render () {
FILE: lib/shared/screens/admin/screens/schemas/screens/new/components/builder/types.jsx
class SchemaTypes (line 7) | class SchemaTypes extends Component {
method render (line 12) | render () {
FILE: lib/shared/screens/admin/screens/schemas/screens/new/index.js
class SchemasNewContainer (line 6) | class SchemasNewContainer extends Component {
method render (line 7) | render () {
FILE: lib/shared/screens/admin/screens/schemas/screens/schema/components/entry.jsx
class SchemaEntry (line 9) | class SchemaEntry extends Component {
method render (line 25) | render () {
FILE: lib/shared/screens/admin/screens/schemas/screens/schema/components/list.jsx
class SchemaEntriesList (line 6) | class SchemaEntriesList extends Component {
method render (line 17) | render () {
method renderEntry (line 25) | renderEntry (schemaEntry, key) {
FILE: lib/shared/screens/admin/screens/schemas/screens/schema/components/menu.jsx
class SchemaMenu (line 46) | class SchemaMenu extends Component {
method render (line 71) | render () {
method renderNew (line 101) | renderNew () {
FILE: lib/shared/screens/admin/screens/schemas/screens/schema/components/new/index.js
class NewSchemaEntryContainer (line 8) | class NewSchemaEntryContainer extends Component {
method getInitState (line 18) | getInitState () {
method changeTitle (line 25) | @bind
method submit (line 32) | @bind
method render (line 48) | render () {
FILE: lib/shared/screens/admin/screens/schemas/screens/schema/components/new/new.jsx
class NewSchemaEntry (line 6) | class NewSchemaEntry extends Component {
method render (line 14) | render () {
FILE: lib/shared/screens/admin/screens/schemas/screens/schema/components/schema.jsx
class Schema (line 7) | class Schema extends Component {
method render (line 14) | render () {
method renderEmpty (line 28) | renderEmpty () {
method renderNoPages (line 37) | renderNoPages () {
FILE: lib/shared/screens/admin/screens/schemas/screens/schema/index.js
class SchemaContainer (line 35) | class SchemaContainer extends Component {
method render (line 41) | render () {
FILE: lib/shared/screens/admin/screens/schemas/screens/schema/menu.js
class SchemaMenuContainer (line 56) | class SchemaMenuContainer extends Component {
method getInitState (line 74) | getInitState () {
method componentDidMount (line 80) | componentDidMount () {
method componentWillReceiveProps (line 84) | componentWillReceiveProps (nextProps) {
method onBack (line 103) | @bind
method onNew (line 108) | @bind
method closeNew (line 115) | @bind
method render (line 122) | render () {
FILE: lib/shared/screens/admin/screens/settings/components/menu.jsx
class SettingsMenu (line 9) | class SettingsMenu extends Component {
method render (line 15) | render () {
FILE: lib/shared/screens/admin/screens/settings/menu.js
class SettingsMenuContainer (line 17) | class SettingsMenuContainer extends Component {
method componentDidMount (line 24) | componentDidMount () {
method onBack (line 28) | @bind
method render (line 33) | render () {
FILE: lib/shared/screens/admin/screens/settings/screens/analytics/components/analytics.jsx
class AnalyticsSettings (line 6) | class AnalyticsSettings extends Component {
method render (line 11) | render () {
FILE: lib/shared/screens/admin/screens/settings/screens/analytics/index.js
class AnalyticsSettingsContainer (line 17) | class AnalyticsSettingsContainer extends Component {
method render (line 20) | render () {
FILE: lib/shared/screens/admin/screens/settings/screens/data/components/data.jsx
class DataSettings (line 4) | class DataSettings extends Component {
method render (line 7) | render () {
FILE: lib/shared/screens/admin/screens/settings/screens/data/index.js
class DataSettingsContainer (line 6) | class DataSettingsContainer extends Component {
method render (line 9) | render () {
FILE: lib/shared/screens/admin/screens/settings/screens/email/components/email.jsx
class EmailSettings (line 6) | class EmailSettings extends Component {
method render (line 11) | render () {
FILE: lib/shared/screens/admin/screens/settings/screens/email/index.js
class EmailSettingsContainer (line 65) | class EmailSettingsContainer extends Component {
method render (line 68) | render () {
FILE: lib/shared/screens/admin/screens/settings/screens/general/components/general.jsx
class GeneralSettings (line 6) | class GeneralSettings extends Component {
method render (line 11) | render () {
FILE: lib/shared/screens/admin/screens/settings/screens/general/index.js
class GeneralSettingsContainer (line 39) | class GeneralSettingsContainer extends Component {
method render (line 42) | render () {
FILE: lib/shared/screens/admin/screens/settings/shared/components/settings-content/index.jsx
class SettingsContent (line 7) | class SettingsContent extends Component {
method render (line 12) | render () {
FILE: lib/shared/screens/admin/screens/users/components/entry.jsx
class Entry (line 9) | class Entry extends Component {
method onDeleteClick (line 23) | @bind
method render (line 29) | render () {
FILE: lib/shared/screens/admin/screens/users/components/list.jsx
class List (line 6) | class List extends Component {
method render (line 17) | render () {
method renderEntry (line 26) | renderEntry (user) {
FILE: lib/shared/screens/admin/screens/users/components/new/index.js
class NewUserContainer (line 7) | class NewUserContainer extends Component {
method getInitState (line 17) | getInitState () {
method submit (line 27) | submit () {
method changeField (line 42) | changeField (field, value) {
method render (line 48) | render () {
FILE: lib/shared/screens/admin/screens/users/components/new/new.jsx
class NewUser (line 6) | class NewUser extends Component {
method changeField (line 17) | changeField (field, value) {
method render (line 21) | render () {
FILE: lib/shared/screens/admin/screens/users/components/users.jsx
class Users (line 15) | class Users extends Component {
method render (line 33) | render () {
method renderNew (line 54) | renderNew () {
method renderDeleteConfirm (line 65) | renderDeleteConfirm () {
FILE: lib/shared/screens/admin/screens/users/index.js
class UsersContainer (line 23) | class UsersContainer extends Component {
method getInitState (line 34) | getInitState () {
method openNew (line 41) | @bind
method closeNew (line 48) | @bind
method searchChange (line 55) | @bind
method onDelete (line 62) | @bind
method cancelDelete (line 70) | @bind
method confirmDelete (line 79) | @bind
method render (line 90) | render () {
FILE: lib/shared/screens/admin/shared/components/balloon/index.jsx
class Balloon (line 9) | class Balloon extends Component {
method render (line 19) | render () {
FILE: lib/shared/screens/admin/shared/components/content-displays/index.jsx
class ContentDisplays (line 7) | class ContentDisplays extends Component {
method init (line 13) | init () {
method onClick (line 18) | onClick (to) {
method render (line 22) | render () {
FILE: lib/shared/screens/admin/shared/components/content-header-actions/index.jsx
class ContentHeaderActions (line 6) | class ContentHeaderActions extends Component {
method render (line 11) | render () {
FILE: lib/shared/screens/admin/shared/components/content-header/index.jsx
class ContentHeader (line 7) | class ContentHeader extends Component {
method render (line 17) | render () {
FILE: lib/shared/screens/admin/shared/components/content-loading/index.jsx
class ContentLoading (line 8) | class ContentLoading extends Component {
method render (line 9) | render () {
FILE: lib/shared/screens/admin/shared/components/content-new/index.jsx
class ContentNew (line 6) | class ContentNew extends Component {
method render (line 12) | render () {
FILE: lib/shared/screens/admin/shared/components/content-search/index.jsx
class ContentSearch (line 6) | class ContentSearch extends Component {
method onChange (line 12) | onChange (event) {
method render (line 16) | render () {
FILE: lib/shared/screens/admin/shared/components/content-sidebar/index.jsx
class ContentSidebar (line 7) | class ContentSidebar extends Component {
method componentWillReceiveProps (line 13) | componentWillReceiveProps (nextProps) {
method render (line 28) | render () {
FILE: lib/shared/screens/admin/shared/components/content/index.jsx
class Content (line 7) | class Content extends Component {
method render (line 12) | render () {
FILE: lib/shared/screens/admin/shared/components/editable-title/index.jsx
class EditableTitle (line 7) | class EditableTitle extends Component {
method getInitState (line 14) | getInitState () {
method componentWillReceiveProps (line 20) | componentWillReceiveProps (nextProps) {
method componentDidUpdate (line 28) | componentDidUpdate (prevProps, prevState) {
method onClick (line 40) | onClick () {
method onChange (line 47) | onChange (event) {
method cancel (line 53) | cancel (event) {
method onSubmit (line 61) | onSubmit (event) {
method render (line 72) | render () {
method renderContent (line 81) | renderContent () {
FILE: lib/shared/screens/admin/shared/components/input-options/border-style/index.jsx
class BorderStyle (line 7) | class BorderStyle extends Component {
method onClick (line 14) | onClick (type, event) {
method render (line 19) | render () {
method renderOption (line 30) | renderOption (type) {
FILE: lib/shared/screens/admin/shared/components/input-options/border/index.jsx
class BorderPicker (line 10) | class BorderPicker extends Component {
method getInitState (line 16) | getInitState () {
method componentWillReceiveProps (line 27) | componentWillReceiveProps (nextProps) {
method onInputChange (line 33) | onInputChange (id, value) {
method parseValue (line 46) | parseValue (value) {
method equal (line 101) | equal (comp1, comp2) {
method changeSelected (line 110) | changeSelected (selected, event) {
method render (line 117) | render () {
method renderToggleButton (line 164) | renderToggleButton (pos, active) {
FILE: lib/shared/screens/admin/shared/components/input-options/box-shadow/edit.jsx
class Edit (line 4) | class Edit extends Component {
method render (line 59) | render () {
FILE: lib/shared/screens/admin/shared/components/input-options/box-shadow/index.jsx
class BoxShadow (line 8) | class BoxShadow extends Component {
method getInitState (line 18) | getInitState () {
method addNewClick (line 24) | addNewClick () {
method changeShadow (line 38) | changeShadow (key, value) {
method selectShadow (line 46) | selectShadow (index) {
method removeShadow (line 58) | removeShadow (index) {
method render (line 64) | render () {
method renderEntry (line 73) | renderEntry (shadow, index) {
FILE: lib/shared/screens/admin/shared/components/input-options/box-shadow/shadow.jsx
class Shadow (line 9) | class Shadow extends Component {
method onClick (line 19) | onClick () {
method onRemove (line 23) | onRemove (event) {
method render (line 29) | render () {
method renderEditing (line 52) | renderEditing () {
FILE: lib/shared/screens/admin/shared/components/input-options/button/index.js
class ButtonContainer (line 17) | class ButtonContainer extends Component {
method onClick (line 26) | onClick (event) {
method render (line 42) | render () {
FILE: lib/shared/screens/admin/shared/components/input-options/checkbox/index.jsx
class Checkbox (line 8) | class Checkbox extends Component {
method toggle (line 16) | @bind
method render (line 26) | render () {
FILE: lib/shared/screens/admin/shared/components/input-options/color/color-palette-picker.jsx
class ColorPicker (line 11) | class ColorPicker extends Component {
method toggleOpen (line 26) | toggleOpen (event) {
method render (line 32) | render () {
method renderContent (line 57) | renderContent () {
FILE: lib/shared/screens/admin/shared/components/input-options/color/color-picker.jsx
class ColorPicker (line 8) | class ColorPicker extends Component {
method render (line 13) | render () {
FILE: lib/shared/screens/admin/shared/components/input-options/color/color.jsx
class Color (line 9) | class Color extends Component {
method getInitState (line 25) | getInitState () {
method onClick (line 31) | onClick () {
method onMouseEnter (line 35) | onMouseEnter () {
method onMouseLeave (line 42) | onMouseLeave () {
method render (line 48) | render () {
method renderInfo (line 66) | renderInfo () {
FILE: lib/shared/screens/admin/shared/components/input-options/color/colors-collection.jsx
class ColorsCollection (line 8) | class ColorsCollection extends Component {
method onSubmit (line 21) | onSubmit (event) {
method render (line 26) | render () {
method renderColor (line 41) | renderColor (color) {
method renderAdding (line 53) | renderAdding () {
FILE: lib/shared/screens/admin/shared/components/input-options/color/edit.jsx
class Edit (line 17) | class Edit extends Component {
method componentDidMount (line 48) | componentDidMount () {
method componentWillUnmount (line 53) | componentWillUnmount () {
method onClose (line 57) | onClose (event) {
method render (line 94) | render () {
FILE: lib/shared/screens/admin/shared/components/input-options/color/gradient-points.jsx
class GradientPoints (line 9) | class GradientPoints extends Component {
method constructor (line 20) | constructor (props, children) {
method componentWillUnmount (line 26) | componentWillUnmount () {
method onMouseDown (line 31) | onMouseDown (index, event) {
method onMouseMove (line 41) | onMouseMove (event) {
method onMouseUp (line 60) | onMouseUp (event) {
method markerClicked (line 70) | markerClicked (number, event) {
method addPoint (line 76) | addPoint (event) {
method render (line 83) | render () {
method renderPoint (line 97) | renderPoint (colorObj, index) {
FILE: lib/shared/screens/admin/shared/components/input-options/color/hue.jsx
class Hue (line 8) | class Hue extends Component {
method constructor (line 15) | constructor (props, children) {
method componentWillUnmount (line 21) | componentWillUnmount () {
method onMouseDown (line 26) | onMouseDown (event) {
method onMouseMove (line 36) | onMouseMove (event) {
method onMouseUp (line 49) | onMouseUp (event) {
method render (line 55) | render () {
FILE: lib/shared/screens/admin/shared/components/input-options/color/index.js
constant INPUT_TYPES (line 13) | const INPUT_TYPES = ['hex', 'rgba', 'hsva'];
class ColorPalettePickerContainer (line 30) | class ColorPalettePickerContainer extends Component {
method getInitState (line 46) | getInitState () {
method onChange (line 56) | onChange (changes) {
method selectColor (line 60) | selectColor (id) {
method hsvChange (line 64) | hsvChange (hsv) {
method hexChange (line 68) | hexChange (hex) {
method rgbChange (line 72) | rgbChange (rgb) {
method valueChange (line 76) | valueChange (valueType, value) {
method opacityChange (line 103) | opacityChange (opacity) {
method toggleOpened (line 128) | toggleOpened () {
method previousInputType (line 134) | previousInputType () {
method nextInputType (line 140) | nextInputType () {
method toggleAddingColor (line 146) | toggleAddingColor () {
method changeAddingColor (line 152) | changeAddingColor (addingColorName) {
method addColor (line 158) | addColor () {
method changeToSolid (line 187) | changeToSolid () {
method changeToLinear (line 202) | changeToLinear () {
method changeToRadial (line 230) | changeToRadial () {
method changeAngle (line 258) | changeAngle (angle) {
method changeRadius (line 262) | changeRadius (radius) {
method changeCenter (line 266) | changeCenter (center) {
method changeEditingPoint (line 270) | changeEditingPoint (editingPoint) {
method pointPercChange (line 276) | pointPercChange (editingPoint, perc) {
method addPoint (line 290) | addPoint (perc) {
method removePoint (line 319) | removePoint (index) {
method getCurrentColor (line 332) | getCurrentColor () {
method render (line 340) | render () {
FILE: lib/shared/screens/admin/shared/components/input-options/color/input.jsx
class Inputs (line 7) | class Inputs extends Component {
method getInitState (line 15) | getInitState () {
method onFocus (line 21) | onFocus () {
method onBlur (line 28) | onBlur () {
method onChange (line 34) | onChange (event) {
method render (line 41) | render () {
FILE: lib/shared/screens/admin/shared/components/input-options/color/inputs.jsx
class Inputs (line 9) | class Inputs extends Component {
method init (line 22) | init () {
method onHexChange (line 31) | onHexChange (value) {
method onRGBChange (line 37) | onRGBChange (prop, value) {
method onHSVChange (line 47) | onHSVChange (prop, value) {
method onOpacityChange (line 61) | onOpacityChange (value) {
method render (line 69) | render () {
method renderInputs (line 83) | renderInputs () {
FILE: lib/shared/screens/admin/shared/components/input-options/color/linear-gradient.jsx
class LinearGradient (line 10) | class LinearGradient extends Component {
method constructor (line 21) | constructor (props, children) {
method getInitState (line 27) | getInitState () {
method componentWillUnmount (line 33) | componentWillUnmount () {
method markerClicked (line 38) | markerClicked (number) {
method onMouseDown (line 42) | onMouseDown (index, event) {
method onMouseMove (line 59) | onMouseMove (event) {
method onMouseUp (line 131) | onMouseUp (event) {
method onLineClick (line 141) | onLineClick (event) {
method getLineAngle (line 166) | getLineAngle (pointA, pointB) {
method getRectPoint (line 176) | getRectPoint (angle, radius) {
method render (line 203) | render () {
method renderContent (line 211) | renderContent () {
method renderPoint (line 260) | renderPoint (pointA, pointB, colorObj, index) {
method renderAngle (line 282) | renderAngle () {
FILE: lib/shared/screens/admin/shared/components/input-options/color/opacity.jsx
class Opacity (line 7) | class Opacity extends Component {
method constructor (line 14) | constructor (props, children) {
method componentWillUnmount (line 20) | componentWillUnmount () {
method onMouseDown (line 25) | onMouseDown (event) {
method onMouseMove (line 35) | onMouseMove (event) {
method onMouseUp (line 44) | onMouseUp (event) {
method render (line 50) | render () {
FILE: lib/shared/screens/admin/shared/components/input-options/color/radial-gradient.jsx
class RadialGradient (line 13) | class RadialGradient extends Component {
method constructor (line 24) | constructor (props, children) {
method getInitState (line 30) | getInitState () {
method componentWillUnmount (line 36) | componentWillUnmount () {
method markerClicked (line 41) | markerClicked (number) {
method onMouseDown (line 45) | onMouseDown (index, event) {
method onMouseMove (line 62) | onMouseMove (event) {
method onMouseUp (line 115) | onMouseUp (event) {
method onLineClick (line 125) | onLineClick (event) {
method getRadialLine (line 146) | getRadialLine () {
method render (line 224) | render () {
method renderContent (line 232) | renderContent () {
method renderPoint (line 269) | renderPoint (pointA, pointB, colorObj, index) {
FILE: lib/shared/screens/admin/shared/components/input-options/color/radial-radius.jsx
class RadialRadius (line 7) | class RadialRadius extends Component {
method init (line 13) | init () {
method onClick (line 20) | onClick (radius, event) {
method render (line 25) | render () {
FILE: lib/shared/screens/admin/shared/components/input-options/color/sat-light.jsx
class SatLight (line 9) | class SatLight extends Component {
method constructor (line 16) | constructor (props, children) {
method componentWillUnmount (line 22) | componentWillUnmount () {
method onMouseDown (line 27) | onMouseDown (event) {
method onMouseMove (line 37) | onMouseMove (event) {
method onMouseUp (line 51) | onMouseUp (event) {
method render (line 57) | render () {
FILE: lib/shared/screens/admin/shared/components/input-options/color/types.jsx
class Types (line 7) | class Types extends Component {
method render (line 15) | render () {
FILE: lib/shared/screens/admin/shared/components/input-options/columns/column.jsx
class Column (line 8) | class Column extends Component {
method onClick (line 18) | @bind
method render (line 24) | render () {
FILE: lib/shared/screens/admin/shared/components/input-options/columns/columns-manager.jsx
class ColumnsManager (line 10) | class ColumnsManager extends Component {
method getInitState (line 26) | getInitState () {
method parseValue (line 32) | parseValue (value, idChanged = -1) {
method onClick (line 37) | @bind
method onChange (line 50) | onChange (id, value) {
method render (line 57) | render () {
method renderChildren (line 66) | renderChildren () {
method renderColumn (line 97) | renderColumn (id, value) {
method renderOptions (line 111) | renderOptions () {
FILE: lib/shared/screens/admin/shared/components/input-options/columns/index.js
class ColumnsManagerContainer (line 12) | class ColumnsManagerContainer extends Component {
method render (line 64) | render () {
FILE: lib/shared/screens/admin/shared/components/input-options/combobox/index.jsx
class Combobox (line 9) | class Combobox extends Component {
method getInitState (line 20) | getInitState () {
method toggle (line 26) | @bind
method optionClicked (line 33) | optionClicked (value, event) {
method render (line 45) | render () {
method renderOption (line 75) | renderOption (option, i) {
FILE: lib/shared/screens/admin/shared/components/input-options/corners/index.jsx
class CornersPicker (line 6) | class CornersPicker extends Component {
method getInitState (line 13) | getInitState () {
method componentWillReceiveProps (line 20) | componentWillReceiveProps (nextProps) {
method onInputChange (line 26) | onInputChange (value) {
method getValuesString (line 38) | getValuesString (values) {
method parseValue (line 42) | parseValue (value) {
method changeSelected (line 79) | changeSelected (selected, event) {
method render (line 86) | render () {
method renderToggleButton (line 120) | renderToggleButton (pos, active) {
FILE: lib/shared/screens/admin/shared/components/input-options/filters/edit.jsx
class Edit (line 11) | class Edit extends Component {
method onOptionChange (line 23) | onOptionChange (key, value) {
method render (line 27) | render () {
method renderOptions (line 51) | renderOptions () {
FILE: lib/shared/screens/admin/shared/components/input-options/filters/filter.jsx
class Filter (line 9) | class Filter extends Component {
method getDateString (line 20) | getDateString (gran, value) {
method onClick (line 30) | onClick () {
method onRemove (line 36) | onRemove (event) {
method render (line 42) | render () {
method renderContent (line 63) | renderContent () {
method renderEditing (line 134) | renderEditing () {
FILE: lib/shared/screens/admin/shared/components/input-options/filters/filters.jsx
class Filters (line 6) | class Filters extends Component {
method render (line 25) | render () {
method renderFilter (line 35) | renderFilter (filter, index) {
method renderNew (line 47) | renderNew () {
FILE: lib/shared/screens/admin/shared/components/input-options/filters/index.js
class FiltersContainer (line 22) | class FiltersContainer extends Component {
method getInitState (line 37) | getInitState () {
method componentWillReceiveProps (line 44) | componentWillReceiveProps (nextProps) {
method getSelectedSchemaId (line 50) | getSelectedSchemaId (props) {
method fetchData (line 55) | fetchData (props) {
method openNew (line 73) | openNew () {
method onPropertyChange (line 84) | onPropertyChange (prop) {
method onOptionChange (line 92) | onOptionChange (key, value) {
method cancelEdit (line 102) | cancelEdit () {
method submitEdit (line 110) | submitEdit () {
method selectFilter (line 128) | selectFilter (index) {
method removeFilter (line 143) | removeFilter (index) {
method render (line 149) | render () {
FILE: lib/shared/screens/admin/shared/components/input-options/font/dropdown.jsx
class Dropdown (line 7) | class Dropdown extends Component {
method getInitState (line 18) | getInitState () {
method onEntryClick (line 24) | onEntryClick (value, event) {
method toggle (line 29) | toggle () {
method render (line 35) | render () {
method renderCollapsable (line 48) | renderCollapsable () {
method renderEntry (line 58) | renderEntry (entry) {
FILE: lib/shared/screens/admin/shared/components/input-options/font/font-picker.jsx
class FontPicker (line 11) | class FontPicker extends Component {
method init (line 18) | init () {
method getChangedValue (line 23) | getChangedValue (key, value) {
method onChange (line 41) | onChange (key, value) {
method render (line 46) | render () {
method renderOptions (line 55) | renderOptions () {
method renderFont (line 99) | renderFont () {
FILE: lib/shared/screens/admin/shared/components/input-options/font/font.jsx
class Font (line 7) | class Font extends Component {
method render (line 17) | render () {
FILE: lib/shared/screens/admin/shared/components/input-options/font/index.js
class FontPickerContainer (line 31) | class FontPickerContainer extends Component {
method render (line 49) | render () {
FILE: lib/shared/screens/admin/shared/components/input-options/icon/icon-picker.jsx
class IconPicker (line 4) | class IconPicker extends Component {
method render (line 12) | render () {
method renderSelected (line 20) | renderSelected () {
FILE: lib/shared/screens/admin/shared/components/input-options/icon/index.js
class IconPickerContainer (line 6) | class IconPickerContainer extends Component {
method getInitState (line 12) | getInitState () {
method openSelector (line 18) | openSelector () {
method closeSelector (line 24) | closeSelector () {
method render (line 30) | render () {
FILE: lib/shared/screens/admin/shared/components/input-options/image/index.js
class ImagePickerContainer (line 36) | class ImagePickerContainer extends Component {
method getInitState (line 48) | getInitState () {
method componentWillReceiveProps (line 56) | componentWillReceiveProps (nextProps) {
method openSelector (line 62) | @bind
method closeSelector (line 69) | @bind
method onMount (line 76) | @bind
method render (line 84) | render () {
FILE: lib/shared/screens/admin/shared/components/input-options/image/picker.jsx
class ImagePicker (line 9) | class ImagePicker extends Component {
method componentDidMount (line 32) | componentDidMount () {
method unselect (line 41) | @bind
method render (line 46) | render () {
method renderUnselect (line 67) | renderUnselect () {
method renderSelected (line 82) | renderSelected () {
method renderMediaSelector (line 95) | renderMediaSelector () {
FILE: lib/shared/screens/admin/shared/components/input-options/input/index.jsx
class Input (line 11) | class Input extends Component {
method componentDidMount (line 24) | componentDidMount () {
method onChange (line 30) | @bind
method render (line 35) | render () {
method renderState (line 59) | renderState () {
FILE: lib/shared/screens/admin/shared/components/input-options/menu/index.js
class MenuPickerContainer (line 17) | class MenuPickerContainer extends Component {
method render (line 28) | render () {
FILE: lib/shared/screens/admin/shared/components/input-options/number/index.jsx
class NumberInput (line 7) | class NumberInput extends Component {
method getInitState (line 29) | getInitState () {
method limitValue (line 35) | limitValue (value) {
method getUnitAndValue (line 53) | getUnitAndValue (str, defaultUnit = this.props.allowed.length > 0 && t...
method onInput (line 81) | onInput (event) {
method up (line 96) | up (event) {
method down (line 106) | down (event) {
method onFocus (line 116) | onFocus () {
method onBlur (line 124) | onBlur () {
method render (line 131) | render () {
method renderArrows (line 159) | renderArrows () {
FILE: lib/shared/screens/admin/shared/components/input-options/optional/index.jsx
class Optional (line 6) | class Optional extends Component {
method toggle (line 13) | toggle (event) {
method render (line 18) | render () {
FILE: lib/shared/screens/admin/shared/components/input-options/page/index.js
class PagePickerContainer (line 17) | class PagePickerContainer extends Component {
method componentDidMount (line 29) | componentDidMount () {
method render (line 35) | render () {
FILE: lib/shared/screens/admin/shared/components/input-options/rich-text/index.jsx
class HtmlArea (line 6) | class HtmlArea extends Component {
method render (line 13) | render () {
FILE: lib/shared/screens/admin/shared/components/input-options/schema/index.js
class SchemaPickerContainer (line 17) | class SchemaPickerContainer extends Component {
method render (line 24) | render () {
FILE: lib/shared/screens/admin/shared/components/input-options/section/index.jsx
class Section (line 7) | class Section extends Component {
method toggle (line 14) | toggle (event) {
method render (line 19) | render () {
FILE: lib/shared/screens/admin/shared/components/input-options/shadow-position/index.jsx
class ShadowPosition (line 7) | class ShadowPosition extends Component {
method init (line 13) | init () {
method onClick (line 18) | onClick (to) {
method render (line 22) | render () {
FILE: lib/shared/screens/admin/shared/components/input-options/sorts/edit.jsx
class Edit (line 7) | class Edit extends Component {
method render (line 19) | render () {
method renderOptions (line 43) | renderOptions () {
FILE: lib/shared/screens/admin/shared/components/input-options/sorts/index.js
class SortsContainer (line 22) | class SortsContainer extends Component {
method getInitState (line 37) | getInitState () {
method componentWillReceiveProps (line 44) | componentWillReceiveProps (nextProps) {
method getSelectedSchemaId (line 50) | getSelectedSchemaId (props) {
method fetchData (line 55) | fetchData (props) {
method openNew (line 73) | openNew () {
method onPropertyChange (line 84) | onPropertyChange (prop) {
method onOrderChange (line 92) | onOrderChange (order) {
method cancelEdit (line 100) | cancelEdit () {
method submitEdit (line 108) | submitEdit () {
method selectSort (line 126) | selectSort (index) {
method removeSort (line 141) | removeSort (index) {
method render (line 147) | render () {
FILE: lib/shared/screens/admin/shared/components/input-options/sorts/sort.jsx
class Sort (line 8) | class Sort extends Component {
method onClick (line 19) | onClick () {
method onRemove (line 25) | onRemove (event) {
method render (line 31) | render () {
method renderContent (line 52) | renderContent () {
method renderEditing (line 123) | renderEditing () {
FILE: lib/shared/screens/admin/shared/components/input-options/sorts/sorts.jsx
class Sorts (line 6) | class Sorts extends Component {
method render (line 25) | render () {
method renderSort (line 35) | renderSort (sort, index) {
method renderNew (line 42) | renderNew () {
FILE: lib/shared/screens/admin/shared/components/input-options/spacing/index.jsx
class SpacingPicker (line 8) | class SpacingPicker extends Component {
method getInitState (line 15) | getInitState () {
method componentWillReceiveProps (line 22) | componentWillReceiveProps (nextProps) {
method onInputChange (line 28) | onInputChange (value) {
method getValuesString (line 40) | getValuesString (values) {
method parseValue (line 44) | parseValue (value) {
method changeSelected (line 81) | changeSelected (selected, event) {
method render (line 88) | render () {
method renderToggleButton (line 120) | renderToggleButton (pos, icon, active) {
FILE: lib/shared/screens/admin/shared/components/input-options/text-shadow/edit.jsx
class Edit (line 4) | class Edit extends Component {
method render (line 44) | render () {
FILE: lib/shared/screens/admin/shared/components/input-options/text-shadow/index.jsx
class TextShadow (line 8) | class TextShadow extends Component {
method getInitState (line 18) | getInitState () {
method addNewClick (line 24) | addNewClick () {
method changeShadow (line 36) | changeShadow (key, value) {
method selectShadow (line 44) | selectShadow (index) {
method removeShadow (line 56) | removeShadow (index) {
method render (line 62) | render () {
method renderEntry (line 71) | renderEntry (shadow, index) {
FILE: lib/shared/screens/admin/shared/components/input-options/text-shadow/shadow.jsx
class Shadow (line 9) | class Shadow extends Component {
method onClick (line 19) | onClick () {
method onRemove (line 23) | onRemove (event) {
method render (line 29) | render () {
method renderEditing (line 49) | renderEditing () {
FILE: lib/shared/screens/admin/shared/components/list-header/index.jsx
class ListHeader (line 6) | class ListHeader extends Component {
method render (line 15) | render () {
method renderNewButton (line 31) | renderNewButton () {
FILE: lib/shared/screens/admin/shared/components/list-search-sort/index.jsx
class ListSearchSort (line 13) | class ListSearchSort extends Component {
method getInitState (line 26) | getInitState () {
method toggleSorts (line 34) | toggleSorts () {
method changeSearch (line 40) | changeSearch () {
method onFocus (line 48) | @bind
method onBlur (line 56) | @bind
method updateSearch (line 66) | @bind
method render (line 74) | render () {
method renderSorts (line 102) | renderSorts () {
method renderSort (line 119) | renderSort (sort, key) {
FILE: lib/shared/screens/admin/shared/components/media-item-preview/index.jsx
class MediaItemPreview (line 8) | class MediaItemPreview extends Component {
method render (line 32) | render () {
method renderImageType (line 54) | renderImageType () {
method renderFaviconType (line 80) | renderFaviconType () {
method renderVideoType (line 87) | renderVideoType () {
method renderAudioType (line 93) | renderAudioType () {
FILE: lib/shared/screens/admin/shared/components/media-selector/entry.jsx
class MediaEntry (line 11) | class MediaEntry extends Component {
method onClick (line 26) | @bind
method render (line 32) | render () {
FILE: lib/shared/screens/admin/shared/components/media-selector/filters.jsx
class Filters (line 9) | class Filters extends Component {
method sortChange (line 20) | sortChange (key, value) {
method render (line 24) | render () {
FILE: lib/shared/screens/admin/shared/components/media-selector/index.js
class MediaSelectorContainer (line 42) | class MediaSelectorContainer extends Component {
method getInitState (line 57) | getInitState () {
method componentWillUpdate (line 65) | componentWillUpdate (nextProps, nextState) {
method changeSort (line 96) | @bind
method changeOrder (line 101) | @bind
method changeType (line 106) | @bind
method render (line 111) | render () {
FILE: lib/shared/screens/admin/shared/components/media-selector/list.jsx
class MediaSelectorList (line 8) | class MediaSelectorList extends Component {
method render (line 20) | render () {
method renderItem (line 35) | renderItem (mediaItem) {
method renderMockItem (line 42) | renderMockItem (upload, index) {
FILE: lib/shared/screens/admin/shared/components/media-selector/media-selector.jsx
class MediasSelector (line 11) | class MediasSelector extends Component {
method render (line 30) | render () {
method renderSidebar (line 49) | renderSidebar () {
FILE: lib/shared/screens/admin/shared/components/media-selector/mock-entry.jsx
class MediaMockEntry (line 9) | class MediaMockEntry extends Component {
method render (line 14) | render () {
FILE: lib/shared/screens/admin/shared/components/media-selector/selected/index.js
class MediaSelectorSelectedContainer (line 30) | class MediaSelectorSelectedContainer extends Component {
method componentWillReceiveProps (line 36) | componentWillReceiveProps (nextProps) {
method render (line 42) | render () {
FILE: lib/shared/screens/admin/shared/components/media-selector/selected/selected.jsx
class MediaSelectorSelected (line 9) | class MediaSelectorSelected extends Component {
method render (line 28) | render () {
FILE: lib/shared/screens/admin/shared/components/media-selector/sidebar.jsx
class MediaSelectorSidebar (line 10) | class MediaSelectorSidebar extends Component {
method render (line 22) | render () {
FILE: lib/shared/screens/admin/shared/components/media-selector/top-bar.jsx
class MediaSelectorTopBar (line 6) | class MediaSelectorTopBar extends Component {
method render (line 7) | render () {
FILE: lib/shared/screens/admin/shared/components/menu-button/index.jsx
class Menu (line 8) | class Menu extends Component {
method getInitState (line 24) | getInitState () {
method caretToggle (line 31) | caretToggle () {
method onClick (line 37) | onClick (event) {
method render (line 45) | render () {
method renderChildren (line 66) | renderChildren () {
method renderCaret (line 77) | renderCaret () {
FILE: lib/shared/screens/admin/shared/components/menu-sub-button/index.jsx
class MenuSubButton (line 8) | class MenuSubButton extends Component {
method render (line 20) | render () {
FILE: lib/shared/screens/admin/shared/components/modal-delete/index.jsx
class ModalDelete (line 10) | class ModalDelete extends Component {
method onSubmit (line 29) | onSubmit (event) {
method render (line 34) | render () {
method renderLoading (line 46) | renderLoading () {
method renderCreateButton (line 64) | renderCreateButton () {
FILE: lib/shared/screens/admin/shared/components/modal-input/index.jsx
class ModalInput (line 8) | class ModalInput extends Component {
method componentDidMount (line 22) | componentDidMount () {
method onChange (line 28) | onChange (event) {
method render (line 32) | render () {
FILE: lib/shared/screens/admin/shared/components/modal-new/index.jsx
class ModalNew (line 9) | class ModalNew extends Component {
method onSubmit (line 21) | onSubmit (event) {
method render (line 26) | render () {
method renderLoading (line 41) | renderLoading () {
method renderCreateButton (line 59) | renderCreateButton () {
FILE: lib/shared/screens/admin/shared/components/modal/index.jsx
class Modal (line 9) | class Modal extends Component {
method componentDidMount (line 19) | componentDidMount () {
method componentWillUnmount (line 27) | componentWillUnmount () {
method keyDown (line 31) | keyDown (evt) {
method onClose (line 40) | onClose () {
method render (line 45) | render () {
method renderTitles (line 67) | renderTitles () {
FILE: lib/shared/screens/admin/shared/components/options-list/index.jsx
class OptionsList (line 10) | class OptionsList extends Component {
method onChange (line 24) | onChange (id, value) {
method render (line 28) | render () {
method renderOptions (line 32) | renderOptions (options) {
method renderColumn (line 40) | renderColumn (option, index) {
method renderOption (line 48) | renderOption (option, index) {
method renderLabel (line 121) | renderLabel (label) {
FILE: lib/shared/screens/admin/shared/components/options-menu/index.jsx
class OptionsMenu (line 4) | class OptionsMenu extends Component {
method render (line 10) | render () {
method renderOption (line 18) | renderOption (option, key) {
FILE: lib/shared/screens/admin/shared/components/page-builder-menu/breadcrumbs/breadcrumbs.jsx
class Breadcrumbs (line 8) | class Breadcrumbs extends Component {
method render (line 16) | render () {
method renderEntry (line 31) | renderEntry (entry) {
FILE: lib/shared/screens/admin/shared/components/page-builder-menu/breadcrumbs/entry.jsx
class Breadcrumbs (line 6) | class Breadcrumbs extends Component {
method onClick (line 12) | onClick () {
method render (line 17) | render () {
FILE: lib/shared/screens/admin/shared/components/page-builder-menu/breadcrumbs/index.js
class BreadcrumbsContainer (line 16) | class BreadcrumbsContainer extends Component {
method render (line 17) | render () {
FILE: lib/shared/screens/admin/shared/components/page-builder-menu/index.js
class PageBuilderMenuContainer (line 14) | class PageBuilderMenuContainer extends Component {
method render (line 15) | render () {
FILE: lib/shared/screens/admin/shared/components/page-builder-menu/menu.jsx
class PageBuilderMenu (line 9) | class PageBuilderMenu extends Component {
method componentWillReceiveProps (line 17) | componentWillReceiveProps (nextProps) {
method render (line 33) | render () {
method renderContent (line 44) | renderContent () {
FILE: lib/shared/screens/admin/shared/components/page-builder-menu/tabs/index.js
class TabsContainer (line 15) | class TabsContainer extends Component {
method render (line 16) | render () {
FILE: lib/shared/screens/admin/shared/components/page-builder-menu/tabs/layers/entry.jsx
class Entry (line 9) | class Entry extends Component {
method getInitState (line 21) | getInitState () {
method onClick (line 27) | onClick () {
method onMouseOver (line 32) | onMouseOver () {
method onMouseOut (line 41) | onMouseOut () {
method openOptions (line 56) | openOptions (event) {
method duplicate (line 64) | duplicate (event) {
method remove (line 73) | remove (event) {
method toggleExpand (line 82) | toggleExpand (event) {
method render (line 89) | render () {
method renderOptionsMenu (line 116) | renderOptionsMenu () {
method renderContent (line 129) | renderContent () {
method renderCaret (line 159) | renderCaret () {
method renderOptions (line 173) | renderOptions () {
FILE: lib/shared/screens/admin/shared/components/page-builder-menu/tabs/layers/index.js
class LayersTabContainer (line 25) | class LayersTabContainer extends Component {
method render (line 26) | render () {
FILE: lib/shared/screens/admin/shared/components/page-builder-menu/tabs/layers/layers.jsx
class Layers (line 9) | class Layers extends Component {
method render (line 21) | render () {
method renderList (line 45) | renderList (children, dropInfo, dropSettings, parent, droppable = true) {
method renderListEntry (line 65) | renderListEntry (elementId) {
FILE: lib/shared/screens/admin/shared/components/page-builder-menu/tabs/settings/animation.jsx
class AnimationTab (line 6) | class AnimationTab extends Component {
method onChange (line 88) | onChange (id, value) {
method playAnimations (line 94) | playAnimations (event) {
method render (line 99) | render () {
method renderContent (line 110) | renderContent () {
FILE: lib/shared/screens/admin/shared/components/page-builder-menu/tabs/settings/index.js
class SettingsTabContainer (line 21) | class SettingsTabContainer extends Component {
method duplicate (line 27) | duplicate () {
method remove (line 33) | remove () {
method render (line 39) | render () {
FILE: lib/shared/screens/admin/shared/components/page-builder-menu/tabs/settings/position.jsx
class PositionSettings (line 56) | class PositionSettings extends Component {
method onChange (line 81) | onChange (id, value) {
method render (line 87) | render () {
FILE: lib/shared/screens/admin/shared/components/page-builder-menu/tabs/settings/props.jsx
class EditProps (line 13) | class EditProps extends Component {
method displayToggleElement (line 22) | displayToggleElement (id, display) {
method render (line 27) | render () {
method renderOptions (line 80) | renderOptions (ElementClass) {
FILE: lib/shared/screens/admin/shared/components/page-builder-menu/tabs/settings/settings.jsx
class SettingsTab (line 8) | class SettingsTab extends Component {
method render (line 16) | render () {
method renderContent (line 27) | renderContent () {
method renderNonSelected (line 40) | renderNonSelected () {
method renderActionButtons (line 49) | renderActionButtons () {
FILE: lib/shared/screens/admin/shared/components/page-builder-menu/tabs/style/index.js
class StyleTabContainer (line 15) | class StyleTabContainer extends Component {
method render (line 16) | render () {
FILE: lib/shared/screens/admin/shared/components/page-builder-menu/tabs/style/style-picker/edit.jsx
class Edit (line 8) | class Edit extends Component {
method render (line 16) | render () {
method renderOptions (line 24) | renderOptions () {
FILE: lib/shared/screens/admin/shared/components/page-builder-menu/tabs/style/style-picker/entry.jsx
class Entry (line 8) | class Entry extends Component {
method getInitState (line 17) | getInitState () {
method openOptions (line 23) | openOptions (event) {
method onMouseLeave (line 31) | onMouseLeave () {
method onClick (line 39) | onClick (event) {
method duplicate (line 44) | duplicate () {
method remove (line 48) | remove () {
method render (line 52) | render () {
method renderOptionsButton (line 64) | renderOptionsButton () {
method renderOptionsMenu (line 75) | renderOptionsMenu () {
method renderInfo (line 88) | renderInfo () {
FILE: lib/shared/screens/admin/shared/components/page-builder-menu/tabs/style/style-picker/index.js
class StylePickerContainer (line 29) | class StylePickerContainer extends Component {
method getInitState (line 47) | getInitState () {
method componentWillReceiveProps (line 58) | componentWillReceiveProps (nextProps) {
method onUpdateStyle (line 66) | onUpdateStyle (styleId) {
method saveStyle (line 75) | async saveStyle () {
method duplicateStyle (line 93) | async duplicateStyle (data) {
method onChangeValue (line 103) | onChangeValue (key, value) {
method onChange (line 115) | onChange (value) {
method toggleEditingTitle (line 124) | toggleEditingTitle () {
method changeTitleValue (line 130) | changeTitleValue (value) {
method toggleEditing (line 136) | toggleEditing () {
method getStyleOptions (line 142) | getStyleOptions (style) {
method render (line 154) | render () {
FILE: lib/shared/screens/admin/shared/components/page-builder-menu/tabs/style/style-picker/style-picker.jsx
class StylePicker (line 13) | class StylePicker extends Component {
method onSubmit (line 43) | onSubmit (event) {
method render (line 48) | render () {
method renderContent (line 66) | renderContent () {
method renderEntry (line 86) | renderEntry (entry) {
method renderEdit (line 101) | renderEdit () {
method renderSaveStyle (line 112) | renderSaveStyle () {
FILE: lib/shared/screens/admin/shared/components/page-builder-menu/tabs/style/style.jsx
class Style (line 8) | class Style extends Component {
method render (line 16) | render () {
method renderStylePicker (line 35) | renderStylePicker (Element) {
method renderNoneSelected (line 47) | renderNoneSelected () {
method renderNotStylable (line 56) | renderNotStylable () {
FILE: lib/shared/screens/admin/shared/components/page-builder-menu/tabs/tab-button.jsx
class TabButton (line 7) | class TabButton extends Component {
method onClick (line 14) | onClick () {
method render (line 19) | render () {
FILE: lib/shared/screens/admin/shared/components/page-builder-menu/tabs/tabs.jsx
class Tabs (line 10) | class Tabs extends Component {
method render (line 16) | render () {
method renderContent (line 32) | renderContent () {
FILE: lib/shared/screens/admin/shared/components/page-builder/canvas/canvas.jsx
class Canvas (line 15) | class Canvas extends Component {
method getInitState (line 36) | getInitState () {
method getChildContext (line 42) | getChildContext () {
method componentDidMount (line 49) | componentDidMount () {
method onScroll (line 53) | onScroll () {
method render (line 57) | render () {
method renderPlaceholder (line 91) | renderPlaceholder () {
method renderStyles (line 98) | renderStyles () {
method renderChildren (line 108) | renderChildren (children, options) {
method renderElement (line 118) | renderElement (options, elementId, positionInParent) {
FILE: lib/shared/screens/admin/shared/components/page-builder/canvas/empty.jsx
class Empty (line 6) | class Empty extends Component {
method onClick (line 11) | onClick () {
method render (line 16) | render () {
FILE: lib/shared/screens/admin/shared/components/page-builder/canvas/index.js
class CanvasContainer (line 41) | class CanvasContainer extends Component {
method getInitState (line 55) | getInitState () {
method componentWillReceiveProps (line 59) | componentWillReceiveProps (nextProps) {
method render (line 65) | render () {
FILE: lib/shared/screens/admin/shared/components/page-builder/elements-menu/autocomplete.jsx
class Autocomplete (line 6) | class Autocomplete extends Component {
method componentDidMount (line 18) | componentDidMount () {
method onInput (line 24) | onInput () {
method focus (line 29) | focus () {
method render (line 47) | render () {
FILE: lib/shared/screens/admin/shared/components/page-builder/elements-menu/elements-menu.jsx
class ElementsMenu (line 12) | class ElementsMenu extends Component {
method getInitState (line 28) | getInitState () {
method componentDidMount (line 42) | componentDidMount () {
method componentWillUnmount (line 56) | componentWillUnmount () {
method focusSearch (line 64) | focusSearch () {
method onSearchChange (line 73) | onSearchChange (search) {
method toggleCategory (line 130) | toggleCategory (category) {
method stopPropagation (line 135) | stopPropagation () {
method updatePosition (line 139) | updatePosition (event = null, props = this.props) {
method onClose (line 179) | onClose () {
method addElement (line 186) | addElement (tag) {
method addSymbol (line 195) | addSymbol (symbolId) {
method elementAcceptable (line 209) | elementAcceptable (elementTag, element) {
method render (line 233) | render () {
method renderContent (line 257) | renderContent () {
FILE: lib/shared/screens/admin/shared/components/page-builder/elements-menu/index.js
class ElementsMenuContainer (line 25) | class ElementsMenuContainer extends Component {
method render (line 31) | render () {
FILE: lib/shared/screens/admin/shared/components/page-builder/elements-menu/list.jsx
class List (line 9) | class List extends Component {
method toggleCategory (line 21) | toggleCategory (category, event) {
method addElement (line 26) | addElement (tag, event) {
method addSymbol (line 31) | addSymbol (symbolId) {
method render (line 35) | render () {
method renderCategory (line 47) | renderCategory (category) {
method renderElement (line 87) | renderElement (elementObj) {
method renderSymbolsCategory (line 101) | renderSymbolsCategory () {
method renderSymbol (line 126) | renderSymbol (symbol) {
FILE: lib/shared/screens/admin/shared/components/page-builder/elements-menu/search.jsx
class Search (line 10) | class Search extends Component {
method componentDidMount (line 24) | componentDidMount () {
method componentWillUnmount (line 32) | componentWillUnmount () {
method addElementHotkey (line 40) | addElementHotkey (num, event) {
method addElement (line 88) | addElement (tag, event) {
method addSymbol (line 93) | addSymbol (symbolId) {
method render (line 97) | render () {
method renderContent (line 117) | renderContent () {
method renderCategory (line 135) | renderCategory (category) {
method renderElement (line 170) | renderElement (elementObj) {
method renderSymbols (line 193) | renderSymbols () {
method renderSymbol (line 215) | renderSymbol (id) {
FILE: lib/shared/screens/admin/shared/components/page-builder/index.js
class PageBuilderContainer (line 43) | class PageBuilderContainer extends Component {
method componentWillReceiveProps (line 49) | componentWillReceiveProps (nextProps) {
method render (line 59) | render () {
FILE: lib/shared/screens/admin/shared/components/page-builder/page-builder.jsx
class PageBuilder (line 14) | class PageBuilder extends Component {
method componentDidMount (line 21) | componentDidMount () {
method componentWillUnmount (line 28) | componentWillUnmount () {
method render (line 33) | render () {
method renderElementsMenu (line 44) | renderElementsMenu () {
method renderDragger (line 55) | renderDragger () {
FILE: lib/shared/screens/admin/shared/components/scrollable/index.jsx
class Scrollable (line 8) | class Scrollable extends Component {
method render (line 19) | render () {
FILE: lib/shared/screens/admin/shared/components/spinner/index.jsx
class Spinner (line 7) | class Spinner extends Component {
method render (line 13) | render () {
FILE: lib/shared/screens/admin/shared/components/stick/index.jsx
class Stick (line 8) | class Stick extends Component {
method getInitState (line 29) | getInitState () {
method componentDidMount (line 36) | componentDidMount () {
method componentWillUnmount (line 47) | componentWillUnmount () {
method onClose (line 53) | onClose (event) {
method onScroll (line 67) | onScroll () {
method onResize (line 72) | onResize () {
method updatePosition (line 77) | updatePosition () {
method getPosition (line 81) | getPosition () {
method render (line 136) | render () {
FILE: lib/shared/screens/admin/shared/components/upload/index.jsx
class Upload (line 8) | class Upload extends Component {
method onDrop (line 27) | onDrop (files) {
method render (line 41) | render () {
method renderInfos (line 59) | renderInfos () {
FILE: lib/shared/screens/auth/components/logo/index.jsx
class Logo (line 6) | class Logo extends Component {
method render (line 7) | render () {
FILE: lib/shared/screens/auth/index.jsx
class Auth (line 10) | class Auth extends Component {
method render (line 15) | render () {
FILE: lib/shared/screens/auth/screens/init/components/init.jsx
class Init (line 6) | class Init extends Component {
method onChange (line 14) | onChange (id, event) {
method render (line 18) | render () {
FILE: lib/shared/screens/auth/screens/init/index.js
class Init (line 13) | class Init extends Component {
method getInitState (line 18) | getInitState () {
method onChange (line 29) | onChange (id, value) {
method onSubmit (line 36) | onSubmit (event) {
method render (line 53) | render () {
FILE: lib/shared/screens/auth/screens/login/components/login.jsx
class Login (line 6) | class Login extends Component {
method onChange (line 15) | onChange (id, event) {
method render (line 19) | render () {
FILE: lib/shared/screens/auth/screens/login/index.js
class LoginContainer (line 7) | class LoginContainer extends Component {
method getInitState (line 12) | getInitState () {
method onSubmit (line 19) | onSubmit (event) {
method fieldChange (line 39) | fieldChange (id, value) {
method render (line 45) | render () {
Condensed preview — 798 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,427K chars).
[
{
"path": ".eslintrc",
"chars": 1775,
"preview": "{\n \"extends\": \"airbnb\",\n \"parser\": \"babel-eslint\",\n \"rules\": {\n \"object-curly-spacing\": [2, \"never\"],\n \"space-b"
},
{
"path": ".gitignore",
"chars": 652,
"preview": "# Config\n.relaxrc\n\n# Logs\nlogs\n*.log\n\n# Runtime data\npids\n*.pid\n*.seed\n\n# Directory for instrumented libs generated by j"
},
{
"path": ".npmignore",
"chars": 47,
"preview": ".relaxrc\nlib/\nuploads/\nbuild/\npackage.json.tmp\n"
},
{
"path": ".relaxrc.sample",
"chars": 92,
"preview": "{\n \"port\": 8080,\n \"devPort\": 8181,\n \"db\": {\n \"uri\": \"mongodb://localhost/relax\"\n }\n}\n"
},
{
"path": "LICENSE",
"chars": 35147,
"preview": " GNU GENERAL PUBLIC LICENSE\n Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
},
{
"path": "README.md",
"chars": 3098,
"preview": "\n========="
},
{
"path": "ROADMAP.md",
"chars": 2273,
"preview": "Roadmap\n=======\n\nv1.0.0-Beta (Spring 2016)\n-------------------------\n\nSince the start of the project we've been through "
},
{
"path": "app.js",
"chars": 575,
"preview": "import 'babel-polyfill';\n\nimport mongoose from 'mongoose';\n\nimport app from './lib/server';\nimport config from './config"
},
{
"path": "config.js",
"chars": 140,
"preview": "var rc = require('rc');\n\nmodule.exports = rc('relax', {\n port: 8080,\n devPort: 8181,\n db: {\n uri: 'mongodb://local"
},
{
"path": "lib/client/admin.js",
"chars": 138,
"preview": "import 'babel-polyfill';\n\nimport routes from 'routers/admin';\n\nimport renderRoutes from './helpers/render-routes';\n\nrend"
},
{
"path": "lib/client/auth.js",
"chars": 111,
"preview": "import routes from 'routers/auth';\n\nimport renderRoutes from './helpers/render-routes';\n\nrenderRoutes(routes);\n"
},
{
"path": "lib/client/helpers/render-routes.js",
"chars": 623,
"preview": "import configureStore from 'helpers/configure-store';\nimport createHistory from 'history/lib/createBrowserHistory';\nimpo"
},
{
"path": "lib/client/public.js",
"chars": 113,
"preview": "import routes from 'routers/public';\n\nimport renderRoutes from './helpers/render-routes';\n\nrenderRoutes(routes);\n"
},
{
"path": "lib/server/graphql/authorize.js",
"chars": 106,
"preview": "export default function authorize (root) {\n if (!root.user) {\n throw new Error('Unauthorized');\n }\n}\n"
},
{
"path": "lib/server/graphql/mutations/color/add.js",
"chars": 618,
"preview": "import {\n GraphQLNonNull\n} from 'graphql';\n\nimport authorize from '../../authorize';\nimport colorInputType from '../../"
},
{
"path": "lib/server/graphql/mutations/color/duplicate.js",
"chars": 794,
"preview": "import {\n GraphQLNonNull,\n GraphQLID\n} from 'graphql';\n\nimport authorize from '../../authorize';\nimport colorType from"
},
{
"path": "lib/server/graphql/mutations/color/index.js",
"chars": 224,
"preview": "import addColor from './add';\nimport duplicateColor from './duplicate';\nimport removeColor from './remove';\nimport updat"
},
{
"path": "lib/server/graphql/mutations/color/remove.js",
"chars": 697,
"preview": "import getProjection from 'helpers/get-projection';\nimport {\n GraphQLNonNull,\n GraphQLID\n} from 'graphql';\n\nimport aut"
},
{
"path": "lib/server/graphql/mutations/color/update.js",
"chars": 804,
"preview": "import {\n GraphQLNonNull\n} from 'graphql';\nimport getProjection from 'helpers/get-projection';\n\nimport authorize from '"
},
{
"path": "lib/server/graphql/mutations/draft/drop.js",
"chars": 1093,
"preview": "import {\n GraphQLNonNull,\n GraphQLString\n} from 'graphql';\nimport {Types} from 'mongoose';\nimport getProjection from '"
},
{
"path": "lib/server/graphql/mutations/draft/index.js",
"chars": 116,
"preview": "import dropDraft from './drop';\nimport updateDraft from './update';\n\nexport default {\n dropDraft,\n updateDraft\n};\n"
},
{
"path": "lib/server/graphql/mutations/draft/update.js",
"chars": 1240,
"preview": "import getProjection from 'helpers/get-projection';\nimport {\n GraphQLNonNull,\n GraphQLID\n} from 'graphql';\nimport {Typ"
},
{
"path": "lib/server/graphql/mutations/fonts/index.js",
"chars": 205,
"preview": "import removeCustomFont from './remove-custom';\nimport submitCustomFont from './submit-custom';\nimport uploadFont from '"
},
{
"path": "lib/server/graphql/mutations/fonts/remove-custom.js",
"chars": 799,
"preview": "import path from 'path';\nimport rmdir from 'rimraf';\nimport Q from 'q';\nimport {\n GraphQLNonNull,\n GraphQLString,\n Gr"
},
{
"path": "lib/server/graphql/mutations/fonts/submit-custom.js",
"chars": 1835,
"preview": "import forEach from 'lodash.foreach';\nimport fs from 'fs';\nimport mkdirp from 'mkdirp';\nimport mongoose from 'mongoose';"
},
{
"path": "lib/server/graphql/mutations/fonts/upload.js",
"chars": 199,
"preview": "import authorize from '../../authorize';\nimport uploadedType from '../../types/uploaded';\n\nexport default {\n type: uplo"
},
{
"path": "lib/server/graphql/mutations/index.js",
"chars": 573,
"preview": "import color from './color';\nimport draft from './draft';\nimport fonts from './fonts';\nimport media from './media';\nimpo"
},
{
"path": "lib/server/graphql/mutations/media/add.js",
"chars": 2050,
"preview": "import createImageThumbnail from 'helpers/create-image-thumbnail';\nimport fileMimetype from 'helpers/file-mimetype';\nimp"
},
{
"path": "lib/server/graphql/mutations/media/index.js",
"chars": 151,
"preview": "import addMedia from './add';\nimport removeMedia, {removeMediaItem} from './remove';\n\nexport default {\n addMedia,\n rem"
},
{
"path": "lib/server/graphql/mutations/media/remove.js",
"chars": 1462,
"preview": "import getProjection from 'helpers/get-projection';\nimport path from 'path';\nimport rmdir from 'rimraf';\nimport {\n Grap"
},
{
"path": "lib/server/graphql/mutations/menu/add.js",
"chars": 683,
"preview": "import {\n GraphQLNonNull\n} from 'graphql';\n\nimport authorize from '../../authorize';\nimport menuInputType from '../../t"
},
{
"path": "lib/server/graphql/mutations/menu/index.js",
"chars": 158,
"preview": "import addMenu from './add';\nimport removeMenu from './remove';\nimport updateMenu from './update';\n\nexport default {\n a"
},
{
"path": "lib/server/graphql/mutations/menu/remove.js",
"chars": 597,
"preview": "import {\n GraphQLNonNull,\n GraphQLID\n} from 'graphql';\n\nimport authorize from '../../authorize';\nimport menuType from "
},
{
"path": "lib/server/graphql/mutations/menu/update.js",
"chars": 1088,
"preview": "import getProjection from 'helpers/get-projection';\nimport {\n GraphQLNonNull\n} from 'graphql';\n\nimport authorize from '"
},
{
"path": "lib/server/graphql/mutations/page/add.js",
"chars": 941,
"preview": "import getUniqueSlug from 'helpers/get-unique-slug';\nimport {\n GraphQLNonNull\n} from 'graphql';\n\nimport authorize from "
},
{
"path": "lib/server/graphql/mutations/page/duplicate.js",
"chars": 1316,
"preview": "import {\n GraphQLNonNull,\n GraphQLString\n} from 'graphql';\n\nimport authorize from '../../authorize';\nimport pageType f"
},
{
"path": "lib/server/graphql/mutations/page/index.js",
"chars": 268,
"preview": "import addPage from './add';\nimport duplicatePage from './duplicate';\nimport removePage from './remove';\nimport restoreP"
},
{
"path": "lib/server/graphql/mutations/page/remove.js",
"chars": 783,
"preview": "import {\n GraphQLNonNull,\n GraphQLID\n} from 'graphql';\n\nimport authorize from '../../authorize';\nimport pageType from "
},
{
"path": "lib/server/graphql/mutations/page/restore.js",
"chars": 786,
"preview": "import {\n GraphQLNonNull,\n GraphQLID,\n GraphQLInt\n} from 'graphql';\n\nimport authorize from '../../authorize';\nimport "
},
{
"path": "lib/server/graphql/mutations/page/update.js",
"chars": 1393,
"preview": "import {\n GraphQLNonNull\n} from 'graphql';\nimport getProjection from 'helpers/get-projection';\n\nimport authorize from '"
},
{
"path": "lib/server/graphql/mutations/schema-entry/add.js",
"chars": 1167,
"preview": "import getUniqueSlug from 'helpers/get-unique-slug';\nimport parseFields from 'helpers/parse-fields';\nimport {\n GraphQLN"
},
{
"path": "lib/server/graphql/mutations/schema-entry/index.js",
"chars": 266,
"preview": "import addSchemaEntry from './add';\nimport removeSchemaEntry from './remove';\nimport restoreSchemaEntry from './restore'"
},
{
"path": "lib/server/graphql/mutations/schema-entry/remove.js",
"chars": 738,
"preview": "import {\n GraphQLNonNull,\n GraphQLID\n} from 'graphql';\n\nimport authorize from '../../authorize';\nimport schemaEntryMod"
},
{
"path": "lib/server/graphql/mutations/schema-entry/restore.js",
"chars": 963,
"preview": "import {\n GraphQLNonNull,\n GraphQLID,\n GraphQLInt\n} from 'graphql';\n\nimport authorize from '../../authorize';\nimport "
},
{
"path": "lib/server/graphql/mutations/schema-entry/update.js",
"chars": 1670,
"preview": "import getProjection from 'helpers/get-projection';\nimport parseFields from 'helpers/parse-fields';\nimport {\n GraphQLNo"
},
{
"path": "lib/server/graphql/mutations/schemas/add.js",
"chars": 900,
"preview": "import getUniqueSlug from 'helpers/get-unique-slug';\nimport {\n GraphQLNonNull\n} from 'graphql';\n\nimport authorize from "
},
{
"path": "lib/server/graphql/mutations/schemas/index.js",
"chars": 226,
"preview": "import addSchema from './add';\nimport removeSchema from './remove';\nimport restoreSchema from './restore';\nimport update"
},
{
"path": "lib/server/graphql/mutations/schemas/remove.js",
"chars": 569,
"preview": "import {\n GraphQLNonNull,\n GraphQLString\n} from 'graphql';\n\nimport authorize from '../../authorize';\nimport schemaType"
},
{
"path": "lib/server/graphql/mutations/schemas/restore.js",
"chars": 802,
"preview": "import {\n GraphQLNonNull,\n GraphQLID,\n GraphQLInt\n} from 'graphql';\n\nimport authorize from '../../authorize';\nimport "
},
{
"path": "lib/server/graphql/mutations/schemas/update.js",
"chars": 1596,
"preview": "import {\n GraphQLNonNull\n} from 'graphql';\nimport getProjection from 'helpers/get-projection';\n\nimport authorize from '"
},
{
"path": "lib/server/graphql/mutations/settings/index.js",
"chars": 71,
"preview": "import saveSettings from './save';\n\nexport default {\n saveSettings\n};\n"
},
{
"path": "lib/server/graphql/mutations/settings/save.js",
"chars": 971,
"preview": "import forEach from 'lodash.foreach';\nimport getProjection from 'helpers/get-projection';\nimport Q from 'q';\nimport {\n "
},
{
"path": "lib/server/graphql/mutations/style/add.js",
"chars": 759,
"preview": "import parseFields from 'helpers/parse-fields';\nimport {\n GraphQLNonNull\n} from 'graphql';\n\nimport authorize from '../."
},
{
"path": "lib/server/graphql/mutations/style/index.js",
"chars": 164,
"preview": "import addStyle from './add';\nimport removeStyle from './remove';\nimport updateStyle from './update';\n\nexport default {\n"
},
{
"path": "lib/server/graphql/mutations/style/parsable-fields.js",
"chars": 46,
"preview": "export default ['options', 'displayOptions'];\n"
},
{
"path": "lib/server/graphql/mutations/style/remove.js",
"chars": 700,
"preview": "import getProjection from 'helpers/get-projection';\nimport {\n GraphQLNonNull,\n GraphQLID\n} from 'graphql';\n\nimport aut"
},
{
"path": "lib/server/graphql/mutations/style/update.js",
"chars": 945,
"preview": "import getProjection from 'helpers/get-projection';\nimport parseFields from 'helpers/parse-fields';\nimport {\n GraphQLNo"
},
{
"path": "lib/server/graphql/mutations/symbol/add.js",
"chars": 730,
"preview": "import {\n GraphQLNonNull\n} from 'graphql';\n\nimport authorize from '../../authorize';\nimport symbolInputType from '../.."
},
{
"path": "lib/server/graphql/mutations/symbol/index.js",
"chars": 64,
"preview": "import addSymbol from './add';\n\nexport default {\n addSymbol\n};\n"
},
{
"path": "lib/server/graphql/mutations/tab/add.js",
"chars": 900,
"preview": "import {\n GraphQLNonNull,\n GraphQLString,\n GraphQLID\n} from 'graphql';\n\nimport authorize from '../../authorize';\nimpo"
},
{
"path": "lib/server/graphql/mutations/tab/index.js",
"chars": 105,
"preview": "import addTab from './add';\nimport removeTab from './remove';\n\nexport default {\n removeTab,\n addTab\n};\n"
},
{
"path": "lib/server/graphql/mutations/tab/remove.js",
"chars": 677,
"preview": "import getProjection from 'helpers/get-projection';\nimport {\n GraphQLNonNull,\n GraphQLID\n} from 'graphql';\n\nimport aut"
},
{
"path": "lib/server/graphql/mutations/user/add.js",
"chars": 915,
"preview": "import {\n GraphQLNonNull\n} from 'graphql';\n\nimport authorize from '../../authorize';\nimport userInputType from '../../t"
},
{
"path": "lib/server/graphql/mutations/user/index.js",
"chars": 109,
"preview": "import addUser from './add';\nimport removeUser from './remove';\n\nexport default {\n addUser,\n removeUser\n};\n"
},
{
"path": "lib/server/graphql/mutations/user/remove.js",
"chars": 733,
"preview": "import {\n GraphQLNonNull,\n GraphQLID\n} from 'graphql';\n\nimport authorize from '../../authorize';\nimport config from '."
},
{
"path": "lib/server/graphql/queries/color/colors.js",
"chars": 410,
"preview": "import getProjection from 'helpers/get-projection';\nimport {\n GraphQLList\n} from 'graphql';\n\nimport colorType from '../"
},
{
"path": "lib/server/graphql/queries/color/index.js",
"chars": 61,
"preview": "import colors from './colors';\n\nexport default {\n colors\n};\n"
},
{
"path": "lib/server/graphql/queries/draft/draft.js",
"chars": 1000,
"preview": "import getProjection from 'helpers/get-projection';\nimport {\n GraphQLID\n} from 'graphql';\nimport {Types} from 'mongoose"
},
{
"path": "lib/server/graphql/queries/draft/index.js",
"chars": 58,
"preview": "import draft from './draft';\n\nexport default {\n draft\n};\n"
},
{
"path": "lib/server/graphql/queries/generators/schema-list-count.js",
"chars": 381,
"preview": "import authorize from '../../authorize';\nimport countType from '../../types/count';\nimport schemaEntryModel from '../../"
},
{
"path": "lib/server/graphql/queries/generators/schema-list.js",
"chars": 712,
"preview": "import getProjection from 'helpers/get-projection';\nimport {\n GraphQLList\n} from 'graphql';\n\nimport authorize from '../"
},
{
"path": "lib/server/graphql/queries/index.js",
"chars": 582,
"preview": "import color from './color';\nimport draft from './draft';\nimport media from './media';\nimport menu from './menu';\nimport"
},
{
"path": "lib/server/graphql/queries/media/index.js",
"chars": 138,
"preview": "import mediaCount from './media-count';\nimport media, {mediaItem} from './media';\n\nexport default {\n media,\n mediaItem"
},
{
"path": "lib/server/graphql/queries/media/media-count.js",
"chars": 266,
"preview": "import {GraphQLInt} from 'graphql';\n\nimport authorize from '../../authorize';\nimport MediaModel from '../../../models/me"
},
{
"path": "lib/server/graphql/queries/media/media.js",
"chars": 1054,
"preview": "import getProjection from 'helpers/get-projection';\nimport {\n GraphQLList,\n GraphQLNonNull,\n GraphQLID\n} from 'graphq"
},
{
"path": "lib/server/graphql/queries/menu/index.js",
"chars": 187,
"preview": "import menus from './menus';\nimport menusCount from './menus-count';\nimport menu, {validateMenuSlug} from './menu';\n\nexp"
},
{
"path": "lib/server/graphql/queries/menu/menu.js",
"chars": 983,
"preview": "import getProjection from 'helpers/get-projection';\nimport {\n GraphQLString,\n GraphQLID,\n GraphQLNonNull,\n GraphQLBo"
},
{
"path": "lib/server/graphql/queries/menu/menus-count.js",
"chars": 263,
"preview": "import {GraphQLInt} from 'graphql';\n\nimport authorize from '../../authorize';\nimport MenuModel from '../../../models/men"
},
{
"path": "lib/server/graphql/queries/menu/menus.js",
"chars": 673,
"preview": "import getProjection from 'helpers/get-projection';\nimport {\n GraphQLList\n} from 'graphql';\n\nimport authorize from '../"
},
{
"path": "lib/server/graphql/queries/page/index.js",
"chars": 187,
"preview": "import pages from './pages';\nimport pagesCount from './pages-count';\nimport page, {validatePageSlug} from './page';\n\nexp"
},
{
"path": "lib/server/graphql/queries/page/page.js",
"chars": 1416,
"preview": "import getProjection from 'helpers/get-projection';\nimport {\n GraphQLString,\n GraphQLBoolean,\n GraphQLNonNull,\n Grap"
},
{
"path": "lib/server/graphql/queries/page/pages-count.js",
"chars": 216,
"preview": "import {GraphQLInt} from 'graphql';\n\nimport PageModel from '../../../models/page';\n\nexport default {\n type: GraphQLInt,"
},
{
"path": "lib/server/graphql/queries/page/pages.js",
"chars": 669,
"preview": "import getProjection from 'helpers/get-projection';\nimport {\n GraphQLList\n} from 'graphql';\n\nimport authorize from '../"
},
{
"path": "lib/server/graphql/queries/revision/index.js",
"chars": 70,
"preview": "import revisions from './revisions';\n\nexport default {\n revisions\n};\n"
},
{
"path": "lib/server/graphql/queries/revision/revisions.js",
"chars": 743,
"preview": "import getProjection from 'helpers/get-projection';\nimport {\n GraphQLList,\n GraphQLString\n} from 'graphql';\nimport {Ty"
},
{
"path": "lib/server/graphql/queries/schema-entry/index.js",
"chars": 255,
"preview": "import schemaList from './schema-list';\nimport schemaListCount from './schema-list-count';\nimport schemaEntry, {validate"
},
{
"path": "lib/server/graphql/queries/schema-entry/schema-entry.js",
"chars": 1277,
"preview": "import getProjection from 'helpers/get-projection';\nimport {\n GraphQLString,\n GraphQLBoolean,\n GraphQLNonNull,\n Grap"
},
{
"path": "lib/server/graphql/queries/schema-entry/schema-list-count.js",
"chars": 438,
"preview": "import {\n GraphQLID,\n GraphQLInt\n} from 'graphql';\n\nimport authorize from '../../authorize';\nimport schemaEntryModel f"
},
{
"path": "lib/server/graphql/queries/schema-entry/schema-list.js",
"chars": 856,
"preview": "import getProjection from 'helpers/get-projection';\nimport {\n GraphQLList,\n GraphQLID\n} from 'graphql';\n\nimport author"
},
{
"path": "lib/server/graphql/queries/schemas/index.js",
"chars": 209,
"preview": "import schemas from './schemas';\nimport schemasCount from './schemas-count';\nimport schema, {validateSchemaSlug} from '."
},
{
"path": "lib/server/graphql/queries/schemas/schema.js",
"chars": 1045,
"preview": "import getProjection from 'helpers/get-projection';\nimport {\n GraphQLString,\n GraphQLBoolean,\n GraphQLNonNull,\n Grap"
},
{
"path": "lib/server/graphql/queries/schemas/schemas-count.js",
"chars": 269,
"preview": "import {GraphQLInt} from 'graphql';\n\nimport authorize from '../../authorize';\nimport SchemaModel from '../../../models/s"
},
{
"path": "lib/server/graphql/queries/schemas/schemas.js",
"chars": 681,
"preview": "import getProjection from 'helpers/get-projection';\nimport {\n GraphQLList\n} from 'graphql';\n\nimport authorize from '../"
},
{
"path": "lib/server/graphql/queries/settings/index.js",
"chars": 67,
"preview": "import settings from './settings';\n\nexport default {\n settings\n};\n"
},
{
"path": "lib/server/graphql/queries/settings/settings.js",
"chars": 650,
"preview": "import getProjection from 'helpers/get-projection';\nimport {\n GraphQLList,\n GraphQLString\n} from 'graphql';\n\nimport au"
},
{
"path": "lib/server/graphql/queries/style/index.js",
"chars": 61,
"preview": "import styles from './styles';\n\nexport default {\n styles\n};\n"
},
{
"path": "lib/server/graphql/queries/style/styles.js",
"chars": 410,
"preview": "import getProjection from 'helpers/get-projection';\nimport {\n GraphQLList\n} from 'graphql';\n\nimport styleType from '../"
},
{
"path": "lib/server/graphql/queries/symbol/index.js",
"chars": 105,
"preview": "import symbol from './symbol';\nimport symbols from './symbols';\n\nexport default {\n symbol,\n symbols\n};\n"
},
{
"path": "lib/server/graphql/queries/symbol/symbol.js",
"chars": 539,
"preview": "import getProjection from 'helpers/get-projection';\nimport {GraphQLID} from 'graphql';\nimport {Types} from 'mongoose';\n\n"
},
{
"path": "lib/server/graphql/queries/symbol/symbols.js",
"chars": 412,
"preview": "import getProjection from 'helpers/get-projection';\nimport {GraphQLList} from 'graphql';\n\nimport symbolType from '../../"
},
{
"path": "lib/server/graphql/queries/tab/index.js",
"chars": 55,
"preview": "import tabs from './tabs';\n\nexport default {\n tabs\n};\n"
},
{
"path": "lib/server/graphql/queries/tab/tabs.js",
"chars": 522,
"preview": "import getProjection from 'helpers/get-projection';\nimport {GraphQLList} from 'graphql';\n\nimport authorize from '../../a"
},
{
"path": "lib/server/graphql/queries/user/index.js",
"chars": 191,
"preview": "import session from './session';\nimport user from './user';\nimport users from './users';\nimport usersCount from './users"
},
{
"path": "lib/server/graphql/queries/user/session.js",
"chars": 141,
"preview": "import {GraphQLBoolean} from 'graphql';\n\nexport default {\n type: GraphQLBoolean,\n resolve (root) {\n return root.isA"
},
{
"path": "lib/server/graphql/queries/user/user.js",
"chars": 608,
"preview": "import getProjection from 'helpers/get-projection';\nimport {GraphQLID} from 'graphql';\n\nimport authorize from '../../aut"
},
{
"path": "lib/server/graphql/queries/user/users-count.js",
"chars": 263,
"preview": "import {GraphQLInt} from 'graphql';\n\nimport authorize from '../../authorize';\nimport UserModel from '../../../models/use"
},
{
"path": "lib/server/graphql/queries/user/users.js",
"chars": 665,
"preview": "import getProjection from 'helpers/get-projection';\nimport {GraphQLList} from 'graphql';\n\nimport authorize from '../../a"
},
{
"path": "lib/server/graphql/query-pagination.js",
"chars": 1601,
"preview": "import forEach from 'lodash.foreach';\nimport {\n GraphQLString,\n GraphQLInt,\n GraphQLList\n} from 'graphql';\n\nimport fi"
},
{
"path": "lib/server/graphql/types/color-input.js",
"chars": 304,
"preview": "import {\n GraphQLInputObjectType,\n GraphQLString,\n GraphQLID\n} from 'graphql';\n\nconst colorInputType = new GraphQLInp"
},
{
"path": "lib/server/graphql/types/color.js",
"chars": 317,
"preview": "import {\n GraphQLObjectType,\n GraphQLNonNull,\n GraphQLString,\n GraphQLID\n} from 'graphql';\n\nconst colorType = new Gr"
},
{
"path": "lib/server/graphql/types/count.js",
"chars": 198,
"preview": "import {\n GraphQLObjectType,\n GraphQLInt\n} from 'graphql';\n\nconst countType = new GraphQLObjectType({\n name: 'Count',"
},
{
"path": "lib/server/graphql/types/custom-font.js",
"chars": 673,
"preview": "import {\n GraphQLObjectType,\n GraphQLString,\n GraphQLNonNull\n} from 'graphql';\n\nconst customFontType = new GraphQLObj"
},
{
"path": "lib/server/graphql/types/draft-id-input.js",
"chars": 249,
"preview": "import {\n GraphQLInputObjectType,\n GraphQLString\n} from 'graphql';\n\nexport default new GraphQLInputObjectType({\n name"
},
{
"path": "lib/server/graphql/types/draft-id.js",
"chars": 292,
"preview": "import {\n GraphQLObjectType,\n GraphQLNonNull,\n GraphQLString\n} from 'graphql';\n\nexport default new GraphQLObjectType("
},
{
"path": "lib/server/graphql/types/draft-input.js",
"chars": 492,
"preview": "import {\n GraphQLInputObjectType,\n GraphQLString,\n GraphQLInt\n} from 'graphql';\n\nimport draftIdInputType from './draf"
},
{
"path": "lib/server/graphql/types/draft.js",
"chars": 631,
"preview": "import {\n GraphQLObjectType,\n GraphQLNonNull,\n GraphQLString,\n GraphQLInt\n} from 'graphql';\n\nimport draftIdType from"
},
{
"path": "lib/server/graphql/types/filter.js",
"chars": 496,
"preview": "import {\n GraphQLInputObjectType,\n GraphQLNonNull,\n GraphQLString,\n GraphQLList\n} from 'graphql';\n\nconst filterType "
},
{
"path": "lib/server/graphql/types/generators/schema-entry-input.js",
"chars": 1098,
"preview": "import forEach from 'lodash.foreach';\nimport {\n GraphQLInputObjectType,\n GraphQLNonNull,\n GraphQLString,\n GraphQLInt"
},
{
"path": "lib/server/graphql/types/generators/schema-entry.js",
"chars": 1674,
"preview": "import forEach from 'lodash.foreach';\nimport {\n GraphQLObjectType,\n GraphQLNonNull,\n GraphQLString,\n GraphQLInt,\n G"
},
{
"path": "lib/server/graphql/types/media-input.js",
"chars": 463,
"preview": "import {\n GraphQLInputObjectType,\n GraphQLString,\n GraphQLNonNull\n} from 'graphql';\n\nconst mediaInputType = new Graph"
},
{
"path": "lib/server/graphql/types/media.js",
"chars": 1135,
"preview": "import {\n GraphQLObjectType,\n GraphQLNonNull,\n GraphQLString,\n GraphQLInt,\n GraphQLFloat,\n GraphQLID\n} from 'graph"
},
{
"path": "lib/server/graphql/types/menu-data.js",
"chars": 933,
"preview": "import getProjection from 'helpers/get-projection';\nimport {\n GraphQLObjectType,\n GraphQLString,\n GraphQLID,\n GraphQ"
},
{
"path": "lib/server/graphql/types/menu-input.js",
"chars": 553,
"preview": "import {\n GraphQLInputObjectType,\n GraphQLString,\n GraphQLFloat,\n GraphQLID\n} from 'graphql';\n\nconst menuInputType ="
},
{
"path": "lib/server/graphql/types/menu.js",
"chars": 1064,
"preview": "import {\n GraphQLObjectType,\n GraphQLNonNull,\n GraphQLString,\n GraphQLFloat,\n GraphQLID\n} from 'graphql';\n\nimport u"
},
{
"path": "lib/server/graphql/types/page-input.js",
"chars": 655,
"preview": "import {\n GraphQLInputObjectType,\n GraphQLString,\n GraphQLInt,\n GraphQLFloat,\n GraphQLID\n} from 'graphql';\n\nconst p"
},
{
"path": "lib/server/graphql/types/page.js",
"chars": 1176,
"preview": "import {\n GraphQLObjectType,\n GraphQLNonNull,\n GraphQLString,\n GraphQLInt,\n GraphQLFloat,\n GraphQLID\n} from 'graph"
},
{
"path": "lib/server/graphql/types/revision.js",
"chars": 949,
"preview": "import {\n GraphQLObjectType,\n GraphQLNonNull,\n GraphQLString,\n GraphQLInt,\n GraphQLFloat,\n GraphQLID\n} from 'graph"
},
{
"path": "lib/server/graphql/types/schema-entry-input.js",
"chars": 663,
"preview": "import {\n GraphQLInputObjectType,\n GraphQLString,\n GraphQLInt,\n GraphQLFloat,\n GraphQLID\n} from 'graphql';\n\nexport "
},
{
"path": "lib/server/graphql/types/schema-entry.js",
"chars": 1495,
"preview": "import {\n GraphQLObjectType,\n GraphQLNonNull,\n GraphQLString,\n GraphQLInt,\n GraphQLFloat,\n GraphQLID\n} from 'graph"
},
{
"path": "lib/server/graphql/types/schema-input.js",
"chars": 743,
"preview": "import {\n GraphQLInputObjectType,\n GraphQLString,\n GraphQLInt,\n GraphQLFloat,\n GraphQLID\n} from 'graphql';\n\nconst s"
},
{
"path": "lib/server/graphql/types/schema.js",
"chars": 1351,
"preview": "import {\n GraphQLObjectType,\n GraphQLNonNull,\n GraphQLString,\n GraphQLInt,\n GraphQLFloat,\n GraphQLID\n} from 'graph"
},
{
"path": "lib/server/graphql/types/setting-input.js",
"chars": 267,
"preview": "import {\n GraphQLInputObjectType,\n GraphQLString\n} from 'graphql';\n\nconst settingInputType = new GraphQLInputObjectTyp"
},
{
"path": "lib/server/graphql/types/setting.js",
"chars": 280,
"preview": "import {\n GraphQLObjectType,\n GraphQLNonNull,\n GraphQLString\n} from 'graphql';\n\nconst settingType = new GraphQLObject"
},
{
"path": "lib/server/graphql/types/style-input.js",
"chars": 382,
"preview": "import {\n GraphQLInputObjectType,\n GraphQLString,\n GraphQLID\n} from 'graphql';\n\nconst styleInputType = new GraphQLInp"
},
{
"path": "lib/server/graphql/types/style.js",
"chars": 604,
"preview": "import {\n GraphQLObjectType,\n GraphQLNonNull,\n GraphQLString,\n GraphQLID\n} from 'graphql';\n\nconst styleType = new Gr"
},
{
"path": "lib/server/graphql/types/symbol-input.js",
"chars": 306,
"preview": "import {\n GraphQLInputObjectType,\n GraphQLString,\n GraphQLID\n} from 'graphql';\n\nconst symbolInputType = new GraphQLIn"
},
{
"path": "lib/server/graphql/types/symbol.js",
"chars": 409,
"preview": "import {\n GraphQLObjectType,\n GraphQLNonNull,\n GraphQLString,\n GraphQLID\n} from 'graphql';\n\nconst symbolType = new G"
},
{
"path": "lib/server/graphql/types/tab-item.js",
"chars": 270,
"preview": "import {\n GraphQLObjectType,\n GraphQLNonNull,\n GraphQLString\n} from 'graphql';\n\nexport default new GraphQLObjectType("
},
{
"path": "lib/server/graphql/types/tab.js",
"chars": 660,
"preview": "import {\n GraphQLObjectType,\n GraphQLNonNull,\n GraphQLID,\n GraphQLString\n} from 'graphql';\n\nimport tabItemType from "
},
{
"path": "lib/server/graphql/types/uploaded-input.js",
"chars": 440,
"preview": "import {\n GraphQLInputObjectType,\n GraphQLString,\n GraphQLInt\n} from 'graphql';\n\nconst uploadedInputType = new GraphQ"
},
{
"path": "lib/server/graphql/types/uploaded.js",
"chars": 415,
"preview": "import {\n GraphQLObjectType,\n GraphQLString,\n GraphQLInt\n} from 'graphql';\n\nconst uploadedType = new GraphQLObjectTyp"
},
{
"path": "lib/server/graphql/types/user-input.js",
"chars": 436,
"preview": "import {\n GraphQLInputObjectType,\n GraphQLString,\n GraphQLNonNull\n} from 'graphql';\n\nconst userInputType = new GraphQ"
},
{
"path": "lib/server/graphql/types/user.js",
"chars": 394,
"preview": "import {\n GraphQLObjectType,\n GraphQLNonNull,\n GraphQLString\n} from 'graphql';\n\nconst userType = new GraphQLObjectTyp"
},
{
"path": "lib/server/index.js",
"chars": 2796,
"preview": "import bodyParser from 'body-parser';\nimport connectMongo from 'connect-mongo';\nimport express from 'express';\nimport gr"
},
{
"path": "lib/server/logger.js",
"chars": 250,
"preview": "import winston from 'winston';\n\nexport default new winston.Logger({\n transports: [\n new winston.transports.Console({"
},
{
"path": "lib/server/middleware/fonts.js",
"chars": 1534,
"preview": "import forEach from 'lodash.foreach';\n\nimport SettingModel from '../models/setting';\n\nexport default async (req, res, ne"
},
{
"path": "lib/server/middleware/google-analytics.js",
"chars": 1040,
"preview": "import utils from 'helpers/utils';\n\nimport SettingModel from '../models/setting';\n\nexport default async (req, res, next)"
},
{
"path": "lib/server/middleware/index.js",
"chars": 127,
"preview": "import fonts from './fonts';\nimport googleAnalytics from './google-analytics';\n\nexport default {\n fonts,\n googleAnalyt"
},
{
"path": "lib/server/migrate.js",
"chars": 1127,
"preview": "import q from 'q';\nimport semver from 'semver';\nimport {readdirSync} from 'fs';\nimport {basename, extname, join} from 'p"
},
{
"path": "lib/server/models/color.js",
"chars": 239,
"preview": "import mongoose from 'mongoose';\n\nconst colorSchema = new mongoose.Schema({\n label: {\n type: String,\n required: t"
},
{
"path": "lib/server/models/draft.js",
"chars": 489,
"preview": "import mongoose from 'mongoose';\n\nconst draftSchema = new mongoose.Schema({\n _id: {\n _id: {\n type: mongoose.Sch"
},
{
"path": "lib/server/models/index.js",
"chars": 441,
"preview": "import color from './color';\nimport draft from './draft';\nimport media from './media';\nimport menu from './menu';\nimport"
},
{
"path": "lib/server/models/media.js",
"chars": 772,
"preview": "import mongoose from 'mongoose';\n\nconst mediaSchema = new mongoose.Schema({\n name: {\n type: String,\n required: tr"
},
{
"path": "lib/server/models/menu.js",
"chars": 483,
"preview": "import mongoose from 'mongoose';\n\nconst menuSchema = new mongoose.Schema({\n title: {\n type: String,\n required: tr"
},
{
"path": "lib/server/models/migration.js",
"chars": 229,
"preview": "import mongoose from 'mongoose';\n\nconst migrationSchema = new mongoose.Schema({\n _id: {\n type: String\n },\n when: {"
},
{
"path": "lib/server/models/page.js",
"chars": 647,
"preview": "import mongoose from 'mongoose';\n\nconst pageSchema = new mongoose.Schema({\n title: {\n type: String,\n required: tr"
},
{
"path": "lib/server/models/revision.js",
"chars": 479,
"preview": "import mongoose from 'mongoose';\n\nconst schema = new mongoose.Schema({\n _id: {\n _id: {\n type: mongoose.Schema.T"
},
{
"path": "lib/server/models/schema-entry.js",
"chars": 1921,
"preview": "import forEach from 'lodash.foreach';\nimport mongoose from 'mongoose';\nimport {TypesNative} from 'helpers/data-types/nat"
},
{
"path": "lib/server/models/schema.js",
"chars": 1520,
"preview": "import mongoose from 'mongoose';\n// import tabsStore from '../stores/tabs';\n// import revisionsStore from '../stores/rev"
},
{
"path": "lib/server/models/setting.js",
"chars": 244,
"preview": "import mongoose from 'mongoose';\n\nconst settingSchema = new mongoose.Schema({\n _id: {\n type: String\n },\n value: {\n"
},
{
"path": "lib/server/models/style.js",
"chars": 377,
"preview": "import mongoose from 'mongoose';\n\nconst styleSchema = new mongoose.Schema({\n type: {\n type: String,\n required: tr"
},
{
"path": "lib/server/models/symbol.js",
"chars": 262,
"preview": "import mongoose from 'mongoose';\n\nconst symbolSchema = new mongoose.Schema({\n title: {\n type: String,\n required: "
},
{
"path": "lib/server/models/tab.js",
"chars": 274,
"preview": "import mongoose from 'mongoose';\n\nconst tabSchema = new mongoose.Schema({\n _userId: {\n type: mongoose.Schema.Types.O"
},
{
"path": "lib/server/models/user.js",
"chars": 801,
"preview": "import mongoose from 'mongoose';\nimport passport from 'passport';\nimport passportLocalMongoose from 'passport-local-mong"
},
{
"path": "lib/server/routers/admin.js",
"chars": 2587,
"preview": "import getDefaultFavicon from 'helpers/default-favicon';\nimport getMarkup from 'helpers/get-markup';\nimport routeHandler"
},
{
"path": "lib/server/routers/auth.js",
"chars": 2412,
"preview": "import getDefaultFavicon from 'helpers/default-favicon';\nimport getMarkup from 'helpers/get-markup';\nimport passport fro"
},
{
"path": "lib/server/routers/index.js",
"chars": 170,
"preview": "import adminRouter from './admin';\nimport authRouter from './auth';\nimport publicRouter from './public';\n\nexport default"
},
{
"path": "lib/server/routers/public.js",
"chars": 6076,
"preview": "import find from 'lodash.find';\nimport forEach from 'lodash.foreach';\nimport getDefaultFavicon from 'helpers/default-fav"
},
{
"path": "lib/server/schema.js",
"chars": 1856,
"preview": "import clone from 'lodash.clone';\nimport forEach from 'lodash.foreach';\nimport {\n GraphQLObjectType,\n GraphQLSchema\n} "
},
{
"path": "lib/server/shared/components/html.jsx",
"chars": 1195,
"preview": "import React, {PropTypes} from 'react';\n\nexport default class Html extends React.Component {\n static propTypes = {\n "
},
{
"path": "lib/server/shared/helpers/create-image-thumbnail.js",
"chars": 626,
"preview": "import path from 'path';\nimport sharp from 'sharp';\nimport {fcall, ninvoke} from 'q';\n\nconst defaultOptions = {\n width:"
},
{
"path": "lib/server/shared/helpers/default-favicon.js",
"chars": 230,
"preview": "export default function getDefaultIcon (res) {\n return {\n tag: 'link',\n props: {\n rel: 'shortcut icon',\n "
},
{
"path": "lib/server/shared/helpers/file-mimetype.js",
"chars": 157,
"preview": "export default function fileMimetype (file) {\n const fileData = file.file;\n return fileData.substring(fileData.indexOf"
},
{
"path": "lib/server/shared/helpers/get-markup.js",
"chars": 626,
"preview": "import serialize from 'serialize-javascript';\nimport Html from 'components/html';\nimport React from 'react';\nimport {ren"
},
{
"path": "lib/server/shared/helpers/get-projection.js",
"chars": 211,
"preview": "export default function getProjection (fieldASTs) {\n return fieldASTs.selectionSet.selections.reduce((projections, sele"
},
{
"path": "lib/server/shared/helpers/get-unique-slug.js",
"chars": 487,
"preview": "import slugify from 'slug';\n\nasync function check (Model, slug) {\n const exists = await Model.count({slug});\n return {"
},
{
"path": "lib/server/shared/helpers/resize-image.js",
"chars": 393,
"preview": "import sharp from 'sharp';\nimport {fcall} from 'q';\n\nconst defaultOptions = {\n width: 100,\n height: 100,\n quality: 10"
},
{
"path": "lib/server/shared/helpers/route-handler.js",
"chars": 767,
"preview": "import configureStore from 'helpers/configure-store';\nimport {createMemoryHistory} from 'history';\nimport {match, reduxR"
},
{
"path": "lib/server/shared/helpers/safe-html-string.js",
"chars": 94,
"preview": "export default function safeHtmlString (str) {\n return str.replace(/<\\/?[^>]+(>|$)/g, '');\n}\n"
},
{
"path": "lib/server/shared/helpers/write-file.js",
"chars": 538,
"preview": "import fs from 'fs';\nimport mkdirp from 'mkdirp';\nimport path from 'path';\nimport {nfcall} from 'q';\n\nexport default asy"
},
{
"path": "lib/shared/actions/admin-menu.js",
"chars": 217,
"preview": "import actionTypes from 'actions';\n\nexport function openAdminMenu () {\n return {\n type: actionTypes.openAdminMenu\n "
},
{
"path": "lib/shared/actions/colors.js",
"chars": 1196,
"preview": "import {mutation} from 'relate-js';\n\nexport function updateColor (data) {\n return mutation({\n fragments: {\n upd"
},
{
"path": "lib/shared/actions/display.js",
"chars": 141,
"preview": "import actionTypes from 'actions';\n\nexport function changeDisplay (value) {\n return {\n type: actionTypes.changeDispl"
},
{
"path": "lib/shared/actions/dnd.js",
"chars": 473,
"preview": "import actionTypes from 'actions';\n\nexport function startDragging (draggingData, dragInfo) {\n return {\n type: action"
},
{
"path": "lib/shared/actions/draft.js",
"chars": 1218,
"preview": "import actionTypes from 'actions';\nimport request from 'helpers/request';\nimport {mutation} from 'relate-js';\nimport {fr"
},
{
"path": "lib/shared/actions/elements.js",
"chars": 295,
"preview": "import actionTypes from 'actions';\nimport request from 'helpers/request';\n\nexport function getElementData (elementId, {q"
},
{
"path": "lib/shared/actions/fonts.js",
"chars": 3935,
"preview": "import actionTypes from 'actions';\nimport loadFontsAsync from 'helpers/load-fonts';\nimport request from 'helpers/request"
},
{
"path": "lib/shared/actions/graphql.js",
"chars": 387,
"preview": "import actionTypes from 'actions';\nimport request from 'helpers/request';\n\nexport function graphql ({query, variables}, "
},
{
"path": "lib/shared/actions/index.js",
"chars": 4047,
"preview": "export default {\n // Session\n authenticate: 'AUTHENTICATE',\n // Admin menu\n openAdminMenu: 'OPEN_ADMIN_MENU',\n clos"
},
{
"path": "lib/shared/actions/media.js",
"chars": 4442,
"preview": "import actionTypes from 'actions';\nimport request from 'helpers/request';\nimport {mutation} from 'relate-js';\nimport {fr"
},
{
"path": "lib/shared/actions/menu.js",
"chars": 2138,
"preview": "import actionTypes from 'actions';\nimport {pushState} from 'redux-router';\nimport {mutation} from 'relate-js';\n\nexport f"
},
{
"path": "lib/shared/actions/page-builder.js",
"chars": 7268,
"preview": "import actionTypes from 'actions';\nimport forEach from 'lodash.foreach';\nimport request from 'helpers/request';\nimport s"
},
{
"path": "lib/shared/actions/page.js",
"chars": 4964,
"preview": "import actionTypes from 'actions';\nimport request from 'helpers/request';\nimport {pushState} from 'redux-router';\nimport"
},
{
"path": "lib/shared/actions/revisions.js",
"chars": 482,
"preview": "import {fragmentToQL} from 'relax-fragments';\n\nimport actionTypes from 'actions';\nimport request from 'helpers/request';"
},
{
"path": "lib/shared/actions/schema-entry.js",
"chars": 2931,
"preview": "import actionTypes from 'actions';\nimport request from 'helpers/request';\nimport stringifyFields from 'helpers/stringify"
},
{
"path": "lib/shared/actions/schema-list.js",
"chars": 573,
"preview": "import actionTypes from 'actions';\nimport request from 'helpers/request';\nimport {fragmentToQL} from 'relax-fragments';\n"
},
{
"path": "lib/shared/actions/schema.js",
"chars": 2961,
"preview": "import actionTypes from 'actions';\nimport request from 'helpers/request';\nimport stringifyFields from 'helpers/stringify"
},
{
"path": "lib/shared/actions/schemas.js",
"chars": 487,
"preview": "import actionTypes from 'actions';\nimport request from 'helpers/request';\nimport {fragmentToQL} from 'relax-fragments';\n"
},
{
"path": "lib/shared/actions/session.js",
"chars": 538,
"preview": "import actionTypes from 'actions';\nimport request from 'helpers/request';\n\nexport function authenticate (dispatch) {\n r"
},
{
"path": "lib/shared/actions/settings.js",
"chars": 780,
"preview": "import actionTypes from 'actions';\nimport forEach from 'lodash.foreach';\nimport request from 'helpers/request';\nimport {"
}
]
// ... and 598 more files (download for full content)
About this extraction
This page contains the full source code of the edshadi/relax GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 798 files (1.2 MB), approximately 359.5k tokens, and a symbol index with 1708 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.