├── .arcconfig
├── .buildpacks
├── .dockerignore
├── .editorconfig
├── .github
├── ISSUE_TEMPLATE.md
├── PULL_REQUEST_TEMPLATE.md
└── workflows
│ └── test-and-ship.yml
├── .gitignore
├── .travis.yml
├── Dockerfile
├── LICENSE-AGPL
├── LICENSE.md
├── Procfile
├── README.md
├── api
├── .eslintrc
├── .gitignore
├── .prettierignore
├── babel.config.json
├── jest.config.js
├── package-lock.json
├── package.json
├── src
│ ├── config
│ │ ├── configEndpoint.js
│ │ └── settings.js
│ └── ushahidi-api.js
└── webpack.config.js
├── app
├── config.js.j2
├── config.json
└── config.json.j2
├── buildargs.env.encrypted
├── codeship-services.yml
├── codeship-steps.yml
├── deployment.env.encrypted
├── docker.env.encrypted
├── docker
├── build.Dockerfile
├── build.run.sh
├── nginx.default.conf
├── nginx.run.sh
├── release.Dockerfile
├── release.run.sh
├── test.Dockerfile
└── test.run.sh
├── legacy
├── .arclint
├── .babelrc
├── .eslintignore
├── .eslintrc
├── .gitignore
├── app.json
├── app
│ ├── .well-known
│ │ ├── apple-app-site-association
│ │ └── assetlinks.json
│ ├── activity
│ │ ├── activity-module.js
│ │ ├── activity-routes.js
│ │ ├── activity-timeline.directive.js
│ │ ├── activity-timeline.html
│ │ ├── activity.controller.js
│ │ ├── activity.html
│ │ ├── bar-chart.directive.js
│ │ ├── bar-chart.html
│ │ ├── crowdsourced-survey-table.directive.js
│ │ ├── crowdsourced-survey-table.html
│ │ ├── targeted-survey-table.directive.js
│ │ ├── targeted-survey-table.html
│ │ ├── time-chart.directive.js
│ │ └── time-chart.html
│ ├── app.js
│ ├── auth
│ │ ├── 404.controller.js
│ │ ├── 404.html
│ │ ├── auth-module.js
│ │ ├── auth-routes.js
│ │ ├── authentication-events.run.js
│ │ ├── authentication-interceptor.config.js
│ │ ├── authentication.service.js
│ │ ├── forbidden.controller.js
│ │ ├── forbidden.html
│ │ ├── login.controller.js
│ │ ├── login.directive.js
│ │ ├── login.html
│ │ ├── password-reset-confirm.controller.js
│ │ ├── password-reset-confirm.directive.js
│ │ ├── password-reset-confirm.html
│ │ ├── password-reset.controller.js
│ │ ├── password-reset.directive.js
│ │ ├── password-reset.html
│ │ ├── password-reset.service.js
│ │ ├── register.controller.js
│ │ ├── register.directive.js
│ │ ├── register.html
│ │ ├── registration.service.js
│ │ ├── services
│ │ │ └── terms-of-service-endpoint.js
│ │ ├── session.service.js
│ │ ├── tos.directive.js
│ │ ├── tos.html
│ │ └── tos.service.js
│ ├── bootstrap.js
│ ├── common
│ │ ├── common-module.js
│ │ ├── common-routes.js
│ │ ├── configs
│ │ │ ├── cache-config.js
│ │ │ ├── loading.interceptor-config.js
│ │ │ ├── locale-config.js
│ │ │ ├── ui-bootstrap-template-decorators.js
│ │ │ └── uib-pagination.html
│ │ ├── controllers
│ │ │ ├── intercom.js
│ │ │ └── navigation.js
│ │ ├── directives
│ │ │ ├── adaptive-input.js
│ │ │ ├── add-language.directive.js
│ │ │ ├── add-language.html
│ │ │ ├── custom-on-change.js
│ │ │ ├── dropdown.js
│ │ │ ├── embed-only.directive.js
│ │ │ ├── file-upload.directive.js
│ │ │ ├── file-upload.html
│ │ │ ├── first-time-config.html
│ │ │ ├── first-time-config.js
│ │ │ ├── focus.js
│ │ │ ├── language-switch.directive.js
│ │ │ ├── language-switch.html
│ │ │ ├── layout-class.directive.js
│ │ │ ├── list-toolbar.html
│ │ │ ├── list-toolbar.js
│ │ │ ├── loading-dots-button.directive.js
│ │ │ ├── loading-dots-button.html
│ │ │ ├── mainsheet-container.directive.js
│ │ │ ├── mainsheet-container.html
│ │ │ ├── modal-body.directive.js
│ │ │ ├── modal-container.directive.js
│ │ │ ├── modal-container.html
│ │ │ ├── modal.html
│ │ │ ├── modal.js
│ │ │ ├── role-selector.directive.js
│ │ │ ├── role-selector.html
│ │ │ ├── translations-switch.directive.js
│ │ │ └── translations-switch.html
│ │ ├── donation
│ │ │ ├── donation-button.directive.js
│ │ │ ├── donation-button.html
│ │ │ ├── donation-modal.directive.js
│ │ │ ├── donation-modal.html
│ │ │ ├── donation-module.js
│ │ │ ├── donation-toolbar.directive.js
│ │ │ ├── donation-toolbar.html
│ │ │ ├── donation.directive.js
│ │ │ ├── donation.html
│ │ │ └── donation.service.js
│ │ ├── factories
│ │ │ └── loading.interceptor-factory.js
│ │ ├── global
│ │ │ ├── event-handlers.js
│ │ │ ├── language-list.json
│ │ │ └── language-settings.js
│ │ ├── locales
│ │ │ ├── ar.json
│ │ │ ├── bg-BG.json
│ │ │ ├── cs.json
│ │ │ ├── de.json
│ │ │ ├── en.json
│ │ │ ├── es.json
│ │ │ ├── fa-IR.json
│ │ │ ├── fr-FR.json
│ │ │ ├── fr.json
│ │ │ ├── hr.json
│ │ │ ├── ht.json
│ │ │ ├── hu.json
│ │ │ ├── hy.json
│ │ │ ├── id.json
│ │ │ ├── it.json
│ │ │ ├── ja.json
│ │ │ ├── languages.json
│ │ │ ├── nl.json
│ │ │ ├── pt-BR.json
│ │ │ ├── ru.json
│ │ │ ├── sq-AL.json
│ │ │ ├── sw.json
│ │ │ ├── vi-VN.json
│ │ │ ├── vi.json
│ │ │ ├── zh-TW.json
│ │ │ └── zh.json
│ │ ├── notifications
│ │ │ ├── api-errors.html
│ │ │ ├── limit.html
│ │ │ ├── notify.service.js
│ │ │ ├── slider.directive.js
│ │ │ ├── slider.html
│ │ │ └── slider.service.js
│ │ ├── raven
│ │ │ ├── raven.js
│ │ │ └── raven.service.js
│ │ ├── services
│ │ │ ├── collections.service.js
│ │ │ ├── data-export.service.js
│ │ │ ├── data-import.service.js
│ │ │ ├── endpoints
│ │ │ │ ├── MediaEndpoint.js
│ │ │ │ ├── collection.js
│ │ │ │ ├── config.js
│ │ │ │ ├── contact.js
│ │ │ │ ├── data-import.js
│ │ │ │ ├── export-jobs.js
│ │ │ │ ├── form-attributes.js
│ │ │ │ ├── form-stats-endpoint.js
│ │ │ │ ├── form.js
│ │ │ │ ├── hxl-tag-endpoint.js
│ │ │ │ ├── notification.js
│ │ │ │ ├── post-endpoint.js
│ │ │ │ ├── post-lock-endpoint.js
│ │ │ │ ├── role.js
│ │ │ │ ├── savedsearch.js
│ │ │ │ ├── sdk
│ │ │ │ │ ├── CategoriesSdk.js
│ │ │ │ │ ├── PostsSdk.js
│ │ │ │ │ ├── SurveysSdk.js
│ │ │ │ │ └── UtilsSdk.js
│ │ │ │ ├── tag.js
│ │ │ │ └── user-endpoint.js
│ │ │ ├── features.js
│ │ │ ├── geocoding.js
│ │ │ ├── import-complete.html
│ │ │ ├── import.notify.service.js
│ │ │ ├── languages.js
│ │ │ ├── loadingProgress.service.js
│ │ │ ├── mainsheet.service.js
│ │ │ ├── maps.js
│ │ │ ├── modal.service.js
│ │ │ ├── post-filters.service.js
│ │ │ ├── post-lock.service.js
│ │ │ ├── post-survey.service.js
│ │ │ ├── translation.service.js
│ │ │ └── util.js
│ │ ├── user-profile
│ │ │ ├── account-settings.directive.js
│ │ │ ├── account_settings.html
│ │ │ ├── admin-user-setup.directive.js
│ │ │ ├── admin-user-setup.html
│ │ │ ├── notifications.directive.js
│ │ │ ├── notifications.html
│ │ │ ├── user-profile-module.js
│ │ │ ├── user-profile.directive.js
│ │ │ └── user-profile.html
│ │ └── verifier
│ │ │ ├── verifier.controller.js
│ │ │ ├── verifier.html
│ │ │ ├── verifier.js
│ │ │ └── verifier.service.js
│ ├── data
│ │ ├── add-post-text-button.directive.js
│ │ ├── add-post-text-button.html
│ │ ├── collection-toggle
│ │ │ ├── collection-toggle-button.html
│ │ │ └── collection-toggle-button.js
│ │ ├── common
│ │ │ ├── post-edit-create
│ │ │ │ ├── location.directive.js
│ │ │ │ ├── location.html
│ │ │ │ ├── media-edit.service.js
│ │ │ │ ├── media.html
│ │ │ │ ├── post-category-editor.html
│ │ │ │ ├── post-category-editor.js
│ │ │ │ ├── post-datetime-value.directive.js
│ │ │ │ ├── post-datetime-value.html
│ │ │ │ ├── post-edit.controller.js
│ │ │ │ ├── post-edit.service.js
│ │ │ │ ├── post-media.directive.js
│ │ │ │ ├── post-relation.directive.js
│ │ │ │ ├── post-tabs.directive.js
│ │ │ │ ├── post-tabs.html
│ │ │ │ ├── post-value-edit.directive.js
│ │ │ │ ├── post-value-edit.html
│ │ │ │ ├── post-video.directive.js
│ │ │ │ ├── relation.html
│ │ │ │ └── video.html
│ │ │ ├── post-edit-detail-create
│ │ │ │ ├── post-entity.service.js
│ │ │ │ ├── survey-language-selector.directive.js
│ │ │ │ └── survey-language-selector.html
│ │ │ └── post-edit-detail
│ │ │ │ ├── post-messages-reply.html
│ │ │ │ ├── post-messages.directive.js
│ │ │ │ └── post-messages.html
│ │ ├── data-module.js
│ │ ├── data-routes.js
│ │ ├── post-create
│ │ │ ├── main.html
│ │ │ ├── post-create.controller.js
│ │ │ ├── post-editor.directive.js
│ │ │ └── post-editor.html
│ │ ├── post-detail
│ │ │ ├── add-form.html
│ │ │ ├── map.directive.js
│ │ │ ├── map.html
│ │ │ ├── post-add-form.directive.js
│ │ │ ├── post-category-value.directive.js
│ │ │ ├── post-category-value.html
│ │ │ ├── post-detail-data.directive.js
│ │ │ ├── post-detail-data.html
│ │ │ ├── post-lock.directive.js
│ │ │ ├── post-lock.html
│ │ │ ├── post-media-value.directive.js
│ │ │ ├── post-media-value.html
│ │ │ ├── post-value.directive.js
│ │ │ ├── post-value.html
│ │ │ ├── post-video-value.directive.js
│ │ │ └── post-video-value.html
│ │ ├── post-edit
│ │ │ ├── post-data-editor.directive.js
│ │ │ ├── post-data-editor.html
│ │ │ ├── post-toolbox.directive.js
│ │ │ ├── post-toolbox.html
│ │ │ ├── post-translation-editor.directive.js
│ │ │ └── post-translation-editor.html
│ │ ├── post-view-data.directive.js
│ │ ├── post-view-data.html
│ │ ├── post-view.service.js
│ │ └── services
│ │ │ └── message.js
│ ├── gtm-userprops.js
│ ├── index.html
│ ├── map
│ │ ├── collections
│ │ │ ├── editor.directive.js
│ │ │ ├── editor.html
│ │ │ ├── listing.directive.js
│ │ │ ├── listing.html
│ │ │ ├── mode-context.directive.js
│ │ │ └── mode-context.html
│ │ ├── directives
│ │ │ └── overflow-toggle.js
│ │ ├── map-module.js
│ │ ├── map-routes.js
│ │ ├── mode-context
│ │ │ ├── filter-by-datasource.directive.js
│ │ │ ├── filter-by-datasource.html
│ │ │ ├── filter-by-survey-dropdown.directive.js
│ │ │ ├── mode-context-form-filter.directive.js
│ │ │ ├── mode-context-form-filter.html
│ │ │ ├── mode-context.directive.js
│ │ │ └── mode-context.html
│ │ ├── post-card
│ │ │ ├── card.html
│ │ │ ├── collection-toggle
│ │ │ │ ├── collection-toggle-link.html
│ │ │ │ └── collection-toggle-link.js
│ │ │ ├── post-actions.directive.js
│ │ │ ├── post-actions.html
│ │ │ ├── post-actions.service.js
│ │ │ ├── post-card.directive.js
│ │ │ ├── post-metadata.directive.js
│ │ │ ├── post-metadata.html
│ │ │ ├── post-metadata.service.js
│ │ │ ├── post-preview-media.directive.js
│ │ │ └── post-preview-media.html
│ │ ├── post-toolbar
│ │ │ ├── add-post
│ │ │ │ ├── add-post-button.directive.js
│ │ │ │ ├── add-post-button.html
│ │ │ │ ├── add-post-survey-list.directive.js
│ │ │ │ └── add-post-survey-list.html
│ │ │ ├── filter-posts.directive.js
│ │ │ ├── filter-posts.html
│ │ │ ├── filters
│ │ │ │ ├── active-search-filters.directive.js
│ │ │ │ ├── active-search-filters.html
│ │ │ │ ├── filter-category.directive.js
│ │ │ │ ├── filter-category.html
│ │ │ │ ├── filter-date.directive.js
│ │ │ │ ├── filter-date.html
│ │ │ │ ├── filter-form.directive.js
│ │ │ │ ├── filter-form.html
│ │ │ │ ├── filter-has-location.directive.js
│ │ │ │ ├── filter-has-location.html
│ │ │ │ ├── filter-location.directive.js
│ │ │ │ ├── filter-location.html
│ │ │ │ ├── filter-post-order-asc-desc.directive.js
│ │ │ │ ├── filter-post-order-asc-desc.html
│ │ │ │ ├── filter-post-sorting-options.directive.js
│ │ │ │ ├── filter-post-sorting-options.html
│ │ │ │ ├── filter-saved-search.directive.js
│ │ │ │ ├── filter-saved-search.html
│ │ │ │ ├── filter-source.directive.js
│ │ │ │ ├── filter-source.html
│ │ │ │ ├── filter-status.directive.js
│ │ │ │ ├── filter-status.html
│ │ │ │ ├── filter-transformers.service.js
│ │ │ │ ├── filter-unlocked-on-top.directive.js
│ │ │ │ ├── filter-unlocked-on-top.html
│ │ │ │ ├── filter-visible-to.directive.js
│ │ │ │ ├── filter-visible-to.html
│ │ │ │ ├── filters-dropdown.directive.js
│ │ │ │ └── filters-dropdown.html
│ │ │ ├── post-toolbar.directive.js
│ │ │ ├── post-toolbar.html
│ │ │ ├── share
│ │ │ │ ├── post-export.directive.js
│ │ │ │ ├── post-export.html
│ │ │ │ ├── post-share.directive.js
│ │ │ │ ├── post-share.html
│ │ │ │ ├── share-menu-modal.directive.js
│ │ │ │ ├── share-menu-modal.html
│ │ │ │ ├── share-menu.directive.js
│ │ │ │ └── share-menu.html
│ │ │ ├── sort-and-filter-counter.directive.js
│ │ │ └── sort-and-filter-counter.html
│ │ ├── post-view-map.directive.js
│ │ ├── post-view-map.html
│ │ ├── post-view-noui.controller.js
│ │ ├── post-view-noui.html
│ │ ├── savedsearches
│ │ │ ├── editor-directive.js
│ │ │ ├── mode-context.directive.js
│ │ │ ├── mode-context.html
│ │ │ └── savedsearch-editor.html
│ │ └── services
│ │ │ └── view-helper.js
│ ├── mock-backend-config.js
│ ├── mode-bar
│ │ ├── mode-bar.directive.js
│ │ ├── mode-bar.html
│ │ ├── mode-bar.module.js
│ │ ├── support-links.html
│ │ ├── ush-logo.directive.js
│ │ ├── ush-logo.html
│ │ └── ushahidi-logo.html
│ ├── settings
│ │ ├── categories
│ │ │ ├── categories-edit.html
│ │ │ ├── categories.controller.js
│ │ │ ├── categories.html
│ │ │ ├── category-translation-editor.directive.js
│ │ │ ├── category-translation-editor.html
│ │ │ └── edit.controller.js
│ │ ├── data-export
│ │ │ ├── data-export.controller.js
│ │ │ ├── data-export.html
│ │ │ ├── hdx-details.directive.js
│ │ │ ├── hdx-details.html
│ │ │ ├── hdx-export.controller.js
│ │ │ └── hdx-export.html
│ │ ├── data-import
│ │ │ ├── after-import.html
│ │ │ ├── data-after-import.controller.js
│ │ │ ├── data-after-import.directive.js
│ │ │ ├── data-import.controller.js
│ │ │ ├── data-import.directive.js
│ │ │ └── data-import.html
│ │ ├── datasources
│ │ │ ├── datasources.controller.js
│ │ │ ├── datasources.html
│ │ │ ├── gmail-auth.directive.js
│ │ │ └── gmail-auth.html
│ │ ├── directives
│ │ │ ├── category-selector.directive.js
│ │ │ ├── category-selector.html
│ │ │ ├── color-picker.html
│ │ │ ├── color-picker.js
│ │ │ ├── filter-system
│ │ │ │ ├── filter-role.html
│ │ │ │ ├── filter-role.js
│ │ │ │ ├── filter-searchbar.html
│ │ │ │ └── filter-searchbar.js
│ │ │ ├── loading-dots.directive.js
│ │ │ └── loading-dots.html
│ │ ├── donation
│ │ │ ├── donation.controller.js
│ │ │ ├── donation.directive.js
│ │ │ └── donation.html
│ │ ├── roles
│ │ │ ├── editor.directive.js
│ │ │ ├── roles-edit.html
│ │ │ ├── roles.controller.js
│ │ │ ├── roles.directive.js
│ │ │ └── roles.html
│ │ ├── services
│ │ │ ├── accessibility.service.js
│ │ │ ├── endpoints
│ │ │ │ ├── apikey.js
│ │ │ │ ├── country-code-endpoint.js
│ │ │ │ ├── data-providers.js
│ │ │ │ ├── form-contact.js
│ │ │ │ ├── form-roles.js
│ │ │ │ ├── form-stages.js
│ │ │ │ ├── hxl-license-endpoint.js
│ │ │ │ ├── hxl-metadata-endpoint.js
│ │ │ │ ├── hxl-organisations-endpoint.js
│ │ │ │ ├── permission.js
│ │ │ │ ├── user-settings.js
│ │ │ │ └── webhooks.js
│ │ │ └── hxl-export.service.js
│ │ ├── settings-list.controller.js
│ │ ├── settings-list.html
│ │ ├── settings-list.routes.js
│ │ ├── settings.controller.js
│ │ ├── settings.html
│ │ ├── settings.module.js
│ │ ├── settings.routes.js
│ │ ├── site
│ │ │ ├── editor.directive.js
│ │ │ ├── map.directive.js
│ │ │ ├── map.html
│ │ │ ├── settings-editor.html
│ │ │ ├── settings-general.html
│ │ │ └── site.controller.js
│ │ ├── surveys
│ │ │ ├── attribute-create.directive.js
│ │ │ ├── attribute-create.html
│ │ │ ├── attribute-editor.directive.js
│ │ │ ├── attribute-editor.html
│ │ │ ├── edit.controller.js
│ │ │ ├── field-translation-editor.directive.js
│ │ │ ├── field-translation-editor.html
│ │ │ ├── survey-edit.html
│ │ │ ├── survey-editor.directive.js
│ │ │ ├── survey-editor.html
│ │ │ ├── survey-success.html
│ │ │ ├── survey-translation-editor.directive.js
│ │ │ ├── survey-translation-editor.html
│ │ │ ├── survey.notify.service.js
│ │ │ ├── surveys.controller.js
│ │ │ ├── surveys.html
│ │ │ ├── targeted-surveys
│ │ │ │ ├── targeted-edit.controller.js
│ │ │ │ ├── targeted-question-modal.html
│ │ │ │ ├── targeted-question.directive.js
│ │ │ │ └── targeted-survey-edit.html
│ │ │ ├── task-create.directive.js
│ │ │ └── task-create.html
│ │ ├── user-settings
│ │ │ ├── user-settings.controller.js
│ │ │ └── user-settings.html
│ │ ├── users
│ │ │ ├── create.controller.js
│ │ │ ├── edit.controller.js
│ │ │ ├── filter-users.directive.js
│ │ │ ├── filter-users.html
│ │ │ ├── users-edit.html
│ │ │ ├── users.controller.js
│ │ │ └── users.html
│ │ └── webhooks
│ │ │ ├── editor.directive.js
│ │ │ ├── webhooks-edit.html
│ │ │ ├── webhooks.controller.js
│ │ │ ├── webhooks.directive.js
│ │ │ └── webhooks.html
│ └── test-bootstrap.js
├── gulp
│ ├── transifex-download.js
│ └── verifier.js
├── gulpfile.babel.js
├── mocked_backend
│ └── api
│ │ └── v3
│ │ ├── attributes.json
│ │ ├── collections.json
│ │ ├── config.json
│ │ ├── config
│ │ ├── features.json
│ │ ├── map.json
│ │ └── site.json
│ │ ├── forms.json
│ │ ├── forms
│ │ ├── 1.json
│ │ └── 3.json
│ │ ├── posts.json
│ │ ├── posts
│ │ ├── 120.json
│ │ └── 999.json
│ │ ├── roles.json
│ │ ├── sets.json
│ │ ├── stages.json
│ │ ├── stages
│ │ └── 4.json
│ │ ├── tags.json
│ │ ├── tasks.json
│ │ ├── users.json
│ │ └── users
│ │ └── me.json
├── package-lock.json
├── package.json
├── sass
│ ├── overrides
│ │ ├── _dropdown.scss
│ │ ├── _filters.scss
│ │ ├── _intercom.scss
│ │ ├── _leaflet.scss
│ │ ├── _modal.scss
│ │ └── _tui-markdown.scss
│ └── vendor.scss
├── test
│ ├── karma.conf.js
│ ├── pre_test.sh
│ ├── test.sh
│ └── unit
│ │ ├── common
│ │ ├── auth
│ │ │ ├── authentication-events.run.spec.js
│ │ │ ├── authentication-interceptor.config.spec.js
│ │ │ ├── authentication.service.spec.js
│ │ │ ├── login.directive.spec.js
│ │ │ ├── password-reset-confirm.directive.spec.js
│ │ │ ├── password-reset.directive.spec.js
│ │ │ ├── session-spec.js
│ │ │ └── tos.service.spec.js
│ │ ├── controllers
│ │ │ └── intercom.js
│ │ ├── directives
│ │ │ ├── category-selector.directive.spec.js
│ │ │ ├── category-selector.parentsEnabled.directive.spec.js
│ │ │ ├── embed-only.directive.spec.js
│ │ │ ├── file-upload.directive.spec.js
│ │ │ ├── language-switch.directive.spec.js
│ │ │ ├── layout-class.directive.spec.js
│ │ │ └── role-selector.directive.spec.js
│ │ ├── global
│ │ │ └── event-handlers-spec.js
│ │ ├── notifications
│ │ │ └── notify.service.spec.js
│ │ ├── raven.spec.js
│ │ ├── services
│ │ │ ├── LoadingProgress.service.spec.js
│ │ │ ├── endpoints
│ │ │ │ ├── form-attributes.js
│ │ │ │ ├── form-stages.js
│ │ │ │ ├── form.js
│ │ │ │ ├── permission-endpoint-spec.js
│ │ │ │ ├── post-endpoint-spec.js
│ │ │ │ ├── role-endpoint-spec.js
│ │ │ │ ├── tag.js
│ │ │ │ └── user-endpoint-spec.js
│ │ │ ├── features.js
│ │ │ ├── util-spec.js
│ │ │ └── view-helper-spec.js
│ │ └── user-profile
│ │ │ └── directives
│ │ │ ├── notifications-directive-spec.js
│ │ │ └── user-profile-directive-spec.js
│ │ ├── main
│ │ ├── activity
│ │ │ ├── activity.controller.spec.js
│ │ │ ├── bar-chart.directive.spec.js
│ │ │ └── time-chart.directive.spec.js
│ │ └── post
│ │ │ ├── collections
│ │ │ └── mode-context.spec.js
│ │ │ ├── common
│ │ │ ├── post-actions.directive.spec.js
│ │ │ ├── post-actions.service.spec.js
│ │ │ └── post-metadata.service.spec.js
│ │ │ ├── detail
│ │ │ ├── post-detail-data.directive.spec.js
│ │ │ ├── post-media-value.directive.spec.js
│ │ │ ├── post-messages.directive.spec.js
│ │ │ └── post-value.directive.spec.js
│ │ │ ├── modify
│ │ │ ├── location.directive.spec.js
│ │ │ ├── media-edit.service.spec.js
│ │ │ ├── post-create.controller.spec.js
│ │ │ ├── post-edit.controller.spec.js
│ │ │ ├── post-edit.service.spec.js
│ │ │ ├── post-editor.directive.spec.js
│ │ │ ├── post-media.directive.spec.js
│ │ │ ├── post-relation.directive.spec.js
│ │ │ ├── post-tabs.directive.spec.js
│ │ │ ├── post-value-edit.directive.spec.js
│ │ │ └── post-video.directive.spec.js
│ │ │ ├── savedsearches
│ │ │ └── mode-context.spec.js
│ │ │ └── views
│ │ │ ├── filter-by-datasource.spec.js
│ │ │ ├── filters
│ │ │ ├── active-search-filters.directive.spec.js
│ │ │ ├── filter-category.directive.spec.js
│ │ │ ├── filter-post-order-asc-desc.spec.js
│ │ │ ├── filter-post-sorting-options.directive.spec.js
│ │ │ ├── filter-unlocked-on-top.directive.spec.js
│ │ │ ├── filters-dropdown.directive.spec.js
│ │ │ ├── filters-posts.directive.spec.js
│ │ │ ├── post-filters-add-if-current-matches-original.service.spec.js
│ │ │ ├── post-filters-clean-ui-filters.service.spec.js
│ │ │ ├── post-filters.service.spec.js
│ │ │ └── sort-and-filter-counter.directive.spec.js
│ │ │ ├── mode-context-form-filter.directive.spec.js
│ │ │ ├── post-card.directive.spec.js
│ │ │ ├── post-preview-media.directive.spec.js
│ │ │ ├── post-view-data.directive.spec.js
│ │ │ ├── post-view-map.directive.spec.js
│ │ │ └── share
│ │ │ └── post-export.directive.spec.js
│ │ ├── make-test-app.js
│ │ ├── mock
│ │ ├── controllers
│ │ │ └── navigation.controller.mock.js
│ │ ├── factories
│ │ │ └── socket-factory.mock.js
│ │ ├── mock-modules.js
│ │ └── services
│ │ │ ├── accessibility.service.js
│ │ │ ├── authentication.js
│ │ │ ├── collection.js
│ │ │ ├── config.js
│ │ │ ├── contact.js
│ │ │ ├── country-code-endpoint.js
│ │ │ ├── data-export.js
│ │ │ ├── data-import.js
│ │ │ ├── data-import.service.js
│ │ │ ├── data-provider.js
│ │ │ ├── data-retriever.js
│ │ │ ├── features.js
│ │ │ ├── form-attributes.js
│ │ │ ├── form-contact.js
│ │ │ ├── form-role.js
│ │ │ ├── form-stages.js
│ │ │ ├── form-stats-endpoint.js
│ │ │ ├── form.js
│ │ │ ├── global-filters.js
│ │ │ ├── hxl-export.js
│ │ │ ├── importnotify.js
│ │ │ ├── languages.js
│ │ │ ├── loadingProgress.service.js
│ │ │ ├── maps.js
│ │ │ ├── media-edit-service.js
│ │ │ ├── media.js
│ │ │ ├── message.js
│ │ │ ├── modal.service.js
│ │ │ ├── notification.js
│ │ │ ├── notify.js
│ │ │ ├── permission.js
│ │ │ ├── post-actions-service.js
│ │ │ ├── post-edit-service.js
│ │ │ ├── post-filters.js
│ │ │ ├── post-lock-endpoint.js
│ │ │ ├── post-lock.service.js
│ │ │ ├── post-metadata-service.js
│ │ │ ├── post-survey-service.js
│ │ │ ├── post-view-service.js
│ │ │ ├── post.js
│ │ │ ├── role.js
│ │ │ ├── savedsearch.js
│ │ │ ├── sdk
│ │ │ ├── CategoriesSdk.js
│ │ │ ├── PostsSdk.js
│ │ │ ├── SurveysSdk.js
│ │ │ └── UtilsSdk.js
│ │ │ ├── session.js
│ │ │ ├── survey-notify.js
│ │ │ ├── tag.js
│ │ │ ├── third_party
│ │ │ ├── leaflet.js
│ │ │ └── transitions.js
│ │ │ ├── translate.js
│ │ │ ├── translation-service.js
│ │ │ ├── user-settings.js
│ │ │ └── user.js
│ │ ├── settings
│ │ ├── categories
│ │ │ ├── categories-controller-spec.js
│ │ │ └── categories-edit-controller-spec.js
│ │ ├── data-export
│ │ │ ├── data-export.controller.spec.js
│ │ │ └── hdx-export.controller.spec.js
│ │ ├── data-import
│ │ │ ├── after-data-import.directive.spec.js
│ │ │ ├── data-import-controller-spec.js
│ │ │ └── setting-data-import-directive-spec.js
│ │ ├── datasources
│ │ │ └── datasources-controller-spec.js
│ │ ├── roles
│ │ │ ├── roles-controller-spec.js
│ │ │ ├── setting-roles-directive-spec.js
│ │ │ └── setting-roles-editor-directive-spec.js
│ │ ├── site
│ │ │ ├── general-controller-spec.js
│ │ │ ├── setting-editor-directive-spec.js
│ │ │ └── setting-map-directive-spec.js
│ │ ├── surveys
│ │ │ ├── settings-survey-editor.directive.spec.js
│ │ │ ├── survey-translation-editor.directive.spec.js
│ │ │ └── targeted-edit.controller.spec.js
│ │ └── users
│ │ │ ├── users-controller-spec.js
│ │ │ ├── users-create-controller-spec.js
│ │ │ └── users-edit-controller-spec.js
│ │ └── spec.bundle.js
├── webpack.config.js
├── webpack.dev.config.js
├── webpack.dist.config.js
└── webpack.test.config.js
├── package-lock.json
├── package.json
├── root
├── .eslintignore
├── .eslintrc
├── .gitignore
├── .prettierignore
├── babel.config.json
├── package-lock.json
├── package.json
├── src
│ ├── config.js
│ ├── datalayer.js
│ ├── importmap.json
│ ├── index.ejs
│ ├── loading.scss
│ ├── microfrontend-layout.html
│ └── ushahidi-root-config.js
└── webpack.config.js
├── server
├── nginx-site.conf
├── rewrite.htaccess
└── scripts
│ ├── generateImportMap.js
│ ├── proxy.js
│ ├── ready.js
│ └── start.js
├── single.stage.Dockerfile
└── utilities
├── .eslintrc
├── .gitignore
├── .prettierignore
├── babel.config.json
├── jest.config.js
├── package-lock.json
├── package.json
├── src
└── ushahidi-utilities.js
└── webpack.config.js
/.arcconfig:
--------------------------------------------------------------------------------
1 | {
2 | "phabricator.uri" : "https://phabricator.ushahidi.com/",
3 | "repository.callsign" : "UWEB"
4 | }
5 |
--------------------------------------------------------------------------------
/.buildpacks:
--------------------------------------------------------------------------------
1 | https://github.com/heroku/heroku-buildpack-nodejs
2 | https://github.com/rjmackay/heroku-buildpack-gulp
3 |
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | .git
2 | node_modules
3 | Dockerfile
4 | *.Dockerfile
5 | tmp
6 | .out
7 | codeship-*
8 | deployment.env
9 | deployment.env.encrypted
10 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = spaces
6 | indent_size = 4
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ### Expected behaviour
2 |
3 | ### Actual behaviour
4 |
5 | ### Steps to reproduce the behaviour/error
6 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | This pull request makes the following changes:
2 | -
3 |
4 | Testing checklist:
5 | - [ ]
6 |
7 | - [ ] I certify that I ran my checklist
8 |
9 | Fixes ushahidi/platform# .
10 |
11 | Ping @ushahidi/platform
12 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # dotrun package
9 | .docker-project
10 | .yarn.*.hash
11 | .dotrun.json
12 |
13 | npm-debug.log*
14 | yarn-debug.log*
15 | yarn-error.log*
16 |
17 | # build
18 | /build
19 | /tmp
20 |
21 | # local configuratinon
22 | .env.*.local
23 | .env.local
24 | .env
25 |
26 | # junk
27 | *.DS_Store
28 | *.fuse*
29 |
--------------------------------------------------------------------------------
/Procfile:
--------------------------------------------------------------------------------
1 | web: npm start
2 |
--------------------------------------------------------------------------------
/api/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["important-stuff", "plugin:prettier/recommended"],
3 | "parser": "@babel/eslint-parser"
4 | }
5 |
--------------------------------------------------------------------------------
/api/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (https://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # TypeScript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 | # next.js build output
61 | .next
62 | dist
63 |
64 | # Editor directories and files
65 | .idea
66 | .vscode
67 | *.suo
68 | *.ntvs*
69 | *.njsproj
70 | *.sln
71 | *.sw?
72 | .DS_Store
73 |
--------------------------------------------------------------------------------
/api/.prettierignore:
--------------------------------------------------------------------------------
1 | .gitignore
2 | .prettierignore
3 | yarn.lock
4 | yarn-error.log
5 | package-lock.json
6 | dist
7 | coverage
8 | pnpm-lock.yaml
--------------------------------------------------------------------------------
/api/babel.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@babel/preset-env"],
3 | "plugins": [
4 | [
5 | "@babel/plugin-transform-runtime",
6 | {
7 | "useESModules": true,
8 | "regenerator": false
9 | }
10 | ]
11 | ],
12 | "env": {
13 | "test": {
14 | "presets": [
15 | [
16 | "@babel/preset-env",
17 | {
18 | "targets": "current node"
19 | }
20 | ]
21 | ]
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/api/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | transform: {
3 | "^.+\\.(j|t)sx?$": "babel-jest",
4 | },
5 | moduleNameMapper: {
6 | "\\.(css)$": "identity-obj-proxy",
7 | },
8 | };
9 |
--------------------------------------------------------------------------------
/api/src/config/configEndpoint.js:
--------------------------------------------------------------------------------
1 | import * as UshahidiSdk from "ushahidi-platform-sdk/build/src/index";
2 | import { getBackendUrl } from "./settings.js";
3 |
4 | const backendUrl = getBackendUrl();
5 | const ushahidi = new UshahidiSdk.Config(backendUrl);
6 |
7 | export const getConfig = function (id = "") {
8 | return ushahidi.getConfig(id);
9 | };
10 |
--------------------------------------------------------------------------------
/api/src/config/settings.js:
--------------------------------------------------------------------------------
1 | export const getBackendUrl = function () {
2 | let backendUrl = "";
3 | // window.ushahidi.backendUrl is configured in ./root/src/config.js
4 | // BACKEND_URL is set on build-time with Webpack from environment variables
5 | if (window.ushahidi && window.ushahidi.backendUrl) {
6 | backendUrl = window.ushahidi.backendUrl;
7 | } else {
8 | backendUrl = BACKEND_URL;
9 | }
10 |
11 | // REGEX to format the url correctly
12 | return backendUrl.replace(/\/$/, "");
13 | };
14 |
--------------------------------------------------------------------------------
/api/src/ushahidi-api.js:
--------------------------------------------------------------------------------
1 | export { getConfig } from "./config/configEndpoint";
2 |
--------------------------------------------------------------------------------
/api/webpack.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require("webpack");
2 | const { merge } = require("webpack-merge");
3 | const singleSpaDefaults = require("webpack-config-single-spa");
4 |
5 | module.exports = (webpackConfigEnv, argv) => {
6 | const defaultConfig = singleSpaDefaults({
7 | orgName: "ushahidi",
8 | projectName: "api",
9 | webpackConfigEnv,
10 | argv,
11 | });
12 | let filename = defaultConfig.mode === 'development' ? 'ushahidi-api.js' : 'ushahidi-api.[chunkhash].js';
13 |
14 | return merge(defaultConfig, {
15 | output: {
16 | filename,
17 | clean: true
18 | },
19 | plugins: [
20 | new webpack.DefinePlugin({
21 | BACKEND_URL: JSON.stringify(
22 | process.env.BACKEND_URL || "http://backend.url.undefined"
23 | ),
24 | }),
25 | ],
26 | });
27 | };
28 |
--------------------------------------------------------------------------------
/app/config.js.j2:
--------------------------------------------------------------------------------
1 | // Configure your Ushahidi deployment
2 |
3 | window.ushahidi = {
4 | backendUrl: '{{ BACKEND_URL }}',
5 | mapboxApiKey: '{{ MAPBOX_API_KEY }}',
6 | {% if GA_KEY %}
7 | gaEnabled: true,
8 | gaKey: '{{ GA_KEY }}',
9 | {% else %}
10 | gaEnabled: false,
11 | {% endif %}
12 | {% if GOOGLE_MAPS_API_KEY %}
13 | googleMapsApiKey: '{{ GOOGLE_MAPS_API_KEY }}',
14 | {% endif %}
15 | {% if GTM_CONTAINER_ID %}
16 | googleTagManager: '{{ GTM_CONTAINER_ID }}',
17 | {% endif %}
18 | intercomAppId: '{{ INTERCOM_APPID }}',
19 | appStoreId: '{{ APP_STORE_ID }}',
20 | ravenUrl: '{{ RAVEN_URL }}',
21 | tosReleaseDate: '{{ TOS_RELEASE_DATE }}',
22 | {% if ENABLED_SOURCES %}}
23 | sources: {{ ENABLED_SOURCES.split(',') | map('trim') | list }},
24 | {% endif %}
25 | }
26 |
--------------------------------------------------------------------------------
/app/config.json:
--------------------------------------------------------------------------------
1 | // Set configuration for Ushahidi mobile app
2 |
3 | //{
4 | // client_id: "",
5 | // client_secret: "",
6 | // backend_url: "",
7 | // google_analytics_id: "",
8 | // intercom_app_id: "",
9 | // mapbox_api_key: "",
10 | // raven_url: ""
11 | //}
12 |
--------------------------------------------------------------------------------
/app/config.json.j2:
--------------------------------------------------------------------------------
1 | {
2 | "client_id": "{{ OAUTH_CLIENT_ID | default('ushahidiui') }}",
3 | "client_secret": "{{ OAUTH_CLIENT_SECRET | default('35e7f0bca957836d05ca0492211b0ac707671261') }}",
4 | "backend_url": "{{ BACKEND_URL }}",
5 | "google_analytics_id": "{{ GA_KEY }}",
6 | "intercom_app_id": "{{ INTERCOM_APPID }}",
7 | "mapbox_api_key": "{{ MAPBOX_API_KEY }}",
8 | "raven_url": "{{ RAVEN_URL }}"
9 | }
10 |
--------------------------------------------------------------------------------
/buildargs.env.encrypted:
--------------------------------------------------------------------------------
1 | aUXiCjDBqCPhEAYhlXLXpC+lGUL9jevdDHq4jpNE497/BEwS2gQXdBtjIp3OHly/66Jcaloj1FSlpRizlpBDk4HHs8k=
--------------------------------------------------------------------------------
/codeship-steps.yml:
--------------------------------------------------------------------------------
1 | # run 'jet run test gulp test' for tests
2 |
3 | - name: "Build client"
4 | service: build
5 | command: build
6 |
7 |
8 | - type: parallel
9 | steps:
10 | - name: "Release bundle"
11 | service: release
12 | command: release
13 | tag: '^v[0-9]\.[0-9]+.[0-9]+([\-a-zA-Z0-9\.]+)?$'
14 | - name: "Deployment director"
15 | service: deploy
16 | command: CI_NAME=codeship ush-deployment-director.sh
17 |
18 |
--------------------------------------------------------------------------------
/docker.env.encrypted:
--------------------------------------------------------------------------------
1 | codeship:v2
2 | CB3n+FyxdRS8Za5VdpyiyNnyP9Io1Yj0NKWf6LDrN7/GOo/0ACbNhWjJvKCXTfFiR38XGXrxFGv85yg+FirQeXYjKRpZs8dReWAZKDXrzGl2UL4p82yUJSVDPKMwyEgVANVzrYi8uAAEEjzKv+ocRITTqp5JS2rjMIkb7KifzvMJgQsUO7iBcCiK3giyUF3QpmsSgB2nomwhf7JBDppzIC/xXF8A/g==
--------------------------------------------------------------------------------
/docker/build.Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ushahidi/node-ci:node-10-gulp-4
2 |
3 | RUN mkdir -p /var/app
4 | WORKDIR /var/app
5 | COPY ./package.json ./
6 | COPY ./root/package.json ./root/package.json
7 | COPY ./legacy/package.json ./legacy/package.json
8 | COPY ./utilities/package.json ./utilities/package.json
9 | COPY ./api/package.json ./api/package.json
10 | RUN npm run install:all
11 |
12 | COPY docker/build.run.sh /build.run.sh
13 |
14 | ENTRYPOINT [ "/bin/bash", "/build.run.sh" ]
15 |
--------------------------------------------------------------------------------
/docker/nginx.default.conf:
--------------------------------------------------------------------------------
1 | server {
2 |
3 | listen $HTTP_PORT default_server;
4 | server_name _;
5 |
6 | root /usr/share/nginx/html;
7 | index index.html index.htm;
8 |
9 | location / {
10 | try_files $uri $uri/ @missing;
11 | }
12 |
13 | # Rewrite 404s back to index.html for pushState support
14 | # All routing is handled by Angular.
15 | location @missing {
16 | rewrite ^ /index.html last;
17 | }
18 |
19 | }
--------------------------------------------------------------------------------
/docker/nginx.run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | if [ "$1" = "noop" ]; then
4 | # do nothing operator
5 | sleep infinity
6 | exit 0;
7 | fi
8 |
9 | # patch in frontend configuration
10 | if [ -z "$BACKEND_URL" ]; then
11 | echo "ERROR! You must provide a BACKEND_URL variable pointing at an ushahidi API host"
12 | exit 1
13 | fi
14 |
15 | if [ -n "`which jinja`" ]; then
16 | if [ -f config.js.j2 ]; then
17 | echo "- Generating config.js from template:"
18 | python3 -c 'import os, json ; print(json.dumps(dict(os.environ)))' | \
19 | jinja -d - -f json config.js.j2 | \
20 | tee config.js
21 | fi
22 |
23 | if [ -f config.json.j2 ]; then
24 | echo "- Generating config.json from template:"
25 | python3 -c 'import os, json ; print(json.dumps(dict(os.environ)))' | \
26 | jinja -d - -f json config.json.j2 | \
27 | tee config.json
28 | fi
29 | fi
30 |
31 | # execute the provided command
32 | exec "$@"
33 |
--------------------------------------------------------------------------------
/docker/release.Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.14
2 |
3 | RUN go get github.com/ushahidi/github-release
4 |
5 | COPY docker/release.run.sh /release.run.sh
6 |
7 | ENTRYPOINT [ "/bin/bash", "/release.run.sh" ]
8 |
--------------------------------------------------------------------------------
/docker/release.run.sh:
--------------------------------------------------------------------------------
1 | #/bin/sh
2 |
3 | set -ex
4 |
5 | if [ -z "$GITHUB_RELEASE_TOKEN" ]; then
6 | echo "Please provide a GITHUB_RELEASE_TOKEN environment variable!"
7 | fi
8 |
9 | export GITHUB_TOKEN=$GITHUB_RELEASE_TOKEN
10 |
11 | GITHUB_ORG=${GITHUB_ORG:-ushahidi}
12 | GITHUB_REPO_NAME=${GITHUB_REPO_NAME:-$CI_REPO_NAME}
13 | GITHUB_VERSION=${GITHUB_VERSION:-$CI_BRANCH}
14 |
15 | ghr() {
16 | local cmd=$1
17 | shift 1
18 | /go/bin/github-release $cmd \
19 | --user $GITHUB_ORG \
20 | --repo $GITHUB_REPO_NAME \
21 | $*
22 | }
23 |
24 | if ghr info --tag $GITHUB_VERSION ; then
25 | # release already exists, leave it alone
26 | echo "Release already exists, leaving it alone"
27 | else
28 | # release has to be created
29 | ghr release --tag $GITHUB_VERSION --name $GITHUB_VERSION
30 | fi
31 |
32 | for f in $(find /release -type f); do
33 | ghr upload --tag $GITHUB_VERSION --name $(basename $f) --file $f
34 | done
35 |
--------------------------------------------------------------------------------
/docker/test.Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ushahidi/node-ci:node-10-gulp-4
2 |
3 | RUN mkdir -p /var/app
4 | WORKDIR /var/app
5 | COPY package.json /var/app
6 | RUN npm-install-silent.sh
7 |
8 | COPY docker/test.run.sh /test.run.sh
9 |
10 | ENTRYPOINT [ "/bin/bash", "/test.run.sh" ]
11 |
--------------------------------------------------------------------------------
/docker/test.run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 |
5 | # Ensure volume with source code is present
6 | check_vols_src() {
7 | if [ ! -d /vols/src ]; then
8 | echo "No /vols/src with code"
9 | exit 1
10 | fi
11 | }
12 |
13 | # Sync from source code to the build directory, exclude any folders and file
14 | # that are result of the build process
15 | function sync {
16 | check_vols_src
17 | {
18 | echo "- .git"
19 | echo "- .bin"
20 | echo "- node_modules"
21 | echo "- tmp"
22 | } > /tmp/rsync_exclude
23 | rsync -ar --exclude-from=/tmp/rsync_exclude --delete-during /vols/src/ ./
24 | }
25 |
26 | install() {
27 | npm-install-silent.sh
28 | }
29 |
30 | sync
31 | install
32 | test/pre_test.sh
33 | test/test.sh
34 |
--------------------------------------------------------------------------------
/legacy/.arclint:
--------------------------------------------------------------------------------
1 | {
2 | "linters" : {
3 | "jshint" : {
4 | "type" : "jshint",
5 | "include" : "(\\.js$)",
6 | "exclude" : "@/bower_components/.*\\.js$@",
7 | "jshint.jshintrc" : ".jshintrc",
8 | "jshint.jshintignore" : ".jshintignore"
9 | },
10 | "jscs" : {
11 | "type" : "jscs",
12 | "include" : "(\\.js$)"
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/legacy/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": ["transform-runtime"],
3 | "presets": ["es2015", "stage-0"],
4 | "env": {
5 | "test": {
6 | "plugins": [ "istanbul" ]
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/legacy/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | bower_components
3 | test/coverage/
4 | server/www
5 |
--------------------------------------------------------------------------------
/legacy/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | .sass-cache
3 | bower_components
4 | node_modules
5 | npm-debug.log
6 | .gulpconfig.json
7 | .env
8 | test/coverage/
9 | build/*
10 | dist/*
11 | .DS_Store
12 | server/www/locales/
13 | *.aes
14 | *.swp
15 | *.swo
16 | buildargs.env
17 | deployment.env
18 | docker.env
19 | vault.txt
20 | *.swo
21 | *.swp
22 | *.svg
23 | server/www/img/icons/
24 | server/www/
25 | app/locales/
26 | app/stats.html
27 |
--------------------------------------------------------------------------------
/legacy/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Ushahidi Platform Client",
3 | "description": "The JS client for the Ushahidi Platform.",
4 | "keywords": [
5 | "ushahidi",
6 | "crowdmap"
7 | ],
8 | "website": "http://ushahidi.com",
9 | "repository": "https://github.com/ushahidi/platform-client",
10 | "logo": "http://www.ushahidi.com/assets/img/favicon.ico",
11 | "success_url": "/",
12 | "env": {
13 | "BUILDPACK_URL": "https://github.com/heroku/heroku-buildpack-multi.git",
14 | "NODE_ENV": "dev",
15 | "NPM_CONFIG_PRODUCTION": "false",
16 | "BACKEND_URL": {
17 | "description" : "A deployment of ushahidi/platform to use",
18 | "value" : "https://ushahidi-platform-api-master.herokuapp.com",
19 | "required" : true
20 | },
21 | "TX_USERNAME": {
22 | "description" : "Your username in transifex in order to download translation files (optional)",
23 | "required": false
24 | },
25 | "TX_PASSWORD": {
26 | "description": "Your password in transifex (optional)",
27 | "required": false
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/legacy/app/.well-known/apple-app-site-association:
--------------------------------------------------------------------------------
1 | {
2 | "applinks": {
3 | "apps": [],
4 | "details": [
5 | {
6 | "appID": "{{ appStoreLinkingId }}",
7 | "paths": [ "*"]
8 | }
9 | ]
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/legacy/app/.well-known/assetlinks.json:
--------------------------------------------------------------------------------
1 | [{
2 | "relation": ["delegate_permission/common.handle_all_urls"],
3 | "target": {
4 | "namespace": "android_app",
5 | "package_name": "com.ushahidi.mobile",
6 | "sha256_cert_fingerprints":
7 | ["2E:ED:51:63:46:74:11:3C:4B:B5:2D:2B:FA:51:93:18:34:7E:AB:24:84:3E:97:C6:F2:1B:00:20:ED:23:8F:63"]
8 | }
9 | }]
10 |
--------------------------------------------------------------------------------
/legacy/app/activity/activity-module.js:
--------------------------------------------------------------------------------
1 | export const ACTIVITY_MODULE = angular.module('ushahidi.activity', [])
2 |
3 | .directive('activityTimeline', require('./activity-timeline.directive.js'))
4 | .directive('activityBarChart', require('./bar-chart.directive.js'))
5 | .directive('activityTimeChart', require('./time-chart.directive.js'))
6 | .directive('targetedSurveyTable', require('./targeted-survey-table.directive.js'))
7 | .directive('crowdsourcedSurveyTable', require('./crowdsourced-survey-table.directive.js'))
8 | ;
9 |
--------------------------------------------------------------------------------
/legacy/app/activity/activity-routes.js:
--------------------------------------------------------------------------------
1 | angular.module('ushahidi.activity.routes', [])
2 |
3 | .config([
4 | '$stateProvider',
5 | '$urlMatcherFactoryProvider',
6 | function (
7 | $stateProvider,
8 | $urlMatcherFactoryProvider
9 | ) {
10 | $urlMatcherFactoryProvider.strictMode(false);
11 |
12 | $stateProvider
13 | .state({
14 | name: 'activity',
15 | url: '/activity',
16 | controller: require('./activity.controller.js'),
17 | template: require('./activity.html'),
18 | lazyLoad: function ($transition$) {
19 | const $ocLazyLoad = $transition$.injector().get('$ocLazyLoad');
20 | return System.import('@ushahidi/legacy-activity').then(mod => {
21 | $ocLazyLoad.load(mod.ACTIVITY_MODULE);
22 | });
23 | }
24 | });
25 | }]
26 | );
27 |
--------------------------------------------------------------------------------
/legacy/app/activity/bar-chart.html:
--------------------------------------------------------------------------------
1 |
2 |
19 |
20 |
graph.no_data
21 |
22 |
23 |
--------------------------------------------------------------------------------
/legacy/app/auth/404.controller.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$scope',
3 | function (
4 | $scope
5 | ) {
6 |
7 | }];
8 |
--------------------------------------------------------------------------------
/legacy/app/auth/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
nav.404
4 |
5 |
6 | app.404
7 |
8 |
9 |
--------------------------------------------------------------------------------
/legacy/app/auth/auth-module.js:
--------------------------------------------------------------------------------
1 | angular.module('ushahidi.auth', [])
2 |
3 | // Authentication
4 | .service('Authentication', require('./authentication.service.js'))
5 | .service('Registration', require('./registration.service.js'))
6 | .service('Session', require('./session.service.js'))
7 | .service('PasswordReset', require('./password-reset.service.js'))
8 | .service('TermsOfService', require('./tos.service.js'))
9 | .directive('login', require('./login.directive.js'))
10 | .directive('register', require('./register.directive.js'))
11 | .directive('passwordReset', require('./password-reset.directive.js'))
12 | .directive(
13 | 'passwordResetConfirm',
14 | require('./password-reset-confirm.directive.js')
15 | )
16 | .directive('termsOfService', require('./tos.directive.js'))
17 |
18 | // From common module
19 | .service('TermsOfServiceEndpoint', require('./services/terms-of-service-endpoint.js'))
20 |
21 | .config(require('./authentication-interceptor.config.js'))
22 | .run(require('./authentication-events.run.js'))
23 |
24 | .config(require('./auth-routes.js'))
25 |
--------------------------------------------------------------------------------
/legacy/app/auth/forbidden.controller.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$scope',
3 | function (
4 | $scope
5 | ) {
6 |
7 | }];
8 |
--------------------------------------------------------------------------------
/legacy/app/auth/forbidden.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
nav.forbidden
4 |
5 |
6 | app.forbidden
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/legacy/app/auth/login.controller.js:
--------------------------------------------------------------------------------
1 | module.exports = LoginController;
2 |
3 | LoginController.$inject = ['Authentication','$location'];
4 | function LoginController(Authentication, $location) {
5 | Authentication.openLogin();
6 | $location.url('/');
7 | }
8 |
--------------------------------------------------------------------------------
/legacy/app/auth/login.html:
--------------------------------------------------------------------------------
1 |
25 |
--------------------------------------------------------------------------------
/legacy/app/auth/password-reset-confirm.controller.js:
--------------------------------------------------------------------------------
1 | module.exports = PasswordResetConfirmController;
2 |
3 | PasswordResetConfirmController.$inject = ['$rootScope', 'PasswordReset', '$location', '$transition$'];
4 | function PasswordResetConfirmController($rootScope, PasswordReset, $location, $transition$) {
5 | var $scope = $rootScope.$new();
6 | $scope.token = $transition$.params().token;
7 |
8 | PasswordReset.openResetConfirm($scope);
9 | $location.url('/');
10 | }
11 |
--------------------------------------------------------------------------------
/legacy/app/auth/password-reset.controller.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | 'PasswordReset',
3 | '$location',
4 | function (
5 | PasswordReset,
6 | $location
7 | ) {
8 | PasswordReset.openReset();
9 | $location.url('/');
10 | }];
11 |
--------------------------------------------------------------------------------
/legacy/app/auth/password-reset.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = PasswordResetDirective;
2 |
3 | PasswordResetDirective.$inject = [];
4 | function PasswordResetDirective() {
5 | return {
6 | restrict: 'E',
7 | scope: true,
8 | controller: PasswordResetController,
9 | template: require('./password-reset.html')
10 | };
11 | }
12 | PasswordResetController.$inject = [
13 | '$scope',
14 | 'PasswordReset',
15 | 'Authentication'
16 | ];
17 | function PasswordResetController(
18 | $scope,
19 | PasswordReset,
20 | Authentication
21 | ) {
22 | $scope.processing = false;
23 | $scope.email = '';
24 |
25 | $scope.submit = submit;
26 | $scope.cancel = cancel;
27 |
28 | activate();
29 |
30 | function activate() {
31 | // If we're already logged in
32 | if (Authentication.getLoginStatus()) {
33 | $scope.$parent.closeModal();
34 | }
35 | }
36 |
37 | $scope.processing = false;
38 |
39 | function resetDone() {
40 | $scope.processing = false;
41 | PasswordReset.openResetConfirm();
42 | }
43 |
44 | function submit() {
45 | $scope.processing = true;
46 |
47 | PasswordReset
48 | .reset($scope.email)
49 | .finally(resetDone);
50 | }
51 |
52 | function cancel() {
53 | $scope.$parent.closeModal();
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/legacy/app/auth/password-reset.html:
--------------------------------------------------------------------------------
1 |
25 |
--------------------------------------------------------------------------------
/legacy/app/auth/password-reset.service.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$http',
3 | 'Util',
4 | 'ModalService',
5 | function (
6 | $http,
7 | Util,
8 | ModalService
9 | ) {
10 |
11 | return {
12 |
13 | reset: function (email) {
14 | var payload = {
15 | email: email
16 | };
17 |
18 | return $http.post(Util.apiUrl('/passwordreset'), payload);
19 | },
20 |
21 | resetConfirm: function (token, password) {
22 | var payload = {
23 | token: token,
24 | password: password
25 | };
26 |
27 | return $http.post(Util.apiUrl('/passwordreset/confirm'), payload);
28 | },
29 |
30 | openReset: function () {
31 | ModalService.openTemplate('', 'nav.forgotyourpassword', false, false, true, false);
32 | },
33 |
34 | openResetConfirm: function (scope) {
35 | ModalService.openTemplate('', 'nav.resetpassword', false, scope, true, false);
36 | }
37 | };
38 |
39 | }];
40 |
--------------------------------------------------------------------------------
/legacy/app/auth/register.controller.js:
--------------------------------------------------------------------------------
1 | module.exports = RegisterController;
2 |
3 | RegisterController.$inject = ['Registration','$location'];
4 | function RegisterController(Registration, $location) {
5 | Registration.openRegister();
6 | $location.url('/');
7 | }
8 |
--------------------------------------------------------------------------------
/legacy/app/auth/registration.service.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$rootScope',
3 | '$http',
4 | '$q',
5 | 'Util',
6 | '$location',
7 | 'ModalService',
8 | function (
9 | $rootScope,
10 | $http,
11 | $q,
12 | Util,
13 | $location,
14 | ModalService
15 | ) {
16 |
17 | return {
18 |
19 | register: function (realname, email, password) {
20 | var payload = {
21 | realname: realname,
22 | email: email,
23 | password: password
24 | },
25 |
26 | deferred = $q.defer(),
27 |
28 | handleRequestError = function (response) {
29 | deferred.reject(response);
30 | $rootScope.$broadcast('event:registration:register:failed');
31 | },
32 |
33 | handleRequestSuccess = function (response) {
34 | $rootScope.$broadcast('event:registration:register:succeeded');
35 | deferred.resolve(response);
36 | };
37 |
38 | $http.post(Util.apiUrl('/register'), payload).then(handleRequestSuccess, handleRequestError);
39 |
40 | return deferred.promise;
41 | },
42 |
43 | openRegister: function () {
44 | ModalService.openTemplate('', 'nav.register', false, false, true, false);
45 | }
46 | };
47 |
48 | }];
49 |
--------------------------------------------------------------------------------
/legacy/app/auth/services/terms-of-service-endpoint.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$resource',
3 | 'Util',
4 | function (
5 | $resource,
6 | Util
7 | ) {
8 |
9 | var TermsOfServiceEndpoint = $resource(Util.apiUrl('/tos/'), {
10 |
11 | }, {
12 | get: {
13 | method: 'GET'
14 | }
15 | });
16 |
17 | return TermsOfServiceEndpoint;
18 | }];
19 |
--------------------------------------------------------------------------------
/legacy/app/auth/tos.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = TermsOfServiceDirective;
2 |
3 | TermsOfServiceDirective.$inject = [];
4 | function TermsOfServiceDirective() {
5 | return {
6 | restrict: 'E',
7 | scope: {},
8 | controller: TosController,
9 | template: require('./tos.html')
10 | };
11 | }
12 |
13 | TosController.$inject = [
14 | '$scope',
15 | 'Authentication',
16 | 'TermsOfService',
17 | 'TermsOfServiceEndpoint',
18 | 'Session',
19 | 'CONST'
20 | ];
21 | function TosController(
22 | $scope,
23 | Authentication,
24 | TermsOfService,
25 | TermsOfServiceEndpoint,
26 | Session,
27 | CONST
28 | ) {
29 | $scope.terms = {
30 | accept: false
31 | };
32 |
33 | $scope.tosSubmit = function () {
34 | if (!$scope.terms.accept) {
35 | return;
36 | }
37 |
38 | TermsOfServiceEndpoint.save({tos_version_date: CONST.TOS_RELEASE_DATE})
39 | .$promise.then(function (tosSessionData) {
40 | // Don't really need this if, but it's just a backup so that you can't access the site if tos is not set properly
41 | if (tosSessionData.agreement_date) {
42 | $scope.$parent.confirm();
43 | }
44 | });
45 | };
46 | }
47 |
--------------------------------------------------------------------------------
/legacy/app/auth/tos.html:
--------------------------------------------------------------------------------
1 |
18 |
--------------------------------------------------------------------------------
/legacy/app/bootstrap.js:
--------------------------------------------------------------------------------
1 | require('./app.js');
2 | import singleSpaAngularJS from 'single-spa-angularjs';
3 |
4 | //exporting lifecycle-functions for angular-app
5 | const ngLifecycles = singleSpaAngularJS({
6 | angular: angular,
7 | mainAngularModule: 'app',
8 | uiRouter: true,
9 | preserveGlobal: false,
10 | strictDi: true,
11 | template: require('./index.html')
12 | });
13 |
14 | export const bootstrap = ngLifecycles.bootstrap;
15 |
16 | export const mount = ngLifecycles.mount;
17 | export const unmount = ngLifecycles.unmount;
18 |
19 |
--------------------------------------------------------------------------------
/legacy/app/common/common-routes.js:
--------------------------------------------------------------------------------
1 | module.exports = ['$stateProvider', '$urlMatcherFactoryProvider', function ($stateProvider, $urlMatcherFactoryProvider) {
2 |
3 | $urlMatcherFactoryProvider.strictMode(false);
4 |
5 | $stateProvider
6 | .state({
7 | name: 'verifier',
8 | url: '/verifier',
9 | controller: require('./verifier/verifier.controller.js'),
10 | template: require('./verifier/verifier.html')
11 | });
12 | }];
13 |
--------------------------------------------------------------------------------
/legacy/app/common/configs/cache-config.js:
--------------------------------------------------------------------------------
1 | module.exports = ['CacheFactoryProvider', function (CacheFactoryProvider) {
2 | angular.extend(CacheFactoryProvider.defaults, {
3 | maxAge: 15 * 60 * 1000, // 15 mins
4 | cacheFlushInterval: 60 * 60 * 1000, // This cache will clear itself every hour
5 | storageMode: 'localStorage',
6 | storagePrefix: 'ush-caches.',
7 | deleteOnExpire: 'aggressive'
8 | });
9 | }];
10 |
--------------------------------------------------------------------------------
/legacy/app/common/configs/loading.interceptor-config.js:
--------------------------------------------------------------------------------
1 | module.exports = ['$httpProvider', function ($httpProvider) {
2 | $httpProvider.interceptors.push('loading');
3 | }];
4 |
--------------------------------------------------------------------------------
/legacy/app/common/configs/locale-config.js:
--------------------------------------------------------------------------------
1 | module.exports = ['$translateProvider', function ($translateProvider) {
2 | $translateProvider.useSanitizeValueStrategy('escaped');
3 |
4 | $translateProvider.translations('en', require('../locales/en.json'));
5 |
6 | $translateProvider.useStaticFilesLoader({
7 | prefix: 'locales/',
8 | suffix: '.json'
9 | });
10 |
11 | $translateProvider.preferredLanguage('en');
12 | $translateProvider.fallbackLanguage('en');
13 | }];
14 |
--------------------------------------------------------------------------------
/legacy/app/common/configs/ui-bootstrap-template-decorators.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$templateCache',
3 | function (
4 | $templateCache
5 | ) {
6 | $templateCache.put('uib/template/pagination/pagination.html', require('./uib-pagination.html'));
7 | }];
8 |
--------------------------------------------------------------------------------
/legacy/app/common/controllers/navigation.js:
--------------------------------------------------------------------------------
1 | module.exports = NavigationController;
2 |
3 | NavigationController.$inject = ['Authentication', 'ConfigEndpoint', 'BootstrapConfig', '$rootScope', 'Features'];
4 | function NavigationController(Authentication, ConfigEndpoint, BootstrapConfig, $rootScope, Features) {
5 | var vm = this;
6 |
7 | vm.site = BootstrapConfig;
8 | vm.reloadSiteConfig = reloadSiteConfig;
9 | //vm.canCreatePost = canCreatePost;
10 | //vm.canRegister = canRegister;
11 | //vm.logoutClick = logoutClick;
12 |
13 | activate();
14 |
15 | $rootScope.$on('event:update:header', reloadSiteConfig);
16 |
17 | function activate() {
18 |
19 | Features.loadFeatures().then(function () {
20 | vm.activityIsAvailable = Features.isViewEnabled('activity');
21 | vm.planIsAvailable = Features.isViewEnabled('plan');
22 | });
23 |
24 | reloadSiteConfig();
25 | }
26 |
27 | function reloadSiteConfig() {
28 | ConfigEndpoint.get({ id: 'site' }).$promise.then(function (site) {
29 | vm.site = site;
30 | });
31 | }
32 |
33 | // Move to add post button (or associated service)
34 | // function canCreatePost() {
35 | // return $rootScope.loggedin || !vm.site.private;
36 | // };
37 | }
38 |
--------------------------------------------------------------------------------
/legacy/app/common/directives/custom-on-change.js:
--------------------------------------------------------------------------------
1 | angular.module('ushahidi.common.custom-on-change', [])
2 |
3 | .directive('customOnChange', function () {
4 | return {
5 | restricet: 'A',
6 | link: function ($scope, $element, $attrs) {
7 | var onChangeFunc = $scope.$eval($attrs.customOnChange);
8 | $element.bind('change', onChangeFunc);
9 | }
10 | };
11 | });
12 |
--------------------------------------------------------------------------------
/legacy/app/common/directives/embed-only.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = EmbedOnlyDirective;
2 |
3 | EmbedOnlyDirective.$inject = [];
4 | function EmbedOnlyDirective() {
5 | return {
6 | restrict: 'A',
7 | controller: EmbedOnlyController
8 | };
9 | }
10 |
11 | EmbedOnlyController.$inject = ['$scope', '$element', '$attrs', '$rootScope', '_', '$window'];
12 | function EmbedOnlyController($scope, $element, $attrs, $rootScope, _, $window) {
13 | var globalEmbed = ($window.self !== $window.top) ? true : false;
14 |
15 | if (globalEmbed && ($attrs.embedOnly === 'false')) {
16 | $element.addClass('hidden');
17 | } else if (!globalEmbed && ($attrs.embedOnly === 'true')) {
18 | $element.addClass('hidden');
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/legacy/app/common/directives/file-upload.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/legacy/app/common/directives/focus.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Focus directive.
3 | * Use this to set focus on input fields that may otherwise not have focus when they become available.
4 | */
5 |
6 | module.exports = Focus;
7 |
8 | Focus.$inject = [
9 | '$timeout'
10 | ];
11 |
12 | function Focus($timeout) {
13 | return {
14 | restrict: 'A',
15 | link: function (scope, element, attrs) {
16 | scope.$watch(attrs.focus, function (value) {
17 | if (value) {
18 | $timeout(function () {
19 | element[0].focus();
20 | });
21 | }
22 | });
23 | }
24 | };
25 | }
26 |
--------------------------------------------------------------------------------
/legacy/app/common/directives/language-switch.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = LanguageSwitchDirective;
2 |
3 | LanguageSwitchDirective.$inject = [];
4 |
5 | function LanguageSwitchDirective() {
6 | return {
7 | restrict: 'E',
8 | scope: {
9 | site: '=?'
10 | },
11 | controller: LanguageSwitchController,
12 | template: require('./language-switch.html')
13 | };
14 | }
15 | LanguageSwitchController.$inject = ['$scope', 'Languages', 'TranslationService', '$location'];
16 | function LanguageSwitchController($scope, Languages, TranslationService, $location) {
17 | $scope.changeLanguage = changeLanguage;
18 | $scope.$on('event:authentication:login:succeeded', TranslationService.setStartLanguage);
19 | $scope.$on('event:authentication:logout:succeeded', TranslationService.setStartLanguage);
20 | activate();
21 |
22 | function activate() {
23 | $scope.languages = Languages.getLanguages();
24 | }
25 |
26 | function changeLanguage(code) {
27 | if ($location.path() !== '/settings/general') {
28 | TranslationService.setLanguage(code);
29 | TranslationService.translate(code);
30 | }
31 | }
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/legacy/app/common/directives/language-switch.html:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/legacy/app/common/directives/layout-class.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = LayoutClassDirective;
2 |
3 | LayoutClassDirective.$inject = [];
4 | function LayoutClassDirective() {
5 | return {
6 | restrict: 'E',
7 | scope: {
8 | layout: '@'
9 | },
10 | controller: LayoutClassController
11 | };
12 | }
13 |
14 | LayoutClassController.$inject = ['$scope', '$rootScope', '$window'];
15 | function LayoutClassController($scope, $rootScope, $window) {
16 | var isEmbed = ($window.self !== $window.top) ? true : false;
17 | if (!isEmbed) {
18 | $rootScope.setLayout('layout-' + $scope.layout);
19 | } else {
20 | // If we are in embed mode
21 | // we must append the layout to the embed layout
22 | $rootScope.setLayout('layout-embed layout-' + $scope.layout);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/legacy/app/common/directives/list-toolbar.html:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/legacy/app/common/directives/loading-dots-button.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = LoadingDotsButtonDirective;
2 |
3 | LoadingDotsButtonDirective.$inject = [];
4 |
5 | function LoadingDotsButtonDirective() {
6 | return {
7 | restrict: 'E',
8 | scope: {
9 | buttonClass: '@',
10 | label: '=',
11 | disabled: '='
12 | },
13 | controller: LoadingDotsButtonController,
14 | template: require('./loading-dots-button.html')
15 | };
16 | }
17 | LoadingDotsButtonController.$inject = ['$scope'];
18 |
19 | function LoadingDotsButtonController($scope) {
20 | }
21 |
--------------------------------------------------------------------------------
/legacy/app/common/directives/loading-dots-button.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/legacy/app/common/directives/mainsheet-container.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 | {{ title | translate }}
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/legacy/app/common/directives/modal-body.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = ModalBody;
2 |
3 | ModalBody.$inject = ['$window'];
4 | function ModalBody($window) {
5 | return {
6 | restrict: 'AC',
7 | link: ModalBodyLink
8 | };
9 |
10 | function ModalBodyLink($scope, $element) {
11 | activate();
12 |
13 | function activate() {
14 | $element.css('max-height', modalBodyHeight());
15 | }
16 |
17 | angular.element($window).bind('resize', handleResize);
18 | // Unbind on destroy
19 | $scope.$on('$destroy', function (event) {
20 | angular.element($window).unbind('resize', handleResize);
21 | });
22 |
23 | function modalBodyHeight() {
24 | return $window.innerHeight * 0.66 + 'px';
25 | }
26 |
27 | function handleResize() {
28 | activate();
29 |
30 | // Manual $digest required as resize event
31 | // is outside of angular
32 | $scope.$digest();
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/legacy/app/common/directives/modal-container.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
14 |
15 | {{ title | translate }}
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/legacy/app/common/directives/modal.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
14 |
15 | {{ title }}
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/legacy/app/common/directives/translations-switch.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = TranslationSwitchDirective;
2 |
3 | TranslationSwitchDirective.$inject = [];
4 |
5 | function TranslationSwitchDirective() {
6 | return {
7 | restrict: 'E',
8 | scope: {
9 | languages:'=',
10 | languagesToSelect:'=',
11 | removeLanguage:'&'
12 | },
13 | controller: TranslationSwitchController,
14 | template: require('./translations-switch.html')
15 | };
16 | }
17 | TranslationSwitchController.$inject = ['$scope', 'ModalService'];
18 |
19 | function TranslationSwitchController($scope, ModalService) {
20 | activate();
21 |
22 | function activate() {
23 | }
24 |
25 | $scope.switchToLanguage = function(language) {
26 | $scope.languages.active = language;
27 | };
28 |
29 | $scope.openLanguages = function() {
30 | ModalService.openTemplate('', 'form.select_language', false, $scope, true, true);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/legacy/app/common/directives/translations-switch.html:
--------------------------------------------------------------------------------
1 |
2 |
6 |
12 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/legacy/app/common/donation/donation-button.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = DonationButtonDirective;
2 |
3 | DonationButtonDirective.$inject = [];
4 | function DonationButtonDirective() {
5 | return {
6 | restrict: 'E',
7 | replace: true,
8 | scope: {
9 | button: '=?'
10 | },
11 | controller: DonationButtonController,
12 | template: require('./donation-button.html')
13 | };
14 | }
15 |
16 | DonationButtonController.$inject = ['$scope', '$window', 'DonationService'];
17 | function DonationButtonController($scope, $window, DonationService) {
18 | $scope.loading = false;
19 | $scope.openDonationModal = DonationService.openDonationModal;
20 | $scope.isButton = isButton;
21 |
22 | function isButton() {
23 | return $scope.button;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/legacy/app/common/donation/donation-button.html:
--------------------------------------------------------------------------------
1 |
17 |
--------------------------------------------------------------------------------
/legacy/app/common/donation/donation-modal.directive.js:
--------------------------------------------------------------------------------
1 | const { config } = require('raven-js');
2 |
3 | module.exports = DonationModalDirective;
4 |
5 | DonationModalDirective.$inject = [];
6 | function DonationModalDirective() {
7 | return {
8 | restrict: 'E',
9 | scope: {},
10 | replace: true,
11 | controller: DonationModalController,
12 | template: require('./donation-modal.html')
13 | };
14 | }
15 |
16 | DonationModalController.$inject = ['$scope', '$rootScope'];
17 | function DonationModalController($scope, $rootScope) {
18 | $scope.donation = $rootScope.donation;
19 | $scope.donationClientEnabled = $rootScope.donationClientEnabled;
20 | }
21 |
--------------------------------------------------------------------------------
/legacy/app/common/donation/donation-module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('ushahidi.donation', [])
3 |
4 | .directive('donation', require('./donation.directive.js'))
5 |
6 | .directive('donationButton', require('./donation-button.directive.js'))
7 |
8 | .directive('donationModal', require('./donation-modal.directive.js'))
9 |
10 | .directive('donationToolbar', require('./donation-toolbar.directive.js'))
11 |
12 | .service('DonationService', require('./donation.service.js'));
13 |
--------------------------------------------------------------------------------
/legacy/app/common/donation/donation-toolbar.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = DonationToolbarDirective;
2 |
3 | DonationToolbarDirective.$inject = [];
4 | function DonationToolbarDirective() {
5 | return {
6 | restrict: 'E',
7 | scope: {},
8 | replace: true,
9 | controller: DonationToolbarController,
10 | template: require('./donation-toolbar.html')
11 | };
12 | }
13 |
14 | DonationToolbarController.$inject = ['$scope', '$rootScope', 'DonationService'];
15 | function DonationToolbarController($scope, $rootScope, DonationService) {
16 | $scope.formattedAmount = 0.0;
17 | $scope.openDonationModal = DonationService.openDonationModal;
18 |
19 | $rootScope.$on('setDonatedAmount', function (event, value) {
20 | $scope.formattedAmount = value;
21 | $scope.$apply();
22 | });
23 | }
24 |
--------------------------------------------------------------------------------
/legacy/app/common/donation/donation-toolbar.html:
--------------------------------------------------------------------------------
1 |
16 |
--------------------------------------------------------------------------------
/legacy/app/common/donation/donation.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/legacy/app/common/factories/loading.interceptor-factory.js:
--------------------------------------------------------------------------------
1 | module.exports = LoadingInterceptor;
2 |
3 | LoadingInterceptor.$inject = ['LoadingProgress', '$q', '$injector'];
4 |
5 | function LoadingInterceptor(LoadingProgress, $q, $injector) {
6 | /* an interceptor that triggers loading-state in the beginning of
7 | * a http-request and remove it when all requests are done */
8 |
9 | return {
10 | request: function (config) {
11 | if (LoadingProgress.getLoadingState() !== true) {
12 | LoadingProgress.setLoadingState(true);
13 | }
14 | // we want this to trigger isSaving everytime except when a lock-updates
15 | if (config.method === 'PUT' && config.url.indexOf('lock') === -1) {
16 | LoadingProgress.setSavingState(true);
17 | }
18 | return config;
19 | },
20 | response: function (response) {
21 | var httpService = $injector.get('$http');
22 | if (httpService.pendingRequests.length === 0) {
23 | LoadingProgress.setLoadingState(false);
24 | LoadingProgress.setSavingState(false);
25 | }
26 | return response || $q.when(response);
27 | }
28 | };
29 | }
30 |
--------------------------------------------------------------------------------
/legacy/app/common/global/event-handlers.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$rootScope',
3 | function (
4 | $rootScope
5 | ) {
6 | // Setup PL layout and switching function
7 | $rootScope.globalLayout = 'layout-a';
8 | $rootScope.setLayout = function (layout) {
9 | $rootScope.globalLayout = layout;
10 | };
11 | // Setup PL modal visible and switching function
12 | $rootScope.modalVisible = false;
13 |
14 | $rootScope.toggleModalVisible = function (state) {
15 | $rootScope.modalVisible = (typeof state !== 'undefined') ? state : !$rootScope.modalVisible;
16 | };
17 | }];
18 |
--------------------------------------------------------------------------------
/legacy/app/common/global/language-settings.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | // '$scope',
3 | '$rootScope',
4 | '$translate',
5 | 'TranslationService',
6 | function (
7 | // $scope,
8 | $rootScope,
9 | $translate,
10 | TranslationService
11 | ) {
12 |
13 | $rootScope.rtlEnabled = false;
14 |
15 | $rootScope.switchRtl = function () {
16 | $rootScope.rtlEnabled = !$rootScope.rtlEnabled;
17 | };
18 | TranslationService.getLanguage().then(function (language) {
19 | translate(language);
20 | });
21 |
22 | function translate(language) {
23 | TranslationService.translate(language);
24 | }
25 | }];
26 |
--------------------------------------------------------------------------------
/legacy/app/common/notifications/api-errors.html:
--------------------------------------------------------------------------------
1 |
2 | {{error}}
3 |
4 |
--------------------------------------------------------------------------------
/legacy/app/common/notifications/limit.html:
--------------------------------------------------------------------------------
1 | {{ message }}
2 |
8 |
--------------------------------------------------------------------------------
/legacy/app/common/notifications/slider.html:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
Loading...
9 |
10 |
15 |
18 |
19 |
20 |
23 |
24 |
25 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/legacy/app/common/raven/raven.service.js:
--------------------------------------------------------------------------------
1 | class RavenService {
2 | constructor($rootScope, Session, Raven) {
3 | 'ngInject';
4 | this.$rootScope = $rootScope;
5 | this.Session = Session;
6 | this.Raven = Raven;
7 | }
8 |
9 | init() {
10 | this.$rootScope.$on('event:authentication:login:succeeded', this.handleLogin.bind(this));
11 | this.$rootScope.$on('event:authentication:logout:succeeded', this.handleLogout.bind(this));
12 |
13 | if (this.Session.getSessionDataEntry('userId')) {
14 | this.handleLogin();
15 | }
16 | }
17 |
18 | handleLogin() {
19 | if (this.Session.getSessionDataEntry('userId')) {
20 | this.Raven.setUserContext({
21 | id: this.Session.getSessionDataEntry('userId')
22 | });
23 | } else {
24 | this.Raven.setUserContext({});
25 | }
26 | }
27 |
28 | handleLogout() {
29 | this.Raven.setUserContext({});
30 | }
31 |
32 | }
33 |
34 | export default RavenService;
35 |
--------------------------------------------------------------------------------
/legacy/app/common/services/endpoints/MediaEndpoint.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$resource',
3 | '$rootScope',
4 | 'Util',
5 | function (
6 | $resource,
7 | $rootScope,
8 | Util
9 | ) {
10 |
11 | var MediaEndpoint = $resource(Util.apiUrl('/media/:id'), {
12 | id: '@id'
13 | }, {
14 | query: {
15 | method: 'GET',
16 | isArray: true,
17 | transformResponse: function (data /*, header*/) {
18 | return Util.transformResponse(data).results;
19 | }
20 | },
21 | update: {
22 | method: 'PUT'
23 | }
24 | });
25 |
26 |
27 | return MediaEndpoint;
28 |
29 | }];
30 |
--------------------------------------------------------------------------------
/legacy/app/common/services/endpoints/form-stats-endpoint.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$resource',
3 | 'Util',
4 | function (
5 | $resource,
6 | Util
7 | ) {
8 |
9 | var FormStatsEndpoint = $resource(Util.apiUrl('/forms/:formId/stats/:extra'), {
10 | formId: '@formId'
11 | }, {
12 | query: {
13 | method: 'GET',
14 | isArray: false,
15 | paramSerializer: '$httpParamSerializerJQLike',
16 | transformResponse: function (data /*, header*/) {
17 | return angular.fromJson(data);
18 | }
19 | },
20 | get: {
21 | method: 'GET'
22 | }
23 | });
24 |
25 | return FormStatsEndpoint;
26 | }];
27 |
--------------------------------------------------------------------------------
/legacy/app/common/services/endpoints/hxl-tag-endpoint.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$resource',
3 | 'Util',
4 | function (
5 | $resource,
6 | Util
7 | ) {
8 |
9 | var HxlTagEndpoint = $resource(Util.apiUrl('/hxl/tags'), {
10 | id: '@id'
11 | }, {
12 | get: {
13 | method: 'GET'
14 | },
15 | update: {
16 | method: 'PUT'
17 | },
18 | deleteEntity: {
19 | method: 'DELETE'
20 | }
21 | });
22 |
23 | return HxlTagEndpoint;
24 |
25 | }];
26 |
--------------------------------------------------------------------------------
/legacy/app/common/services/endpoints/notification.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$resource',
3 | 'Util',
4 | function (
5 | $resource,
6 | Util
7 | ) {
8 |
9 | var NotificationEndpoint = $resource(Util.apiUrl('/notifications/:id'), {
10 | id: '@id'
11 | }, {
12 | query: {
13 | method: 'GET',
14 | isArray: true,
15 | transformResponse: function (data /*, header*/) {
16 | return angular.fromJson(data).results;
17 | }
18 | },
19 | get: {
20 | method: 'GET',
21 | // Short term fix to handle boucing to login when unviewable
22 | // notification is returned
23 | params: {'ignore403': '@ignore403'}
24 | },
25 | update: {
26 | method: 'PUT'
27 | },
28 | delete: {
29 | method: 'DELETE'
30 | }
31 | });
32 |
33 | return NotificationEndpoint;
34 | }];
35 |
--------------------------------------------------------------------------------
/legacy/app/common/services/endpoints/post-lock-endpoint.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$resource',
3 | '$rootScope',
4 | 'Util',
5 | '_',
6 | '$http',
7 | function (
8 | $resource,
9 | $rootScope,
10 | Util,
11 | _,
12 | $http
13 | ) {
14 |
15 | var PostLockEndpoint = $resource(Util.apiUrl('/posts/:post_id/lock/'), {
16 | post_id: '@post_id'
17 | }, {
18 | getLock: {
19 | method: 'PUT'
20 | },
21 | unlockByPost: {
22 | method: 'DELETE'
23 | },
24 | unlock: {
25 | method: 'DELETE'
26 | },
27 | options: {
28 | method: 'OPTIONS'
29 | }
30 | });
31 |
32 | return PostLockEndpoint;
33 |
34 | }];
35 |
--------------------------------------------------------------------------------
/legacy/app/common/services/endpoints/savedsearch.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$resource',
3 | 'Util',
4 | function (
5 | $resource,
6 | Util
7 | ) {
8 |
9 | var SavedSearchEndpoint = $resource(Util.apiUrl('/savedsearches/:id'), {
10 | id: '@id'
11 | }, {
12 | query: {
13 | method: 'GET',
14 | isArray: true,
15 | transformResponse: function (data /*, header*/) {
16 | return angular.fromJson(data).results;
17 | }
18 | },
19 | get: {
20 | method: 'GET'
21 | },
22 | update: {
23 | method: 'PUT'
24 | },
25 | delete: {
26 | method: 'DELETE'
27 | }
28 | });
29 |
30 | return SavedSearchEndpoint;
31 |
32 | }];
33 |
--------------------------------------------------------------------------------
/legacy/app/common/services/endpoints/sdk/CategoriesSdk.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | 'Util',
3 | 'Session',
4 | 'UshahidiSdk',
5 | function (
6 | Util,
7 | Session,
8 | UshahidiSdk
9 | ) {
10 |
11 | let _ushahidi = null;
12 |
13 | const ushahidi = function () {
14 | if (_ushahidi) { return _ushahidi; }
15 | return new UshahidiSdk.Categories(
16 | Util.url(''),
17 | Session.getSessionDataEntry('accessToken'),
18 | Session.getSessionDataEntry('accessTokenExpires')
19 | );
20 | }
21 |
22 | const getCategories = function(id) {
23 | return ushahidi()
24 | .getCategories(id);
25 | }
26 |
27 | const saveCategory = function(category) {
28 | return ushahidi()
29 | .saveCategory(category);
30 | }
31 |
32 | const deleteCategory = function(id) {
33 | return ushahidi()
34 | .deleteCategory(id);
35 | }
36 |
37 | return { getCategories, saveCategory, deleteCategory };
38 | }];
39 |
--------------------------------------------------------------------------------
/legacy/app/common/services/endpoints/sdk/UtilsSdk.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | 'Util',
3 | 'UshahidiSdk',
4 | function (
5 | Util,
6 | UshahidiSdk
7 | ) {
8 |
9 | const url = Util.url('');
10 | const getLanguages = function() {
11 | return UshahidiSdk.getLanguages(url);
12 | }
13 |
14 | return {getLanguages};
15 | }];
16 |
--------------------------------------------------------------------------------
/legacy/app/common/services/features.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | 'ConfigEndpoint',
3 | 'Util',
4 | '$q',
5 | function (
6 | ConfigEndpoint,
7 | Util,
8 | $q
9 | ) {
10 |
11 | var Features = {
12 | features: undefined,
13 | loadFeatures: function () {
14 | var deferred = $q.defer();
15 | if (Features.features) {
16 | deferred.resolve(Features.features);
17 | } else {
18 | ConfigEndpoint.getFresh({id: 'features'}).$promise.then(function (features) {
19 | Features.features = features;
20 | deferred.resolve(Features.features);
21 | });
22 | }
23 | return deferred.promise;
24 | },
25 | isFeatureEnabled: function (feature) {
26 | return Features.features[feature].enabled;
27 | },
28 | isViewEnabled: function (view) {
29 | return Features.features.views[view];
30 | },
31 | getLimit: function (feature) {
32 | return Features.features.limits[feature];
33 | }
34 | };
35 |
36 | return Util.bindAllFunctionsToSelf(Features);
37 | }];
38 |
--------------------------------------------------------------------------------
/legacy/app/common/services/import-complete.html:
--------------------------------------------------------------------------------
1 |
2 | Your CSV import is complete. {{processed}} records imported, {{errors}} records failed.
3 |
4 |
5 | The data from your CSV spreadsheet, {{filename}}, was successfully imported into your {{form_name}} survey.
6 |
7 | See imported posts
8 | Import another CSV file
9 |
12 |
--------------------------------------------------------------------------------
/legacy/app/common/services/import.notify.service.js:
--------------------------------------------------------------------------------
1 | module.exports = ImportNotify;
2 |
3 | var scope;
4 |
5 | ImportNotify.$inject = ['_', '$q', '$rootScope', '$translate', 'SliderService'];
6 | function ImportNotify(_, $q, $rootScope, $translate, SliderService) {
7 | return {
8 | importComplete: importComplete
9 | };
10 |
11 | function importComplete(values) {
12 | var scope = getScope();
13 |
14 | scope = _.extend(scope, values);
15 |
16 | showSlider();
17 |
18 | function showSlider() {
19 | SliderService.openTemplate(require('./import-complete.html'), 'thumb-up', 'confirmation', scope, false, false);
20 | }
21 | }
22 |
23 | function getScope() {
24 | if (scope) {
25 | scope.$destroy();
26 | }
27 | scope = $rootScope.$new();
28 | return scope;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/legacy/app/common/services/languages.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$http',
3 | function (
4 | $http
5 | ) {
6 |
7 | // Get translated languages if they have been downloaded from https://www.transifex.com/api/2/languages
8 | const languages = require('../locales/languages.json')
9 | return {
10 | getLanguages: function () {
11 | if (languages.languages && languages.languages.length > 0) {
12 | return languages.languages;
13 | } else {
14 | return [
15 | {
16 | 'rtl': false,
17 | 'pluralequation': 'language.pluralequation',
18 | 'code': 'en',
19 | 'name': 'English',
20 | 'nplurals': 2
21 | }
22 | ];
23 | }
24 | }
25 | }
26 | }];
27 |
--------------------------------------------------------------------------------
/legacy/app/common/user-profile/account-settings.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$rootScope',
3 | 'UserEndpoint',
4 | 'ModalService',
5 | function (
6 | $rootScope,
7 | UserEndpoint,
8 | ModalService
9 | ) {
10 | return {
11 | restrict: 'E',
12 | replace: true,
13 | scope: {},
14 | template: require('./account_settings.html'),
15 | link: function (scope) {
16 | scope.user = UserEndpoint.getFresh({id: 'me'});
17 |
18 | scope.general = true;
19 | scope.notifications = false;
20 |
21 | scope.showGeneral = function () {
22 | scope.general = true;
23 | scope.notifications = false;
24 | };
25 |
26 | scope.showNotifications = function () {
27 | scope.general = false;
28 | scope.notifications = true;
29 | };
30 |
31 | scope.$on('event:close', function () {
32 | ModalService.close();
33 | });
34 | }
35 | };
36 | }];
37 |
--------------------------------------------------------------------------------
/legacy/app/common/user-profile/account_settings.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{user.realname || user.email}} user_profile.title
4 |
5 |
6 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/legacy/app/common/user-profile/admin-user-setup.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$rootScope',
3 | 'ModalService',
4 | function (
5 | $rootScope,
6 | ModalService
7 | ) {
8 | return {
9 | restrict: 'E',
10 | replace: true,
11 | scope: {},
12 | template: require('./admin-user-setup.html'),
13 | link: function (scope) {
14 | scope.$on('event:close', function () {
15 | ModalService.close();
16 | });
17 | }
18 | };
19 | }];
20 |
--------------------------------------------------------------------------------
/legacy/app/common/user-profile/admin-user-setup.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/legacy/app/common/user-profile/user-profile-module.js:
--------------------------------------------------------------------------------
1 | angular.module('ushahidi.user-profile', [])
2 | .directive('accountSettings', require('./account-settings.directive.js'))
3 | .directive('adminUserSetup', require('./admin-user-setup.directive'))
4 | .directive('userProfile', require('./user-profile.directive.js'))
5 | .directive('notifications', require('./notifications.directive.js'))
6 | ;
7 |
--------------------------------------------------------------------------------
/legacy/app/common/verifier/verifier.service.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | 'Verifier',
3 | 'Notify',
4 | '$rootScope',
5 | 'Util',
6 | function (
7 | Verifier,
8 | Notify,
9 | $rootScope,
10 | Util
11 | ) {
12 | return {
13 | debugModeCheck: function () {
14 | Verifier.checkDebugMode(Util.apiUrl('/verifier/db'))
15 | .then(function (result) {
16 | if (result) {
17 | Notify.notifyPermanent(`You have debug-mode switched on. If you are an admin of this deployment,
18 | we recommend you disable this check and NOT leaving it enabled in the API.
19 | You may disable the check by running the "composer installdebug:disable" command in the API folder.`);
20 | }
21 | });
22 | }
23 | };
24 | }
25 | ];
26 |
27 |
--------------------------------------------------------------------------------
/legacy/app/data/add-post-text-button.html:
--------------------------------------------------------------------------------
1 |
10 |
11 |
20 |
--------------------------------------------------------------------------------
/legacy/app/data/collection-toggle/collection-toggle-button.html:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/legacy/app/data/collection-toggle/collection-toggle-button.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$rootScope',
3 | '_',
4 | 'CollectionsService',
5 | function (
6 | $rootScope,
7 | _,
8 | CollectionsService
9 | ) {
10 | return {
11 | restrict: 'E',
12 | replace: true,
13 | scope: {
14 | posts: '=',
15 | selectedPosts: '=',
16 | onDone: '&'
17 | },
18 | link: function ($scope, $element, $attrs, ngModel) {
19 | $scope.toggleCollection = function () {
20 | // Reduce set of post of objects to only those currently selected
21 | var selectedPostObjects = _.filter($scope.posts, function (post) {
22 | return _.contains($scope.selectedPosts, post.id);
23 | });
24 |
25 | CollectionsService.showAddToCollection(selectedPostObjects);
26 | // Trigger done handler (clear selected posts)
27 | $scope.onDone();
28 | };
29 | },
30 | template: require('./collection-toggle-button.html')
31 | };
32 | }];
33 |
--------------------------------------------------------------------------------
/legacy/app/data/common/post-edit-create/post-datetime-value.html:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/legacy/app/data/common/post-edit-create/video.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/legacy/app/data/common/post-edit-detail-create/post-entity.service.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | 'CONST',
3 | function (
4 | CONST
5 | ) {
6 | return function (data) {
7 | return angular.extend({}, {
8 | // id: 0,
9 | title: '',
10 | description: '',
11 | locale: CONST.DEFAULT_LOCALE,
12 | post_content: [],
13 | completed_stages: [],
14 | published_to: [],
15 | post_date: new Date(),
16 | enabled_languages: {}
17 | }, data);
18 | };
19 | }];
20 |
--------------------------------------------------------------------------------
/legacy/app/data/common/post-edit-detail-create/survey-language-selector.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = SurveyLanguageSelector;
2 |
3 | SurveyLanguageSelector.$inject = [
4 | ];
5 |
6 | function SurveyLanguageSelector() {
7 | return {
8 | restrict: 'E',
9 | scope: {
10 | languages:'=',
11 | title: '='
12 | },
13 | controller: SurveyLanguageSelectorController,
14 | template: require('./survey-language-selector.html')
15 | };
16 | }
17 |
18 | SurveyLanguageSelectorController.$inject = ['$scope'];
19 |
20 | function SurveyLanguageSelectorController($scope) {
21 |
22 | $scope.changeLanguage = changeLanguage;
23 |
24 |
25 | function changeLanguage(language) {
26 | $scope.languages.active = language;
27 | $scope.languages.default = language;
28 | }
29 | };
30 |
--------------------------------------------------------------------------------
/legacy/app/data/common/post-edit-detail/post-messages-reply.html:
--------------------------------------------------------------------------------
1 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/legacy/app/data/post-create/main.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/legacy/app/data/post-create/post-create.controller.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$scope',
3 | '$translate',
4 | '$location',
5 | '$controller',
6 | '$transition$',
7 | 'PostEntity',
8 | 'PostEndpoint',
9 | function (
10 | $scope,
11 | $translate,
12 | $location,
13 | $controller,
14 | $transition$,
15 | postEntity,
16 | PostEndpoint
17 | ) {
18 | $translate('post.create_post').then(function (title) {
19 | $scope.title = title;
20 | $scope.$emit('setPageTitle', title);
21 | });
22 |
23 | $scope.post = postEntity();
24 |
25 | PostEndpoint.options().$promise.then(function (options) {
26 | $scope.post.allowed_privileges = options.allowed_privileges;
27 | });
28 | $scope.formId = $transition$.params().id;
29 | }];
30 |
--------------------------------------------------------------------------------
/legacy/app/data/post-detail/add-form.html:
--------------------------------------------------------------------------------
1 |
32 |
--------------------------------------------------------------------------------
/legacy/app/data/post-detail/map.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
{{ feature.geometry.coordinates[1] }}, {{ feature.geometry.coordinates[0] }}
6 |
7 |
--------------------------------------------------------------------------------
/legacy/app/data/post-detail/post-category-value.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = PostCategoryValue;
2 |
3 | PostCategoryValue.$inject = [];
4 |
5 | function PostCategoryValue() {
6 | return {
7 | restrict: 'E',
8 | controller: PostCategoryValueController,
9 | scope: {
10 | categories: '=',
11 | activeLanguage:'='
12 | },
13 | template: require('./post-category-value.html')
14 | };
15 | }
16 | PostCategoryValueController.$inject = ['$scope', '_'];
17 |
18 | function PostCategoryValueController($scope, _) {
19 | // Make a list of parent category ids referenced by categories in the list
20 | let parent_ids = _.uniq(_.without(_.pluck($scope.categories, 'parent_id'), null));
21 | $scope.display = $scope.categories.filter(f => {
22 | // Hide categories that have been marked as inaccessible by the API
23 | if (_.isUndefined(f._ush_hidden)) {
24 | // Hide categories that have been referenced as their parent categories by some
25 | // other category in the list
26 | if (!parent_ids.includes(f.id)) {
27 | return f;
28 | }
29 | }
30 | });
31 | function activate() {}
32 | activate();
33 | }
34 |
--------------------------------------------------------------------------------
/legacy/app/data/post-detail/post-category-value.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | {{category.translations[activeLanguage].tag || category.tag}},
7 |
8 |
9 |
--------------------------------------------------------------------------------
/legacy/app/data/post-detail/post-lock.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
The post is locked because Seth Hall is working on it right now. Try editing a different post.
10 |
The post is locked because Seth Hall is working on it right now. Click the unlock button to break lock.
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/legacy/app/data/post-detail/post-media-value.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = ['MediaEndpoint', '_', function (MediaEndpoint, _) {
2 | return {
3 | restrict: 'E',
4 | replace: true,
5 | scope: {
6 | mediaId: '=',
7 | label: '@',
8 | mediaHasCaption: '='
9 | },
10 | template: require('./post-media-value.html'),
11 | link: MediaValueLink
12 | };
13 |
14 | function MediaValueLink($scope) {
15 | function loadMedia() {
16 | $scope.mediaLoaded = true;
17 | if ($scope.mediaId) {
18 | $scope.mediaLoaded = false;
19 | MediaEndpoint.get({id: $scope.mediaId}).$promise.then(function (media) {
20 | $scope.media = media;
21 | $scope.mediaLoaded = true;
22 | });
23 | }
24 | }
25 | loadMedia();
26 |
27 | $scope.$watch('mediaId', function (newMediaId, oldMediaId) {
28 | if (newMediaId !== oldMediaId) {
29 | loadMedia();
30 | }
31 | });
32 | }
33 |
34 | }];
35 |
--------------------------------------------------------------------------------
/legacy/app/data/post-detail/post-media-value.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
13 |
![]()
14 |
{{ media.caption }}
15 |
16 |
--------------------------------------------------------------------------------
/legacy/app/data/post-detail/post-video-value.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = PostVideoValue;
2 |
3 | PostVideoValue.$inject = [];
4 |
5 | function PostVideoValue() {
6 | return {
7 | restrict: 'E',
8 | scope: {
9 | videoUrl: '=',
10 | label: '@'
11 | },
12 | template: require('./post-video-value.html'),
13 | controller: PostVideoValueController
14 | };
15 | }
16 |
17 | PostVideoValueController.$inject = [
18 | '$scope',
19 | '$sce'
20 | ];
21 |
22 | function PostVideoValueController(
23 | $scope,
24 | $sce
25 | ) {
26 | activate();
27 |
28 | function activate() {
29 | if ($scope.videoUrl && $scope.videoUrl.length > 0) {
30 | $scope.videoUrl = $sce.trustAsResourceUrl($scope.videoUrl);
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/legacy/app/data/post-detail/post-video-value.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | {{videoUrl}}
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/legacy/app/data/post-view.service.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '_',
3 | 'Util',
4 | '$translate',
5 | '$rootScope',
6 | 'SliderService',
7 | function (
8 | _,
9 | Util,
10 | $translate,
11 | $rootScope,
12 | SliderService
13 | ) {
14 | var scope;
15 |
16 | var PostViewService = {
17 | showNoPostsSlider: function () {
18 | var scope = getScope();
19 | // TODO review translation sanitization
20 | $translate(['post.there_are_no_posts', 'post.in_this_deployment']).then(function (noPostText) {
21 | scope.noPostText = noPostText;
22 | SliderService.openTemplate(
23 | '{{noPostText["post.there_are_no_posts"]}}{{noPostText["post.in_this_deployment"]}}
' +
24 | '' +
25 | '',
26 | 'file', false, scope, false, false, true);
27 | });
28 |
29 | }
30 | };
31 |
32 | function getScope() {
33 | if (scope) {
34 | scope.$destroy();
35 | }
36 | scope = $rootScope.$new();
37 | return scope;
38 | }
39 |
40 | return Util.bindAllFunctionsToSelf(PostViewService);
41 | }];
42 |
--------------------------------------------------------------------------------
/legacy/app/data/services/message.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$resource',
3 | 'Util',
4 | function (
5 | $resource,
6 | Util
7 | ) {
8 |
9 | var MessageEndpoint = $resource(Util.apiUrl('/messages/:id'), {
10 | id: '@id'
11 | }, {
12 | query: {
13 | method: 'GET',
14 | isArray: true,
15 | transformResponse: function (data /*, header*/) {
16 | return angular.fromJson(data);
17 | }
18 | },
19 | get: {
20 | method: 'GET'
21 | },
22 | allInThread: {
23 | method: 'GET',
24 | params: {
25 | contact: '@contact',
26 | offset: '@offset',
27 | limit: '@limit',
28 | order: 'asc',
29 | orderby: 'created'
30 | },
31 | isArray: false,
32 | transformResponse: function (data /*, header*/) {
33 | return angular.fromJson(data);
34 | }
35 | },
36 | save: {
37 | method: 'POST'
38 | }
39 | });
40 |
41 | return MessageEndpoint;
42 | }];
43 |
--------------------------------------------------------------------------------
/legacy/app/index.html:
--------------------------------------------------------------------------------
1 |
18 |
--------------------------------------------------------------------------------
/legacy/app/map/directives/overflow-toggle.js:
--------------------------------------------------------------------------------
1 | module.exports = OverflowToggleDirective;
2 |
3 | OverflowToggleDirective.$inject = ['$parse'];
4 | function OverflowToggleDirective($parse) {
5 | return {
6 | restrict: 'A',
7 | link: OverflowToggleController
8 | };
9 |
10 | function OverflowToggleController($scope, $element, $attrs) {
11 | var toggle = $element[0].querySelector('.form-field-toggle');
12 | var hasOverflow = angular.bind({}, $parse($attrs.hasOverflow), $scope);
13 |
14 | $scope.$watch(hasOverflow, function (hasOverflow) {
15 | $element.toggleClass('has-overflow', hasOverflow);
16 | });
17 |
18 | angular.element(toggle).on('click', function ($event) {
19 | $event.preventDefault();
20 | hasOverflow() ? $element.toggleClass('show-overflow') : '';
21 | });
22 | }
23 | }
24 |
25 |
--------------------------------------------------------------------------------
/legacy/app/map/mode-context/filter-by-survey-dropdown.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = FilterBySurveryDropdownDirective;
2 |
3 | FilterBySurveryDropdownDirective.$inject = [];
4 | function FilterBySurveryDropdownDirective() {
5 | return {
6 | restrict: 'A',
7 | replace: true,
8 | controller: FilterBySurveryDropdownController
9 | };
10 | }
11 |
12 | FilterBySurveryDropdownController.$inject = ['$scope', '$rootScope'];
13 | function FilterBySurveryDropdownController($scope, $rootScope) {
14 |
15 | $scope.filtersMenuOpen = false;
16 |
17 | activate();
18 |
19 | function activate() {
20 | $rootScope.$on('filters:open:dropdown', function () {
21 | externalOpenDropDown();
22 | });
23 | }
24 |
25 | function externalOpenDropDown() {
26 | $scope.filtersMenuOpen = true;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/legacy/app/map/mode-context/mode-context.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = ModeContext;
2 |
3 | ModeContext.$inject = [];
4 |
5 | function ModeContext() {
6 | return {
7 | restrict: 'E',
8 | scope: {
9 | filters: '='
10 | },
11 | controller: ModeContextController,
12 | template: require('./mode-context.html')
13 | };
14 | }
15 |
16 | ModeContextController.$inject = [
17 | '$scope'
18 | ];
19 | function ModeContextController(
20 | $scope
21 | ) {
22 |
23 | activate();
24 |
25 | function activate() {
26 |
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/legacy/app/map/mode-context/mode-context.html:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
20 |
21 |
--------------------------------------------------------------------------------
/legacy/app/map/post-card/collection-toggle/collection-toggle-link.html:
--------------------------------------------------------------------------------
1 |
2 |
5 | Add to collection
6 |
7 |
--------------------------------------------------------------------------------
/legacy/app/map/post-card/collection-toggle/collection-toggle-link.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$rootScope',
3 | 'CollectionsService',
4 | function (
5 | $rootScope,
6 | CollectionsService
7 | ) {
8 | return {
9 | restrict: 'E',
10 | replace: true,
11 | scope: {
12 | post: '='
13 | },
14 | link: function ($scope, $element, $attrs, ngModel) {
15 | $scope.toggleCollection = function () {
16 | // Collection toggle expects an array of posts
17 | CollectionsService.showAddToCollection([$scope.post]);
18 | };
19 | },
20 | template: require('./collection-toggle-link.html')
21 | };
22 | }];
23 |
--------------------------------------------------------------------------------
/legacy/app/map/post-card/post-preview-media.html:
--------------------------------------------------------------------------------
1 |
2 |
![{{ media.caption }}]()
3 |
![]()
4 |
5 |
6 |
--------------------------------------------------------------------------------
/legacy/app/map/post-toolbar/add-post/add-post-button.html:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
--------------------------------------------------------------------------------
/legacy/app/map/post-toolbar/add-post/add-post-survey-list.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = AddPostSurveyListDirective;
2 |
3 | AddPostSurveyListDirective.$inject = [];
4 |
5 | function AddPostSurveyListDirective() {
6 | return {
7 | restrict: 'E',
8 | scope: true,
9 | controller: AddPostSurveyListController,
10 | template: require('./add-post-survey-list.html')
11 | };
12 | }
13 |
14 | AddPostSurveyListController.$inject = [
15 | '$scope',
16 | '$location',
17 | 'TranslationService'
18 | ];
19 |
20 | function AddPostSurveyListController(
21 | $scope,
22 | $location,
23 | TranslationService
24 | ) {
25 |
26 | $scope.handleClick = handleClick;
27 | TranslationService.getLanguage().then(language=>{
28 | $scope.userLanguage = language;
29 | });
30 |
31 | function handleClick(form) {
32 | $scope.closeMainsheet();
33 | $location.path('posts/create/' + form.id);
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/legacy/app/map/post-toolbar/add-post/add-post-survey-list.html:
--------------------------------------------------------------------------------
1 |
2 | -
3 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/legacy/app/map/post-toolbar/filters/filter-date.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = DateSelectDirective;
2 |
3 | DateSelectDirective.$inject = [];
4 | function DateSelectDirective() {
5 | return {
6 | restrict: 'E',
7 | scope: {
8 | dateBeforeModel: '=',
9 | dateAfterModel: '='
10 | },
11 | controller: DateSelectController,
12 | template: require('./filter-date.html')
13 | };
14 | }
15 |
16 | DateSelectController.$inject = ['$scope', '$rootScope', 'Flatpickr'];
17 | function DateSelectController($scope, $rootScope, Flatpickr) {
18 | let pickers = Flatpickr('.flatpickr', {});
19 |
20 | function pauseTrap() {
21 | $rootScope.$broadcast('event:pauseTrap', true);
22 | }
23 |
24 | function unPauseTrap() {
25 | $rootScope.$broadcast('event:pauseTrap', false);
26 | }
27 |
28 | // There are multiple pickers because of start/end-date in filters
29 | pickers.forEach((picker) => {
30 | if (picker.config) {
31 | if (picker.config.onOpen) {
32 | picker.config.onOpen.push(pauseTrap);
33 | }
34 | if (picker.config.onClose) {
35 | picker.config.onClose.push(unPauseTrap);
36 | }
37 | }
38 | });
39 | }
40 |
--------------------------------------------------------------------------------
/legacy/app/map/post-toolbar/filters/filter-form.html:
--------------------------------------------------------------------------------
1 |
22 |
--------------------------------------------------------------------------------
/legacy/app/map/post-toolbar/filters/filter-has-location.directive.js:
--------------------------------------------------------------------------------
1 |
2 | module.exports = FilterHasLocationDirective;
3 |
4 | FilterHasLocationDirective.$inject = [];
5 |
6 | function FilterHasLocationDirective() {
7 | return {
8 | restrict: 'E',
9 | replace: true,
10 | scope: {
11 | hasLocation: '='
12 | },
13 | require: 'ngModel',
14 | link: FilterHasLocationLink,
15 | template: require('./filter-has-location.html')
16 | };
17 | }
18 |
19 | function FilterHasLocationLink($scope, $element, $attrs, ngModel) {
20 | activate();
21 | function activate() {
22 | $scope.$watch('hasLocation', saveToView, true);
23 | }
24 |
25 | function saveToView(hasLocation) {
26 | ngModel.$setViewValue(angular.copy(hasLocation));
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/legacy/app/map/post-toolbar/filters/filter-has-location.html:
--------------------------------------------------------------------------------
1 |
34 |
--------------------------------------------------------------------------------
/legacy/app/map/post-toolbar/filters/filter-location.html:
--------------------------------------------------------------------------------
1 |
24 |
25 |
--------------------------------------------------------------------------------
/legacy/app/map/post-toolbar/filters/filter-post-order-asc-desc.html:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/legacy/app/map/post-toolbar/filters/filter-post-sorting-options.html:
--------------------------------------------------------------------------------
1 |
13 |
--------------------------------------------------------------------------------
/legacy/app/map/post-toolbar/filters/filter-saved-search.html:
--------------------------------------------------------------------------------
1 |
16 |
27 |
--------------------------------------------------------------------------------
/legacy/app/map/post-toolbar/filters/filter-status.html:
--------------------------------------------------------------------------------
1 |
25 |
--------------------------------------------------------------------------------
/legacy/app/map/post-toolbar/filters/filter-unlocked-on-top.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = FilterUnlockedOnTopDirective;
2 |
3 | FilterUnlockedOnTopDirective.$inject = [
4 | '_'
5 | ];
6 | function FilterUnlockedOnTopDirective(_) {
7 | return {
8 | restrict: 'E',
9 | require: 'ngModel',
10 | template: require('./filter-unlocked-on-top.html'),
11 | scope: {},
12 | link: FilterUnlockedOnTopDirectiveLink
13 | };
14 | function FilterUnlockedOnTopDirectiveLink($scope, $element, $attrs, ngModel) {
15 | $scope.unlockedOnTop = {
16 | value: 'true',
17 | labelTranslateKey: 'global_filter.sort.unlockedOnTop.filter_type_tag'
18 | };
19 |
20 | function activate() {
21 | ngModel.$render = renderModelValue;
22 | $scope.$watch('unlockedOnTop', saveToView, true);
23 | }
24 |
25 | function renderModelValue() {
26 | $scope.unlockedOnTop = {
27 | value: ngModel.$viewValue,
28 | labelTranslateKey: 'global_filter.sort.unlockedOnTop.filter_type_tag'
29 | };
30 | }
31 | activate();
32 | function saveToView(unlockedOnTop) {
33 | ngModel.$setViewValue(angular.copy(unlockedOnTop ? unlockedOnTop.value.toString() : ''));
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/legacy/app/map/post-toolbar/filters/filter-unlocked-on-top.html:
--------------------------------------------------------------------------------
1 |
2 |
9 |
--------------------------------------------------------------------------------
/legacy/app/map/post-toolbar/share/post-export.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/legacy/app/map/post-toolbar/share/post-share.html:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/legacy/app/map/post-toolbar/share/share-menu-modal.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = ShareMenuDirective;
2 |
3 | ShareMenuDirective.$inject = [];
4 | function ShareMenuDirective() {
5 | return {
6 | restrict: 'E',
7 | scope: {
8 | surveyId: '=',
9 | postId: '=',
10 | filters: '='
11 | },
12 | replace: true,
13 | controller: ShareMenuController,
14 | template: require('./share-menu-modal.html')
15 | };
16 | }
17 |
18 | ShareMenuController.$inject = [
19 | '$scope',
20 | '$window'
21 | ];
22 | function ShareMenuController(
23 | $scope,
24 | $window
25 | ) {
26 | }
27 |
--------------------------------------------------------------------------------
/legacy/app/map/post-toolbar/share/share-menu-modal.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/legacy/app/map/post-toolbar/sort-and-filter-counter.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = SortAndFilterCounterDirective;
2 |
3 | SortAndFilterCounterDirective.$inject = ['PostFilters'];
4 | function SortAndFilterCounterDirective(PostFilters) {
5 | return {
6 | restrict: 'E',
7 | scope: {},
8 | link: SortAndFilterCounterDirectiveLink,
9 | template: require('./sort-and-filter-counter.html')
10 | };
11 |
12 | function SortAndFilterCounterDirectiveLink($scope, $element, $attrs, ngModel) {
13 | $scope.$watch(function () {
14 | return PostFilters.countFilters();
15 | }, handleFiltersUpdate, true);
16 |
17 | function handleFiltersUpdate() {
18 | $scope.filtersCount = PostFilters.countFilters();
19 | }
20 | }
21 |
22 | }
23 |
24 |
--------------------------------------------------------------------------------
/legacy/app/map/post-toolbar/sort-and-filter-counter.html:
--------------------------------------------------------------------------------
1 |
2 | {{filtersCount}}
3 | app.sort_filter
4 |
5 |
8 |
--------------------------------------------------------------------------------
/legacy/app/map/post-view-map.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/legacy/app/map/post-view-noui.controller.js:
--------------------------------------------------------------------------------
1 | module.exports = PostViewNouiController;
2 |
3 | PostViewNouiController.$inject = ['$scope', '$rootScope', '$translate', '$transition$', 'PostFilters'];
4 | function PostViewNouiController($scope, $rootScope, $translate, $transition$, PostFilters) {
5 | $rootScope.setLayout('layout-embed');
6 | $scope.filters = PostFilters.getFilters();
7 | $scope.$emit('event:allposts:show');
8 | }
9 |
--------------------------------------------------------------------------------
/legacy/app/map/post-view-noui.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/legacy/app/map/services/view-helper.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$translate',
3 | function (
4 | $translate
5 | ) {
6 | var allViews = [
7 | {
8 | name: 'map',
9 | display_name: $translate.instant('views.map')
10 | },
11 | {
12 | name: 'data',
13 | display_name: $translate.instant('views.data')
14 | }
15 | ];
16 |
17 | function views() {
18 | return allViews;
19 | }
20 |
21 | return {
22 | views: views
23 | };
24 | }];
25 |
--------------------------------------------------------------------------------
/legacy/app/mode-bar/mode-bar.module.js:
--------------------------------------------------------------------------------
1 | angular.module('ushahidi.modebar', [])
2 |
3 | .directive('modeBar', require('./mode-bar.directive.js'))
4 | .directive('ushLogo', require('./ush-logo.directive.js'))
5 |
6 | .run([
7 | '$templateCache',
8 | function ($templateCache) {
9 | $templateCache.put(
10 | 'mode-bar/ushahidi-logo.html',
11 | require('./ushahidi-logo.html')
12 | );
13 | }
14 | ]);
15 |
--------------------------------------------------------------------------------
/legacy/app/mode-bar/support-links.html:
--------------------------------------------------------------------------------
1 |
2 | app.support
3 |
4 |
5 |
6 |
7 | - app.documentation.title
8 | - app.documentation.description
9 | - app.report_a_bug.title
10 | - app.report_a_bug.description
11 | - app.features.title
12 | - app.features.description
13 | - app.intercom.intercom
14 | - app.intercom.description
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/legacy/app/mode-bar/ush-logo.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = UshLogoDirective;
2 |
3 | UshLogoDirective.$inject = [];
4 | function UshLogoDirective() {
5 | return {
6 | restrict: 'E',
7 | controller: UshLogoController,
8 | replace: true,
9 | template: require('./ush-logo.html')
10 | };
11 | }
12 |
13 | UshLogoController.$inject = [];
14 | function UshLogoController() {
15 | }
16 |
--------------------------------------------------------------------------------
/legacy/app/mode-bar/ush-logo.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Powered by Ushahidi
4 |
5 |
--------------------------------------------------------------------------------
/legacy/app/settings/categories/category-translation-editor.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = CategoryTranslationEditor;
2 |
3 | CategoryTranslationEditor.$inject = [];
4 | function CategoryTranslationEditor() {
5 | return {
6 | restrict: 'E',
7 | scope: {
8 | activeLanguage: '=',
9 | category:'=',
10 | defaultLanguage:'='
11 | },
12 | controller: CategoryTranslationEditorController,
13 | template: require('./category-translation-editor.html')
14 | };
15 | }
16 |
17 | CategoryTranslationEditorController.$inject = [];
18 | function CategoryTranslationEditorController() {
19 | }
20 |
--------------------------------------------------------------------------------
/legacy/app/settings/data-import/data-after-import.controller.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$scope',
3 | '$rootScope',
4 | '$location',
5 | '$translate',
6 | '$q',
7 | '_',
8 | function (
9 | $scope,
10 | $rootScope,
11 | $location,
12 | $translate,
13 | $q,
14 | _
15 | ) {
16 |
17 | // Redirect to home if not authorized
18 | if ($rootScope.hasManageSettingsPermission() === false) {
19 | return $location.path('/');
20 | }
21 |
22 | // Change layout class
23 | $rootScope.setLayout('layout-c');
24 | // Change mode
25 | $scope.$emit('event:mode:change', 'settings');
26 | }];
27 |
--------------------------------------------------------------------------------
/legacy/app/settings/data-import/data-after-import.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$rootScope',
3 | '$translate',
4 | '$location',
5 | function (
6 | $rootScope,
7 | $translate,
8 | $location
9 | ) {
10 | return {
11 | restrict: 'A',
12 | link: function ($scope, $element, $attrs) {
13 | $scope.importComplete = false;
14 |
15 | $rootScope.$on('event:import:complete', function (event, args) {
16 | $scope.collectionId = args.collectionId;
17 | $scope.filename = args.filename;
18 | $scope.importComplete = true;
19 | });
20 | }
21 | };
22 | }];
23 |
--------------------------------------------------------------------------------
/legacy/app/settings/data-import/data-import.controller.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$scope',
3 | '$rootScope',
4 | '$location',
5 | '$translate',
6 | 'FormEndpoint',
7 | '_',
8 | function (
9 | $scope,
10 | $rootScope,
11 | $location,
12 | $translate,
13 | FormEndpoint,
14 | _
15 | ) {
16 | // Redirect to home if not authorized
17 | if ($rootScope.hasManageSettingsPermission() === false) {
18 | return $location.path('/');
19 | }
20 |
21 | // Change layout class
22 | $rootScope.setLayout('layout-c');
23 | // Change mode
24 | $scope.$emit('event:mode:change', 'settings');
25 |
26 | $scope.fileContainer = {
27 | file: null
28 | };
29 |
30 | FormEndpoint.queryFresh().$promise.then(function (response) {
31 | $scope.forms = response;
32 | });
33 | }
34 | ];
35 |
--------------------------------------------------------------------------------
/legacy/app/settings/datasources/gmail-auth.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = GmailAuthDirective;
2 |
3 | GmailAuthDirective.$inject = [];
4 | function GmailAuthDirective() {
5 | return {
6 | restrict: 'E',
7 | scope: true,
8 | controller: GmailAuthController,
9 | template: require('./gmail-auth.html')
10 | };
11 | }
12 | GmailAuthController.$inject = [
13 | '$scope'
14 | ];
15 | function GmailAuthController(
16 | $scope
17 | ) {
18 | $scope.processing = false;
19 | $scope.code = '';
20 |
21 | $scope.submit = submit;
22 | $scope.cancel = cancel;
23 |
24 | $scope.processing = false;
25 |
26 | function submit() {
27 | $scope.processing = true;
28 | $scope.$parent.authorizeGmailProvider($scope.code, $scope.date)
29 | .finally(function () {
30 | $scope.processing = false;
31 | $scope.$parent.closeModal();
32 | })
33 | }
34 |
35 | function cancel() {
36 | $scope.$parent.closeModal();
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/legacy/app/settings/directives/color-picker.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Ushahidi Angular Color Picker directive
3 | * Drop in directive for color picking
4 | */
5 |
6 | module.exports = [
7 | function () {
8 | var controller = [
9 | '$scope',
10 | '$translate',
11 | function (
12 | $scope,
13 | $translate
14 | ) {
15 | // Set default color
16 | $scope.color = '#eee';
17 | // Update local color when inbound color is changed
18 | $scope.$watch('colorContainer.color', function () {
19 | if ($scope.colorContainer.color) {
20 | $scope.color = $scope.colorContainer.color.replace('#', '');
21 | }
22 | });
23 |
24 | $scope.setColor = function (color) {
25 | $scope.colorContainer.color = color.indexOf('#') > -1 ? color : '#' + color;
26 | };
27 | }
28 | ];
29 | return {
30 | restrict: 'E',
31 | replace: true,
32 | template: require('./color-picker.html'),
33 | scope: {
34 | colorContainer: '='
35 | },
36 | controller: controller
37 | };
38 | }
39 | ];
40 |
--------------------------------------------------------------------------------
/legacy/app/settings/directives/filter-system/filter-role.html:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/legacy/app/settings/directives/filter-system/filter-role.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Ushahidi Angular Filter System role directive
3 | * Drop in directive responsible for role selection
4 | * for filtering
5 | */
6 |
7 | module.exports = [
8 | function (
9 | ) {
10 | var controller = [
11 | '$scope',
12 | '$rootScope',
13 | '$translate',
14 | 'RoleEndpoint',
15 | function (
16 | $scope,
17 | $rootScope,
18 | $translate,
19 | RoleEndpoint
20 | ) {
21 | RoleEndpoint.query().$promise.then(function (roles) {
22 | $scope.roles = roles;
23 | });
24 | }];
25 | return {
26 | restrict: 'E',
27 | replace: true,
28 | template: require('./filter-role.html'),
29 | scope: {
30 | model: '='
31 | },
32 | controller: controller
33 | };
34 | }];
35 |
--------------------------------------------------------------------------------
/legacy/app/settings/directives/loading-dots.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = LoadingDotsDirective;
2 |
3 | LoadingDotsDirective.$inject = [];
4 |
5 | function LoadingDotsDirective() {
6 | return {
7 | restrict: 'E',
8 | scope: {
9 | buttonClass: '@',
10 | label: '=',
11 | disabled: '='
12 | },
13 | controller: LoadingDotsController,
14 | template: require('./loading-dots.html')
15 | };
16 | }
17 | LoadingDotsController.$inject = ['$scope'];
18 |
19 | function LoadingDotsController($scope) {
20 | }
21 |
--------------------------------------------------------------------------------
/legacy/app/settings/directives/loading-dots.html:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/legacy/app/settings/donation/donation.controller.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$scope',
3 | '$rootScope',
4 | '$location',
5 | '$translate',
6 | '_',
7 | function ($scope, $rootScope, $location, $translate, _) {
8 | // Redirect to home if not authorized
9 | if ($rootScope.hasManageSettingsPermission() === false) {
10 | return $location.path('/');
11 | }
12 |
13 | // Change layout class
14 | $rootScope.setLayout('layout-c');
15 | // Change mode
16 | $scope.$emit('event:mode:change', 'settings');
17 | }
18 | ];
19 |
--------------------------------------------------------------------------------
/legacy/app/settings/roles/roles.controller.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$scope',
3 | '$translate',
4 | '$rootScope',
5 | '$location',
6 | function (
7 | $scope,
8 | $translate,
9 | $rootScope,
10 | $location
11 | ) {
12 |
13 | // Redirect to home if not authorized
14 | if ($rootScope.hasManageSettingsPermission() === false) {
15 | return $location.path('/');
16 | }
17 |
18 | $translate('tool.manage_roles').then(function (title) {
19 | $scope.title = title;
20 | $scope.$emit('setPageTitle', title);
21 | });
22 | // Change mode
23 | $scope.$emit('event:mode:change', 'settings');
24 |
25 | }];
26 |
--------------------------------------------------------------------------------
/legacy/app/settings/roles/roles.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$translate',
3 | '$rootScope',
4 | '$location',
5 | 'RoleEndpoint',
6 | '_',
7 | 'Features',
8 | function (
9 | $translate,
10 | $rootScope,
11 | $location,
12 | RoleEndpoint,
13 | _,
14 | Features
15 | ) {
16 | return {
17 | restrict: 'A',
18 | link: function ($scope, $element, $attrs) {
19 | $rootScope.setLayout('layout-a');
20 | $scope.refreshView = function () {
21 | RoleEndpoint.queryFresh().$promise.then(function (roles) {
22 | $scope.roles = roles;
23 | });
24 | };
25 |
26 | $scope.refreshView();
27 | Features.loadFeatures().then(function () {
28 | $scope.rolesEnabled = Features.isFeatureEnabled('roles');
29 | });
30 | }
31 | };
32 | }];
33 |
--------------------------------------------------------------------------------
/legacy/app/settings/services/accessibility.service.js:
--------------------------------------------------------------------------------
1 | module.exports = AccessibilityService;
2 | function AccessibilityService() {
3 | return {
4 | setFocus
5 | };
6 | function setFocus(id) {
7 | return document.getElementById(id).focus();
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/legacy/app/settings/services/endpoints/apikey.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$resource',
3 | '$rootScope',
4 | 'Util',
5 | function (
6 | $resource,
7 | $rootScope,
8 | Util
9 | ) {
10 |
11 | var ApiKeyEndpoint = $resource(Util.apiUrl('/apikeys/:id'), {
12 | id: '@id'
13 | }, {
14 | query: {
15 | method: 'GET',
16 | isArray: true,
17 | transformResponse: function (data /*, header*/) {
18 | return Util.transformResponse(data).results;
19 | }
20 | },
21 | get: {
22 | method: 'GET'
23 | },
24 | update: {
25 | method: 'PUT'
26 | }
27 | });
28 |
29 | return ApiKeyEndpoint;
30 |
31 | }];
32 |
--------------------------------------------------------------------------------
/legacy/app/settings/services/endpoints/country-code-endpoint.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$resource',
3 | 'Util',
4 | 'CacheFactory',
5 | function (
6 | $resource,
7 | Util,
8 | CacheFactory
9 | ) {
10 | var cache;
11 | if (!(cache = CacheFactory.get('countryCodes'))) {
12 | cache = CacheFactory.createCache('countryCodes');
13 | }
14 | cache.removeExpired();
15 |
16 | var CountryCodeEndpoint = $resource(Util.apiUrl('/country-codes/'), {
17 | }, {
18 | query: {
19 | method: 'GET',
20 | isArray: true,
21 | cache: cache,
22 | transformResponse: function (data) {
23 | return Util.transformResponse(data).results;
24 | }
25 | }
26 | });
27 |
28 | return CountryCodeEndpoint;
29 | }];
30 |
--------------------------------------------------------------------------------
/legacy/app/settings/services/endpoints/form-contact.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$resource',
3 | 'Util',
4 | 'CacheFactory',
5 | function (
6 | $resource,
7 | Util,
8 | CacheFactory
9 | ) {
10 | var cache;
11 |
12 | if (!(cache = CacheFactory.get('formContactCache'))) {
13 | cache = CacheFactory.createCache('formContactCache');
14 | }
15 | cache.removeExpired();
16 |
17 | var FormContactEndpoint = $resource(Util.apiUrl('/forms/:formId/contacts/'), {
18 | formId: '@formId'
19 | }, {
20 | query: {
21 | method: 'GET',
22 | isArray: true,
23 | cache: cache
24 | },
25 | get: {
26 | method: 'GET',
27 | cache: cache
28 | },
29 | update: {
30 | method: 'PUT'
31 | }
32 | });
33 | return FormContactEndpoint;
34 | }];
35 |
--------------------------------------------------------------------------------
/legacy/app/settings/services/endpoints/hxl-license-endpoint.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$resource',
3 | 'Util',
4 | function (
5 | $resource,
6 | Util
7 | ) {
8 |
9 | var HxlLicenseEndpoint = $resource(Util.apiUrl('/hxl/licenses'), {
10 | id: '@id'
11 | }, {
12 | get: {
13 | method: 'GET'
14 | },
15 | update: {
16 | method: 'PUT'
17 | },
18 | deleteEntity: {
19 | method: 'DELETE'
20 | }
21 | });
22 |
23 | return HxlLicenseEndpoint;
24 |
25 | }];
26 |
--------------------------------------------------------------------------------
/legacy/app/settings/services/endpoints/hxl-metadata-endpoint.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$resource',
3 | 'Util',
4 | function (
5 | $resource,
6 | Util
7 | ) {
8 |
9 | var HxlMetadataEndpoint = $resource(Util.apiUrl('/hxl/metadata'), {
10 | id: '@id'
11 | }, {
12 | get: {
13 | method: 'GET'
14 | },
15 | update: {
16 | method: 'PUT'
17 | },
18 | deleteEntity: {
19 | method: 'DELETE'
20 | }
21 | });
22 |
23 | return HxlMetadataEndpoint;
24 |
25 | }];
26 |
--------------------------------------------------------------------------------
/legacy/app/settings/services/endpoints/hxl-organisations-endpoint.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$resource',
3 | 'Util',
4 | function (
5 | $resource,
6 | Util
7 | ) {
8 |
9 | var HxlOrganisationsEndpoint = $resource(Util.apiUrl('/hxl/organisations'), {
10 | id: '@id'
11 | }, {
12 | get: {
13 | method: 'GET'
14 | },
15 | update: {
16 | method: 'PUT'
17 | },
18 | deleteEntity: {
19 | method: 'DELETE'
20 | }
21 | });
22 |
23 | return HxlOrganisationsEndpoint;
24 |
25 | }];
26 |
--------------------------------------------------------------------------------
/legacy/app/settings/services/endpoints/permission.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$resource',
3 | 'Util',
4 | 'CacheFactory',
5 | function (
6 | $resource,
7 | Util,
8 | CacheFactory
9 | ) {
10 | var cache;
11 |
12 | if (!(cache = CacheFactory.get('permissionCache'))) {
13 | cache = CacheFactory.createCache('permissionCache');
14 | }
15 | cache.removeExpired();
16 |
17 | var PermissionEndpoint = $resource(Util.apiUrl('/permissions/:id'), {
18 | id: '@id'
19 | }, {
20 | query: {
21 | method: 'GET',
22 | transpermissionResponse: function (data /*, header*/) {
23 | return Util.transformResponse(data).results;
24 | }
25 | },
26 | get: {
27 | method: 'GET',
28 | cache: cache
29 | }
30 | });
31 |
32 | PermissionEndpoint.getFresh = function (params) {
33 | cache.remove(Util.apiUrl('/permissions/' + params.id));
34 | return PermissionEndpoint.get(params);
35 | };
36 |
37 | PermissionEndpoint.invalidateCache = function () {
38 | return cache.removeAll();
39 | };
40 |
41 | PermissionEndpoint.queryFresh = function () {
42 | cache.removeAll();
43 | return PermissionEndpoint.query();
44 | };
45 |
46 | return PermissionEndpoint;
47 |
48 | }];
49 |
--------------------------------------------------------------------------------
/legacy/app/settings/settings.controller.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$scope',
3 | '$translate',
4 | '$location',
5 | '$rootScope',
6 | function (
7 | $scope,
8 | $translate,
9 | $location,
10 | $rootScope
11 | ) {
12 |
13 | // Redirect to home if not authorized
14 | if ($rootScope.hasManageSettingsPermission() === false) {
15 | return $location.path('/');
16 | }
17 |
18 | $translate('tool.settings').then(function (title) {
19 | $scope.title = title;
20 | $scope.$emit('setPageTitle', title);
21 | });
22 | // Change mode
23 | $scope.$emit('event:mode:change', 'settings');
24 | }];
25 |
--------------------------------------------------------------------------------
/legacy/app/settings/settings.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/legacy/app/settings/site/settings-general.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/legacy/app/settings/site/site.controller.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$scope',
3 | '$rootScope',
4 | '$location',
5 | '$translate',
6 | function (
7 | $scope,
8 | $rootScope,
9 | $location,
10 | $translate
11 | ) {
12 |
13 | // Redirect to home if not authorized
14 | if ($rootScope.hasManageSettingsPermission() === false) {
15 | return $location.path('/');
16 | }
17 |
18 | $rootScope.setLayout('layout-a');
19 | $translate('tool.site_settings').then(function (title) {
20 | $scope.title = title;
21 | $rootScope.$emit('setPageTitle', title);
22 | });
23 | // Change mode
24 | $scope.$emit('event:mode:change', 'settings');
25 |
26 | }];
27 |
--------------------------------------------------------------------------------
/legacy/app/settings/surveys/attribute-create.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 | {{type.label}}
6 |
7 |
8 | - {{type.description}}
9 |
10 |
--------------------------------------------------------------------------------
/legacy/app/settings/surveys/edit.controller.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$scope',
3 | '$rootScope',
4 | '$transition$',
5 | function (
6 | $scope,
7 | $rootScope,
8 | $transition$
9 | ) {
10 | $scope.surveyId = $transition$.params().id;
11 | $scope.actionType = $transition$.params().action;
12 | }];
13 |
--------------------------------------------------------------------------------
/legacy/app/settings/surveys/survey-edit.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/legacy/app/settings/surveys/survey-success.html:
--------------------------------------------------------------------------------
1 |
2 | {{successText}}
3 |
4 |
5 | Add to survey
6 |
9 |
--------------------------------------------------------------------------------
/legacy/app/settings/surveys/survey-translation-editor.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = SurveyTranslationEditor;
2 |
3 | SurveyTranslationEditor.$inject = [];
4 | function SurveyTranslationEditor() {
5 | return {
6 | restrict: 'E',
7 | scope: {
8 | activeLanguage: '=',
9 | survey:'=',
10 | defaultLanguage:'='
11 | },
12 | controller: SurveyTranslationEditorController,
13 | template: require('./survey-translation-editor.html')
14 | };
15 | }
16 |
17 | SurveyTranslationEditorController.$inject = ['$rootScope', '$scope', 'ModalService','_'];
18 | function SurveyTranslationEditorController($rootScope, $scope, ModalService, _) {
19 | $scope.openField = openField;
20 | $scope.form = {};
21 | $rootScope.$on('event:surveys:translationMissing', function () {
22 | $scope.form.translation.$setDirty();
23 | });
24 |
25 | function openField(field, task) {
26 | $scope.activeTask = task;
27 | if (!field.translations[$scope.activeLanguage]) {
28 | field.translations[$scope.activeLanguage] = {}
29 | }
30 | $scope.translateField = field;
31 | ModalService.openTemplate('', 'translations.translate_field', '', $scope, true, true);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/legacy/app/settings/surveys/survey.notify.service.js:
--------------------------------------------------------------------------------
1 | module.exports = SurveyNotify;
2 |
3 | var scope;
4 |
5 | SurveyNotify.$inject = ['_', '$q', '$rootScope', '$translate', 'SliderService'];
6 | function SurveyNotify(_, $q, $rootScope, $translate, SliderService) {
7 | return {
8 | success: success
9 | };
10 |
11 | function success(successText, translateValues, values) {
12 | var scope = getScope();
13 |
14 | function showSlider(successText) {
15 | values.successText = successText;
16 | scope = _.extend(scope, values);
17 |
18 | SliderService.openTemplate(require('./survey-success.html'), 'thumb-up', 'confirmation', scope, false, false);
19 | }
20 |
21 | $translate(successText, translateValues).then(showSlider, showSlider);
22 | }
23 |
24 | function getScope() {
25 | if (scope) {
26 | scope.$destroy();
27 | }
28 | scope = $rootScope.$new();
29 | return scope;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/legacy/app/settings/surveys/task-create.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$rootScope',
3 | 'ModalService',
4 | function (
5 | $rootScope,
6 | ModalService
7 | ) {
8 | return {
9 | restrict: 'E',
10 | template: require('./task-create.html'),
11 | link: function ($scope, $element, $attrs) {
12 |
13 | // Init an empty saved search
14 | $scope.newTask = {
15 | required : false,
16 | fields: [],
17 | type: 'task',
18 | show_when_published: false,
19 | task_is_internal_only: true
20 | };
21 |
22 | $scope.closeModal = function () {
23 | ModalService.close();
24 | };
25 | }
26 | };
27 | }];
28 |
--------------------------------------------------------------------------------
/legacy/app/settings/users/filter-users.directive.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Ushahidi Angular Filter System User directive
3 | * Drop in directive for managing filters for users
4 | */
5 |
6 | module.exports = [
7 | function (
8 | ) {
9 | var controller = [
10 | '$scope',
11 | '$rootScope',
12 | '$translate',
13 | '$timeout',
14 | '_',
15 | function (
16 | $scope,
17 | $rootScope,
18 | $translate,
19 | $timeout,
20 | _
21 | ) {
22 | $scope.filtersMenuOpen = false;
23 | $scope.cancel = function () {
24 | // Reset filters
25 | $scope.usersFiltersForm.$rollbackViewValue();
26 | // and close dropdown
27 | $scope.filtersMenuOpen = false;
28 | };
29 |
30 | $scope.applyFilters = function () {
31 | // ngFormController automatically commits changes to the model ($scope.filters)
32 | // Just close the dropdown
33 | $scope.filtersMenuOpen = false;
34 | };
35 | }];
36 | return {
37 | restrict: 'E',
38 | replace: true,
39 | template: require('./filter-users.html'),
40 | scope: {
41 | filters: '='
42 | },
43 | controller: controller
44 | };
45 | }];
46 |
--------------------------------------------------------------------------------
/legacy/app/settings/webhooks/webhooks.controller.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$scope',
3 | '$translate',
4 | '$rootScope',
5 | '$location',
6 | function (
7 | $scope,
8 | $translate,
9 | $rootScope,
10 | $location
11 | ) {
12 |
13 | // Redirect to home if not authorized
14 | if ($rootScope.hasManageSettingsPermission() === false) {
15 | return $location.path('/');
16 | }
17 |
18 | $translate('tool.manage_webhooks').then(function (title) {
19 | $scope.title = title;
20 | $scope.$emit('setPageTitle', title);
21 | });
22 | // Change mode
23 | $scope.$emit('event:mode:change', 'settings');
24 |
25 | }];
26 |
--------------------------------------------------------------------------------
/legacy/app/settings/webhooks/webhooks.directive.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | '$translate',
3 | '$rootScope',
4 | '$location',
5 | 'WebhookEndpoint',
6 | '_',
7 | 'Features',
8 | function (
9 | $translate,
10 | $rootScope,
11 | $location,
12 | WebhookEndpoint,
13 | _,
14 | Features
15 | ) {
16 | return {
17 | restrict: 'A',
18 | link: function ($scope, $element, $attrs) {
19 | $rootScope.setLayout('layout-a');
20 |
21 | $scope.refreshView = function () {
22 | WebhookEndpoint.queryFresh().$promise.then(function (webhooks) {
23 | $scope.webhooks = webhooks;
24 | });
25 | };
26 |
27 | $scope.refreshView();
28 | Features.loadFeatures().then(function () {
29 | $scope.webhooksEnabled = Features.isFeatureEnabled('webhooks');
30 | });
31 | }
32 | };
33 | }];
34 |
--------------------------------------------------------------------------------
/legacy/app/test-bootstrap.js:
--------------------------------------------------------------------------------
1 | require('./app');
2 | window.ushahidi.bootstrapConfig = require('../mocked_backend/api/v3/config.json').results;
3 | // Just bootstrap the app immediately
4 | angular.bootstrap(document, ['app'], {
5 | strictDi: true
6 | });
7 |
--------------------------------------------------------------------------------
/legacy/mocked_backend/api/v3/config/features.json:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "id": "features",
4 | "url": "http://localhost:8081/api/v2/config/features",
5 | "views": {
6 | "map": true,
7 | "list": true,
8 | "chart": true,
9 | "timeline": true,
10 | "activity": true
11 | },
12 | "data-providers": {
13 | "smssync": true,
14 | "twitter": true,
15 | "frontlinesms": true,
16 | "email": true,
17 | "twilio": true,
18 | "nexmo": true
19 | },
20 | "limits": {
21 | "posts": true,
22 | "forms": true,
23 | "admin_users": true
24 | },
25 | "private": {
26 | "enabled": true
27 | },
28 | "roles": {
29 | "enabled": true
30 | },
31 | "webhooks": {
32 | "enabled": true
33 | },
34 | "data-import": {
35 | "enabled": true
36 | },
37 | "targeted-surveys": {
38 | "enabled": true
39 | },
40 | "csv-speedup": {
41 | "enabled": true
42 | },
43 | "user-settings": {
44 | "enabled": true
45 | },
46 | "anonymise-reporters": {
47 | "enabled": true
48 | },
49 | "hxl": {
50 | "enabled": true
51 | },
52 | "allowed_privileges": [
53 | "read",
54 | "search"
55 | ]
56 | }
57 |
--------------------------------------------------------------------------------
/legacy/mocked_backend/api/v3/config/map.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "map",
3 | "url":"http://localhost:8081/api/v2/config/map",
4 | "clustering": false,
5 | "cluster_radius": 50,
6 | "location_precision":2,
7 | "default_view": {
8 | "lat": -1.3048035,
9 | "lon": 36.8473969,
10 | "zoom": 2,
11 | "baselayer": "MapQuest",
12 | "fit_map_boundaries": true,
13 | "icon": "map-marker",
14 | "color": "blue"
15 | },
16 | "allowed_privileges": [
17 | "read",
18 | "search"
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/legacy/mocked_backend/api/v3/config/site.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "site",
3 | "name": "Ushahidi Mock",
4 | "description": "Ushahidi testing deployment",
5 | "email": "someone@somewhere.somehow",
6 | "timezone": "UTC",
7 | "language": "en-US",
8 | "date_format": "n/j/Y",
9 | "client_url": false,
10 | "first_login": true,
11 | "tier": "free",
12 | "private": false,
13 | "allowed_methods": {
14 | "get": true,
15 | "post": true,
16 | "put": true,
17 | "delete": true
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/legacy/mocked_backend/api/v3/forms/1.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": 1,
3 | "url": "http://192.168.33.110/api/v3/forms/1",
4 | "parent_id": null,
5 | "name": "Test Form",
6 | "description": "Testing form",
7 | "type": "report",
8 | "disabled": false,
9 | "created": "1970-01-01T00:00:00+00:00",
10 | "updated": "2015-11-30T15:09:53+00:00",
11 | "allowed_privileges": [
12 | "read",
13 | "create",
14 | "update",
15 | "delete",
16 | "search"
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/legacy/mocked_backend/api/v3/forms/3.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": 3,
3 | "url": "http://192.168.33.110/api/v3/forms/3",
4 | "parent_id": null,
5 | "name": "new test title",
6 | "description": "new test description",
7 | "type": "report",
8 | "disabled": false,
9 | "created": "1970-01-01T00:00:00+00:00",
10 | "updated": "2015-11-30T15:09:53+00:00",
11 | "allowed_privileges": [
12 | "read",
13 | "create",
14 | "update",
15 | "delete",
16 | "search"
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/legacy/mocked_backend/api/v3/posts/999.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "9999",
3 | "url": "http://localhost:8081/api/v2/posts/9999",
4 | "parent": null,
5 | "user": null,
6 | "title": "Post without a type and form id (could be a message)",
7 | "slug": null,
8 | "content": "Some description",
9 | "author_email": null,
10 | "author_realname": null,
11 | "status": "published",
12 | "created": "1970-01-01T00:00:00+00:00",
13 | "updated": null,
14 | "locale": "en_us",
15 | "values": {
16 | "last_location_point": [
17 | {
18 | "id": "3",
19 | "value": {
20 | "lon": 10.123,
21 | "lat": 26.213
22 | }
23 | }
24 | ]
25 | },
26 | "tags": [
27 |
28 | ],
29 | "allowed_methods": {
30 | "get": true,
31 | "post": true,
32 | "put": true,
33 | "delete": true
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/legacy/mocked_backend/api/v3/stages/4.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": 4,
3 | "url": "http://192.168.33.110/api/v3/form_stages/1",
4 | "form_id": 1,
5 | "label": "4th step",
6 | "priority": 99,
7 | "icon": null,
8 | "required": false,
9 | "allowed_privileges": [
10 | "read",
11 | "create",
12 | "update",
13 | "delete",
14 | "search"
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/legacy/mocked_backend/api/v3/users/me.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": 2,
3 | "url": "http://ushahidi-backend/api/v2/users/2",
4 | "email": "admin@ush.com",
5 | "realname": "Admin Joe",
6 | "logins": 0,
7 | "failed_attempts": 0,
8 | "last_login": null,
9 | "last_attempt": null,
10 | "created": "1970-01-01T00:00:00+00:00",
11 | "updated": "2014-12-13T19:17:57+00:00",
12 | "role": "admin",
13 | "allowed_methods": [
14 | "get",
15 | "post",
16 | "put"
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/legacy/sass/overrides/_dropdown.scss:
--------------------------------------------------------------------------------
1 | .dropdown {
2 | .dropdown-animate {
3 | display: block !important;
4 | opacity: 1 !important;
5 | transition: opacity 0.15s;
6 | }
7 |
8 | .dropdown-animate-flex {
9 | display: flex !important;
10 | opacity: 1 !important;
11 | transition: opacity 0.15s ease-in;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/legacy/sass/overrides/_filters.scss:
--------------------------------------------------------------------------------
1 | .filter-controls {
2 | padding-top: 10px;
3 | padding-bottom: 10px;
4 | text-align: right;
5 |
6 | a.clear-filters {
7 | display: inline-block;
8 | padding: 10px 15px;
9 |
10 | text-transform: none;
11 | font-weight: normal;
12 | letter-spacing: normal;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/legacy/sass/overrides/_intercom.scss:
--------------------------------------------------------------------------------
1 |
2 | .layout-a {
3 | .intercom-launcher-frame, .intercom-lightweight-app-launcher {
4 | right: 13px !important;
5 | @media (max-width: 1150px) {
6 | bottom: 120px !important;
7 | }
8 | }
9 | }
10 | .layout-d {
11 | .intercom-launcher-frame, .intercom-lightweight-app-launcher {
12 | right: 13px !important;
13 | bottom: 80px !important;
14 | @media (max-width: 1023px) {
15 | bottom: 120px !important;
16 | }
17 | }
18 | }
19 |
20 | .intercom-messenger-frame {
21 | right: 100px !important;
22 | }
23 |
--------------------------------------------------------------------------------
/legacy/sass/overrides/_modal.scss:
--------------------------------------------------------------------------------
1 | modal {
2 | div.modal {
3 | display: block;
4 | }
5 |
6 | div.modal-detached {
7 | position: absolute;
8 | bottom: 0; right: 0;
9 | width: 0; height: 0;
10 | visibility: hidden;
11 | pointer-events: none;
12 | }
13 | }
14 |
15 |
16 |
--------------------------------------------------------------------------------
/legacy/sass/vendor.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * Combined vendor stylesheets
3 | */
4 |
5 | // the 'gulp rename' task is a workaround that duplicates the .css file and
6 | // renames it to .scss, allowing us to essentially import vendor .css.
7 | //
8 | // these files are imported via the 'node-modules include path' in gulpfile.js
9 | //
10 | @import "~leaflet/dist/leaflet";
11 | @import "~leaflet.markercluster/dist/MarkerCluster";
12 | @import "~leaflet.markercluster/dist/MarkerCluster.Default";
13 | @import "~leaflet.locatecontrol/src/L.Control.Locate";
14 | @import '~@toast-ui/editor/dist/toastui-editor-viewer.css'; // editor's ui
15 | @import '~@toast-ui/editor/dist/toastui-editor.css'; // editor's content
16 | @import '~flatpickr/dist/flatpickr.min.css';
17 |
18 |
19 | // Custom overrides
20 | @import "overrides/leaflet";
21 | @import "overrides/filters";
22 | @import "overrides/modal";
23 | @import "overrides/intercom";
24 | @import "overrides/tui-markdown";
25 |
--------------------------------------------------------------------------------
/legacy/test/pre_test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #placeholder
--------------------------------------------------------------------------------
/legacy/test/test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -ev
3 |
4 | if [ "${TEST_SUITE}" = "lint" ]; then
5 | npm run eslint
6 | fi
7 |
8 | if [ "${TEST_SUITE}" = "unit" ]; then
9 | NODE_ENV=test gulp test
10 | fi
11 |
--------------------------------------------------------------------------------
/legacy/test/unit/common/directives/embed-only.directive.spec.js:
--------------------------------------------------------------------------------
1 | describe('embed only directive', function () {
2 |
3 | var $rootScope,
4 | $compile,
5 | $scope,
6 | $window,
7 | element;
8 |
9 | beforeEach(function () {
10 | fixture.setBase('mocked_backend/api/v3');
11 |
12 | var testApp = makeTestApp();
13 |
14 | testApp.directive('embedOnly', require('app/common/directives/embed-only.directive'));
15 |
16 | angular.mock.module('testApp');
17 | });
18 |
19 | beforeEach(inject(function (_$rootScope_, _$compile_, _Notify_, _GlobalFilter_, _$window_) {
20 | $rootScope = _$rootScope_;
21 | $compile = _$compile_;
22 | $window = _$window_;
23 | $scope = _$rootScope_.$new();
24 | $rootScope.globalLayout = 'layout-a';
25 | $window.self = 'frame';
26 | $rootScope.setLayout = function () {};
27 | spyOn($rootScope, 'setLayout').and.callThrough();
28 | }));
29 |
30 | it('should set the layout', function () {
31 | element = '';
32 | element = $compile(element)($scope);
33 | $scope.$digest();
34 |
35 | });
36 | });
37 |
--------------------------------------------------------------------------------
/legacy/test/unit/common/directives/file-upload.directive.spec.js:
--------------------------------------------------------------------------------
1 | describe('file upload directive', function () {
2 |
3 | var $rootScope,
4 | $compile,
5 | $scope,
6 | $window,
7 | element;
8 |
9 | beforeEach(function () {
10 | fixture.setBase('mocked_backend/api/v3');
11 |
12 | var testApp = makeTestApp();
13 |
14 | testApp.directive('fileUpload', require('app/common/directives/file-upload.directive'));
15 |
16 | angular.mock.module('testApp');
17 | });
18 |
19 | beforeEach(inject(function (_$rootScope_, _$compile_, _$window_) {
20 | $rootScope = _$rootScope_;
21 | $compile = _$compile_;
22 | $window = _$window_;
23 | $scope = _$rootScope_.$new();
24 | $rootScope.globalLayout = 'layout-a';
25 | $window.self = 'frame';
26 | $rootScope.setLayout = function () {};
27 | spyOn($rootScope, 'setLayout').and.callThrough();
28 | }));
29 |
30 | it('should set the layout', function () {
31 | element = '';
32 | element = $compile(element)($scope);
33 | $scope.$digest();
34 |
35 | });
36 | });
37 |
--------------------------------------------------------------------------------
/legacy/test/unit/common/global/event-handlers-spec.js:
--------------------------------------------------------------------------------
1 | describe('global event handlers', function () {
2 |
3 | var mockedSessionData,
4 | mockedAuthenticationData
5 | ;
6 |
7 | beforeEach(function () {
8 |
9 | var testApp = makeTestApp(),
10 | mockedSessionService =
11 | {
12 | getSessionData: function () {
13 | return mockedSessionData;
14 | },
15 | getSessionDataEntry: function (key) {
16 | return mockedSessionData[key];
17 | },
18 | setSessionDataEntry: function (key, value) {
19 | mockedSessionData[key] = value;
20 | }
21 | },
22 | mockedAuthenticationService =
23 | {
24 | getLoginStatus: function () {
25 | return mockedAuthenticationData.loginStatus;
26 | },
27 | logout : function () {
28 | // Just a stub
29 | }
30 | };
31 |
32 | testApp.service('Session', function () {
33 | return mockedSessionService;
34 | })
35 | .service('Authentication', function () {
36 | return mockedAuthenticationService;
37 | })
38 | .run(require('app/common/global/event-handlers.js'));
39 |
40 |
41 | });
42 | });
43 |
--------------------------------------------------------------------------------
/legacy/test/unit/common/services/features.js:
--------------------------------------------------------------------------------
1 | describe('Features', function () {
2 |
3 | var Features, $rootScope;
4 |
5 | beforeEach(function () {
6 | makeTestApp()
7 | .service('Features', require('app/common/services/features.js'));
8 |
9 |
10 | angular.mock.module('testApp');
11 | });
12 |
13 | beforeEach(angular.mock.inject(function (_$rootScope_, _Features_) {
14 | $rootScope = _$rootScope_;
15 | Features = _Features_;
16 | Features.loadFeatures();
17 | }));
18 |
19 | it('should check if feature is enabled', function () {
20 | expect(Features.isFeatureEnabled('test')).toBe(true);
21 | });
22 |
23 | it('should check if a view is enabled', function () {
24 | expect(Features.isViewEnabled('test')).toBe(true);
25 | });
26 |
27 | it('should get a limit for a given feature', function () {
28 | expect(Features.getLimit('test')).toEqual(1);
29 | });
30 |
31 | it('should reload features', function () {
32 | Features.features = undefined;
33 | Features.loadFeatures();
34 |
35 | expect(Features.features.limits.test).toEqual(1);
36 | });
37 | });
38 |
--------------------------------------------------------------------------------
/legacy/test/unit/common/services/view-helper-spec.js:
--------------------------------------------------------------------------------
1 | describe('view helper', function () {
2 |
3 | var ViewHelper;
4 |
5 | beforeEach(function () {
6 | makeTestApp()
7 | .service('ViewHelper', require('app/map/services/view-helper.js'))
8 | .service('ConfigEndpoint', function () {
9 | return {
10 | get : function () {}
11 | };
12 | })
13 | .factory('BootstrapConfig', function () {
14 | return { map: {}, site: {}, features: {} };
15 | });
16 |
17 | angular.mock.module('testApp');
18 | });
19 |
20 | beforeEach(angular.mock.inject(function (_ViewHelper_) {
21 | ViewHelper = _ViewHelper_;
22 | }));
23 |
24 | it('should return view and display name for map and list', function () {
25 | var views = ViewHelper.views();
26 | expect(_.pluck(views, 'name')).toEqual(['map', 'data']);
27 | expect(_.pluck(views, 'display_name')).toEqual(['views.map', 'views.data']);
28 | });
29 | });
30 |
--------------------------------------------------------------------------------
/legacy/test/unit/main/post/detail/post-media-value.directive.spec.js:
--------------------------------------------------------------------------------
1 | describe('post media value directive', function () {
2 |
3 | var $rootScope,
4 | $scope,
5 | isolateScope,
6 | MediaEndpoint,
7 | element;
8 |
9 | beforeEach(function () {
10 | fixture.setBase('mocked_backend/api/v3');
11 |
12 |
13 | var testApp = makeTestApp();
14 |
15 | testApp.directive('postMediaValue', require('app/data/post-detail/post-media-value.directive'))
16 | .value('$filter', function () {
17 | return function () {};
18 | });
19 |
20 | angular.mock.module('testApp');
21 | });
22 |
23 |
24 |
25 | beforeEach(angular.mock.inject(function (_$rootScope_, $compile) {
26 | $rootScope = _$rootScope_;
27 | $scope = _$rootScope_.$new();
28 |
29 | element = '';
30 | element = $compile(element)($scope);
31 | $rootScope.$digest();
32 | isolateScope = element.isolateScope();
33 | }));
34 |
35 | it('should load media properties', angular.mock.inject(function (_MediaEndpoint_) {
36 | MediaEndpoint = _MediaEndpoint_;
37 |
38 | expect(isolateScope.media.caption).toEqual('test caption');
39 | expect(isolateScope.media.original_file_url).toEqual('http://localhost/test.png');
40 | }));
41 | });
42 |
--------------------------------------------------------------------------------
/legacy/test/unit/main/post/modify/post-create.controller.spec.js:
--------------------------------------------------------------------------------
1 | describe('Post create controller', function () {
2 | var $scope, $controller;
3 |
4 | beforeEach(function () {
5 | fixture.setBase('mocked_backend/api/v3');
6 |
7 | makeTestApp()
8 | .value('PostEntity', function () {
9 | return fixture.load('posts/120.json');
10 | })
11 | .controller('postCreateController', require('app/data/post-create/post-create.controller.js'))
12 | .service('$transition$', function () {
13 | return {
14 | 'params': function () {
15 | return {
16 | 'id': 1
17 | };
18 | }
19 | };
20 | });
21 |
22 | angular.mock.module('testApp');
23 | });
24 |
25 | beforeEach(angular.mock.inject(function (_$rootScope_, _$controller_) {
26 | $scope = _$rootScope_.$new();
27 | $controller = _$controller_;
28 |
29 | }));
30 |
31 | beforeEach(function () {
32 | $controller('postCreateController', {
33 | $scope: $scope
34 | });
35 | });
36 |
37 | it('should load and set options', function () {
38 | expect($scope.post.allowed_privileges[0]).toEqual('read');
39 | expect($scope.post.form.id).toEqual(1);
40 | });
41 | });
42 |
--------------------------------------------------------------------------------
/legacy/test/unit/main/post/views/post-card.directive.spec.js:
--------------------------------------------------------------------------------
1 | describe('post card directive', function () {
2 |
3 | var $rootScope,
4 | $scope,
5 | isolateScope,
6 | GlobalFilter,
7 | Notify,
8 | element;
9 |
10 | beforeEach(function () {
11 | fixture.setBase('mocked_backend/api/v3');
12 |
13 |
14 | var testApp = makeTestApp();
15 |
16 | testApp.directive('postCard', require('app/map/post-card/post-card.directive'))
17 | .value('$filter', function () {
18 | return function () {};
19 | });
20 |
21 | angular.mock.module('testApp');
22 | });
23 |
24 |
25 |
26 | beforeEach(angular.mock.inject(function (_$rootScope_, $compile, _Notify_, _GlobalFilter_) {
27 | $rootScope = _$rootScope_;
28 | $scope = _$rootScope_.$new();
29 |
30 | GlobalFilter = _GlobalFilter_;
31 | Notify = _Notify_;
32 |
33 | $scope.post = fixture.load('posts/120.json');
34 |
35 | element = '';
36 | element = $compile(element)($scope);
37 | $scope.$digest();
38 | isolateScope = element.children().scope();
39 | }));
40 |
41 | describe('test directive functions', function () {
42 | });
43 | });
44 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/controllers/navigation.controller.mock.js:
--------------------------------------------------------------------------------
1 | module.exports = [function () {
2 | this.site = {
3 | name: 'Mock Site'
4 | };
5 | }];
6 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/factories/socket-factory.mock.js:
--------------------------------------------------------------------------------
1 | module.exports = [function () {
2 | return {
3 | init: function () {
4 | return;
5 | },
6 | on: function () {
7 | return;
8 | },
9 | emnit: function () {
10 | return;
11 | }
12 | };
13 | }];
14 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/services/accessibility.service.js:
--------------------------------------------------------------------------------
1 | module.exports = AccessibilityService;
2 | function AccessibilityService() {
3 | return {
4 | setFocus
5 | };
6 | function setFocus(id) {}
7 | }
8 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/services/authentication.js:
--------------------------------------------------------------------------------
1 | module.exports = [function () {
2 | var mockedAuthenticationData = {
3 | loginStatus: false
4 | };
5 | return {
6 | setAuthenticationData: function (authenticationData) {
7 | mockedAuthenticationData = authenticationData;
8 | },
9 | getLoginStatus: function () {
10 | return mockedAuthenticationData.loginStatus;
11 | },
12 | logout : function () {
13 | // Just a stub
14 | },
15 | openLogin : function () {
16 |
17 | }
18 | };
19 | }];
20 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/services/country-code-endpoint.js:
--------------------------------------------------------------------------------
1 | module.exports = [function () {
2 | return {
3 | query: function () {
4 | return {$promise: {
5 | then: function (successCallback, failCallback) {
6 | successCallback({'results': [{
7 | id: 1,
8 | country_name: 'testCountry',
9 | dial_code: '+100',
10 | country_code: 'TC'
11 | }]});
12 | }
13 | }};
14 | }
15 | };
16 | }];
17 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/services/data-export.js:
--------------------------------------------------------------------------------
1 | module.exports = [function () {
2 | return {
3 | startExport: function () {},
4 | loadExportJob: function () {},
5 | loadExportJobs: function () {
6 | return {
7 | then: function () {}
8 | };
9 | }
10 | };
11 | }];
12 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/services/data-import.js:
--------------------------------------------------------------------------------
1 | module.exports = [function () {
2 | return {
3 | update: function () {
4 | return {$promise: {
5 | then: function (successCallback, failCallback) {
6 | successCallback({
7 | name: 'test data-importer',
8 | id: 1
9 | });
10 | }
11 | }};
12 | },
13 | delete: function () {
14 | return {$promise: {
15 | then: function (successCallback) {
16 | successCallback();
17 | }
18 | }};
19 | },
20 | import: function (dataImporter) {
21 | return {$promise: {
22 | then: function (successCallback, failCallback) {
23 | dataImporter.id === 'pass' ? successCallback({id: 1}) : failCallback('error');
24 | }
25 | }};
26 | },
27 | upload: function (formData) {
28 | return {
29 | then: function (successCallback, failCallback) {
30 | successCallback({id: 1});
31 | }
32 | };
33 | }
34 | };
35 | }];
36 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/services/data-import.service.js:
--------------------------------------------------------------------------------
1 | module.exports = [function () {
2 | return {
3 | startImport: function () {},
4 | loadImportJob: function () {},
5 | loadImportJobs: function () {
6 | return {
7 | then: function () {}
8 | };
9 | },
10 | processImportJobs: function () {},
11 | setImportJobs: function () {},
12 | getImportJobs: function () {}
13 | };
14 | }];
15 |
16 |
17 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/services/data-retriever.js:
--------------------------------------------------------------------------------
1 | module.exports = [function () {
2 | return {
3 | setImportData: function (message) {
4 | return {};
5 | },
6 | getImportData: function (message) {
7 | return {};
8 | },
9 | dataMapperInitialData: function (message) {
10 | return {};
11 | }
12 | };
13 | }];
14 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/services/form-contact.js:
--------------------------------------------------------------------------------
1 | module.exports = [function () {
2 | return {
3 | query: function () {
4 | return {$promise: {
5 | then: function (successCallback, failCallback) {
6 | successCallback([{
7 | contact: 'test@ushahidi.com',
8 | id: 1
9 | }]);
10 | }
11 | }};
12 | },
13 | get: function () {
14 | return {$promise: {
15 | then: function (successCallback) {
16 | successCallback({
17 | contact: 'test@ushahidi.com',
18 | id: 1
19 | });
20 | }
21 | }};
22 | },
23 | update: function (contact) {
24 | return function (successCallback, failCallback) {
25 | contact.id === 'pass' ? successCallback({id: 1}) : failCallback('error');
26 | };
27 | },
28 | save: function (contact) {
29 | return function (successCallback, failCallback) {
30 | contact.formId === '1' ? successCallback({id: 1}) : failCallback('error');
31 | };
32 | }
33 | };
34 | }];
35 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/services/form-stats-endpoint.js:
--------------------------------------------------------------------------------
1 | module.exports = [function () {
2 | return {
3 | query: function () {
4 | return {$promise: {
5 | then: function (successCallback, failCallback) {
6 | successCallback({
7 | total_responses: 9,
8 | total_recipients: 5
9 | });
10 | }
11 | }};
12 | }
13 | };
14 | }];
15 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/services/global-filters.js:
--------------------------------------------------------------------------------
1 | module.exports = [function () {
2 | return {
3 | tags: [],
4 | form: [],
5 | set: [],
6 | current_stage: [],
7 | getPostQuery: function () {
8 | return {
9 | q: 'dummy'
10 | };
11 | },
12 | options: {
13 | tags: {},
14 | collections: {},
15 | forms: {}
16 | },
17 | loadInitialData: function () {},
18 | getDefaults: function () {},
19 | setSelected: function () {},
20 | clearSelected: function () {}
21 | };
22 | }];
23 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/services/hxl-export.js:
--------------------------------------------------------------------------------
1 | module.exports = [function () {
2 | return {
3 | getFormsWithTags: function () {
4 | return {$promise: {
5 | then: function (successCallback, failCallback) {
6 | successCallback([{
7 | name: 'test form',
8 | id: 1,
9 | attributes: [
10 | {
11 | name: 'test form attributes',
12 | id: 1,
13 | form_stage_id: 1,
14 | priority: 1,
15 | key: 'test_attr1',
16 | type: 'input',
17 | required: false,
18 | tags: []
19 | }
20 | ]
21 | }]);
22 | }
23 | }};
24 | }
25 | };
26 | }];
27 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/services/importnotify.js:
--------------------------------------------------------------------------------
1 | module.exports = [function () {
2 | return {
3 | importComplete: function (message) {
4 | return {
5 | then: function (successCallback) {
6 | successCallback();
7 | }
8 | };
9 | },
10 | getScope: function () {
11 | return {
12 | then: function (successCallback) {
13 | successCallback();
14 | }
15 | };
16 | }
17 | };
18 | }];
19 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/services/languages.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | function () {
3 | return {
4 | getLanguages: function() {
5 | return [{
6 | 'rtl': false,
7 | 'pluralequation': 'language.pluralequation',
8 | 'code': 'en',
9 | 'name': 'English',
10 | 'nplurals': 2
11 | }]
12 | }
13 | }
14 | }];
15 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/services/loadingProgress.service.js:
--------------------------------------------------------------------------------
1 | module.exports = [function () {
2 | return {
3 | watchTransitions: function () {},
4 | getLoadingState: function () {
5 | return true;
6 | },
7 | getSavingState: function () {
8 | return true;
9 | },
10 | setLoadingState: function () {},
11 | setSavingState: function () {}
12 | };
13 | }];
14 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/services/media-edit-service.js:
--------------------------------------------------------------------------------
1 | module.exports = [function () {
2 | return {
3 | saveMedia: function (media, post) {
4 | return {
5 | then: function (successCallback, failCallback) {
6 | successCallback(
7 | {'results': [{
8 | id: 1
9 | }]
10 | });
11 | }
12 | };
13 | },
14 | deleteMedia: function () {
15 | return true;
16 | },
17 | update: function () {
18 | return true;
19 | },
20 | uploadFile: function (dataImporter) {
21 | return true;
22 | }
23 | };
24 | }];
25 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/services/media.js:
--------------------------------------------------------------------------------
1 | module.exports = [function () {
2 | return {
3 | query: function () {
4 | return {$promise: {
5 | then: function (successCallback, failCallback) {
6 | successCallback({'results': [{
7 | original_file_url: 'http://localhost/test.png',
8 | caption: 'test caption'
9 | }]});
10 | }
11 | }};
12 | },
13 | get: function () {
14 | return {$promise: {
15 | then: function (successCallback) {
16 | successCallback({
17 | original_file_url: 'http://localhost/test.png',
18 | caption: 'test caption'
19 | });
20 | }
21 | }};
22 | },
23 | delete: function () {
24 | return {$promise: {
25 | then: function (successCallback) {
26 | successCallback();
27 | }
28 | }};
29 | }
30 | };
31 | }];
32 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/services/modal.service.js:
--------------------------------------------------------------------------------
1 | module.exports = [function () {
2 | return {
3 | openTemplate: function () {},
4 | openUrl: function () {},
5 | close: function () {}
6 | };
7 | }];
8 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/services/post-actions-service.js:
--------------------------------------------------------------------------------
1 | module.exports = [function () {
2 | return {
3 | delete: function (post) {
4 | return {
5 | then: function () {}
6 | };
7 | },
8 | getStatuses: function () {
9 | return ['published', 'draft', 'archived'];
10 | }
11 | };
12 | }];
13 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/services/post-edit-service.js:
--------------------------------------------------------------------------------
1 | module.exports = [function () {
2 | return {
3 | cleanPostValues: function (post) {
4 | return post;
5 | },
6 | cleanTagValues: function (post) {
7 | return post;
8 | },
9 | validatePost: function () {
10 | return true;
11 | },
12 | validateVideoUrl: function (url) {
13 | if (url === 'https://www.youtube.com/video/1234') {
14 | return ['https://www.youtube.com/embed/1234', 'https:', 'www.', 'youtube.com', 'be.com', 'embed/', '1234', undefined]
15 | } else {
16 | return null;
17 | }
18 | },
19 | canSavePost: function () {
20 | return true;
21 | },
22 | isFirstStage: function (dataImporter) {
23 | return true;
24 | },
25 | isStageValid: function (formData) {
26 | return true;
27 | }
28 | };
29 | }];
30 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/services/post-lock-endpoint.js:
--------------------------------------------------------------------------------
1 | module.exports = [function () {
2 | return {
3 | getLock: function () {
4 | return {$promise: {
5 | then: function (successCallback) {
6 | successCallback();
7 | }
8 | }};
9 | },
10 | unlockByPost: function () {
11 | return {$promise: {
12 | then: function (successCallback) {
13 | successCallback();
14 | }
15 | }};
16 | },
17 | unlock: function () {
18 | return {$promise: {
19 | then: function (successCallback) {
20 | successCallback();
21 | },
22 | finally: function (successCallback) {
23 | successCallback();
24 | }
25 | }};
26 | },
27 | options: function () {
28 | return {$promise: {
29 | then: function (successCallback) {
30 | successCallback();
31 | }
32 | }};
33 | }
34 | };
35 | }];
36 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/services/post-lock.service.js:
--------------------------------------------------------------------------------
1 | module.exports = [function () {
2 | return {
3 | createSocketListener: function () {
4 | return {$promise: {
5 | then: function (successCallback) {
6 | successCallback();
7 | }
8 | }};
9 | },
10 | unlockByPost: function () {
11 | return {$promise: {
12 | then: function (successCallback) {
13 | successCallback();
14 | }
15 | }};
16 | },
17 | unlock: function () {
18 | return {$promise: {
19 | then: function (successCallback) {
20 | successCallback();
21 | }
22 | }};
23 | },
24 | getLock: function () {
25 | return {$promise: {
26 | then: function (successCallback) {
27 | successCallback();
28 | }
29 | }};
30 | },
31 | isPostLockedForCurrentUser: function () {
32 | return {$promise: {
33 | then: function (successCallback) {
34 | successCallback();
35 | }
36 | }};
37 | }
38 | };
39 | }];
40 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/services/post-metadata-service.js:
--------------------------------------------------------------------------------
1 | module.exports = [function () {
2 | return {
3 | formatSource: function (source) { },
4 | loadUser: function () { },
5 | loadContact: function () { },
6 | validateUser: function () { }
7 | };
8 | }];
9 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/services/post-survey-service.js:
--------------------------------------------------------------------------------
1 | module.exports = [function () {
2 | return {
3 | allowedSurveys: function () {
4 | return [];
5 | },
6 | canCreatePostInSurvey : function () {}
7 | };
8 | }];
9 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/services/post-view-service.js:
--------------------------------------------------------------------------------
1 | module.exports = [function () {
2 | return {
3 | showNoPostsSlider: function () { }
4 | };
5 | }];
6 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/services/sdk/UtilsSdk.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | 'Util',
3 | function (
4 | Util
5 | ) {
6 | const url = Util.url('');
7 | const getLanguages = function() {
8 | return { then: function () {
9 | return [{'code':'ach','name':'Acoli'},{'code':'ady','name':'Adyghe'},{'code':'af','name':'Afrikaans'}];
10 | }
11 | }
12 | }
13 | return {getLanguages};
14 | }
15 | ];
16 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/services/session.js:
--------------------------------------------------------------------------------
1 | module.exports = [function () {
2 | var mockedSessionData = {};
3 | return {
4 | setSessionData: function (sessionData) {
5 | mockedSessionData = sessionData;
6 | },
7 | getSessionData: function () {
8 | return mockedSessionData;
9 | },
10 | getSessionDataEntry: function (key) {
11 | return mockedSessionData[key];
12 | },
13 | setSessionDataEntry: function (key, value) {
14 | mockedSessionData[key] = value;
15 | },
16 | setSessionDataEntries: function (entries) {
17 | mockedSessionData = angular.extend({}, mockedSessionData, entries);
18 | }
19 | };
20 | }];
21 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/services/survey-notify.js:
--------------------------------------------------------------------------------
1 | module.exports = [function () {
2 | return {
3 | success: function (message) {
4 | return {
5 | then: function (successCallback) {
6 | successCallback();
7 | }
8 | };
9 | }
10 | };
11 | }];
12 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/services/third_party/leaflet.js:
--------------------------------------------------------------------------------
1 | module.exports = [function () {
2 | return {
3 | geoJson : function () {
4 |
5 | },
6 | markerClusterGroup : function () {
7 |
8 | }
9 | };
10 | }];
11 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/services/third_party/transitions.js:
--------------------------------------------------------------------------------
1 | module.exports = [function () {
2 | return {
3 | onSuccess: function () {
4 | return function () {};
5 | }
6 | };
7 |
8 | }];
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/legacy/test/unit/mock/services/translation-service.js:
--------------------------------------------------------------------------------
1 | module.exports = ['$q',
2 | function ($q) {
3 | return {
4 | translate: function (language) {},
5 | setStartLanguage: function () {},
6 | getLanguage: function () {
7 | return $q(function (resolve, reject) {
8 | resolve('en');
9 | });
10 | },
11 | setLanguage: function () {}
12 | };
13 | }];
14 |
--------------------------------------------------------------------------------
/legacy/test/unit/settings/data-import/data-import-controller-spec.js:
--------------------------------------------------------------------------------
1 | describe('setting data import controller', function () {
2 |
3 | var $rootScope,
4 | $scope,
5 | Notify,
6 | $controller;
7 |
8 | beforeEach(function () {
9 |
10 | var testApp = makeTestApp();
11 |
12 | testApp.controller('settingDataImportController', require('app/settings/data-import/data-import.controller.js'));
13 |
14 | angular.mock.module('testApp');
15 | });
16 |
17 | beforeEach(angular.mock.inject(function (_$rootScope_, _$controller_, _Notify_) {
18 | $rootScope = _$rootScope_;
19 | $controller = _$controller_;
20 | Notify = _Notify_;
21 | $scope = _$rootScope_.$new();
22 |
23 | $rootScope.hasManageSettingsPermission = function () {
24 | return true;
25 | };
26 | }));
27 |
28 |
29 | beforeEach(function () {
30 | $rootScope.setLayout = function () {};
31 | $controller('settingDataImportController', {
32 | $scope: $scope,
33 | $rootScope: $rootScope
34 | });
35 |
36 | $rootScope.setLayout = function () {};
37 |
38 | $rootScope.$digest();
39 | $rootScope.$apply();
40 | });
41 |
42 | it('should retrieve forms and set them', function () {
43 | expect($scope.forms[0].name).toEqual('test form');
44 | });
45 |
46 | });
47 |
--------------------------------------------------------------------------------
/legacy/test/unit/settings/roles/roles-controller-spec.js:
--------------------------------------------------------------------------------
1 | describe('setting roles controller', function () {
2 |
3 | var $rootScope,
4 | $scope,
5 | $q,
6 | Notify,
7 | $controller;
8 |
9 | beforeEach(function () {
10 |
11 | var testApp = makeTestApp();
12 |
13 | testApp.controller('settingRolesController', require('app/settings/roles/roles.controller.js'));
14 |
15 | angular.mock.module('testApp');
16 | });
17 |
18 | beforeEach(angular.mock.inject(function (_$q_, _$rootScope_, _$controller_, _Notify_) {
19 | $rootScope = _$rootScope_;
20 | $q = _$q_;
21 | $controller = _$controller_;
22 | Notify = _Notify_;
23 | $scope = _$rootScope_.$new();
24 |
25 | $rootScope.hasManageSettingsPermission = function () {
26 | return true;
27 | };
28 | }));
29 |
30 |
31 | beforeEach(function () {
32 | spyOn($rootScope, '$emit').and.callThrough();
33 |
34 | $controller('settingRolesController', {
35 | $scope: $scope,
36 | $rootScope: $rootScope
37 | });
38 |
39 | $rootScope.$digest();
40 | $rootScope.$apply();
41 |
42 | });
43 |
44 | });
45 |
--------------------------------------------------------------------------------
/legacy/test/unit/settings/roles/setting-roles-directive-spec.js:
--------------------------------------------------------------------------------
1 | describe('setting roles directive', function () {
2 |
3 | var $rootScope,
4 | $scope,
5 | Notify,
6 | element;
7 |
8 | beforeEach(function () {
9 | fixture.setBase('mocked_backend/api/v3');
10 |
11 |
12 | var testApp = makeTestApp();
13 |
14 | testApp.directive('roles', require('app/settings/roles/roles.directive'))
15 | .value('$filter', function () {
16 | return function () {};
17 | })
18 | .value('PostEntity', {});
19 |
20 | angular.mock.module('testApp');
21 | });
22 |
23 |
24 |
25 | beforeEach(angular.mock.inject(function (_$rootScope_, $compile, _Notify_) {
26 | $rootScope = _$rootScope_;
27 | $scope = _$rootScope_.$new();
28 | $rootScope.setLayout = function () {};
29 | Notify = _Notify_;
30 |
31 | element = '';
32 | element = $compile(element)($scope);
33 | $scope.$digest();
34 | }));
35 |
36 | it('shuld refresh the view', function () {
37 | $scope.refreshView();
38 | expect($scope.roles.length).toEqual(2);
39 | });
40 |
41 | });
42 |
--------------------------------------------------------------------------------
/legacy/test/unit/settings/site/setting-editor-directive-spec.js:
--------------------------------------------------------------------------------
1 | describe('setting editor directive', function () {
2 |
3 | var $rootScope,
4 | $scope,
5 | Notify,
6 | element;
7 |
8 | beforeEach(function () {
9 | fixture.setBase('mocked_backend/api/v3');
10 |
11 |
12 | var testApp = makeTestApp();
13 |
14 | testApp.directive('settingEditor', require('app/settings/site/editor.directive'))
15 | .value('$filter', function () {
16 | return function () {};
17 | })
18 | .value('PostEntity', {});
19 |
20 | angular.mock.module('testApp');
21 | });
22 |
23 |
24 |
25 | beforeEach(angular.mock.inject(function (_$rootScope_, $compile, _Notify_) {
26 | $rootScope = _$rootScope_;
27 | $scope = _$rootScope_.$new();
28 |
29 | Notify = _Notify_;
30 |
31 | element = '';
32 | element = $compile(element)($scope);
33 | $scope.$digest();
34 | }));
35 |
36 | });
37 |
--------------------------------------------------------------------------------
/legacy/webpack.dev.config.js:
--------------------------------------------------------------------------------
1 | var config = require('./webpack.config');
2 |
3 | config.mode = 'development';
4 |
5 | config.devtool = 'sourcemap'
6 |
7 | config.devServer = {
8 | headers: {
9 | 'Access-Control-Allow-Origin': '*'
10 | },
11 | stats: 'errors-only'
12 | }
13 |
14 | // this is modules imported using require inside the code (for example dayjs),
15 | // needed for proxy in dev-environment
16 | config.output.chunkFilename = 'legacy-modules/[name].js'
17 |
18 | module.exports = config;
19 |
--------------------------------------------------------------------------------
/legacy/webpack.dist.config.js:
--------------------------------------------------------------------------------
1 | var config = require('./webpack.config');
2 | config.mode = 'production';
3 | config.stats = 'none';
4 | config.output.filename = '[name].[chunkhash].js';
5 |
6 | module.exports = config;
7 |
--------------------------------------------------------------------------------
/legacy/webpack.test.config.js:
--------------------------------------------------------------------------------
1 | var path = require('path');
2 | var config = require('./webpack.config');
3 |
4 | config.devtool = 'inline-source-map';
5 | config.plugins = [];
6 |
7 | // Add root to resolve for easier refs within tests
8 | config.resolve = {
9 | modules : [
10 | path.resolve('./'),
11 | 'node_modules'
12 | ]
13 | };
14 | config.output = {};
15 | config.mode = 'development';
16 |
17 |
18 | module.exports = config;
19 |
--------------------------------------------------------------------------------
/root/.eslintignore:
--------------------------------------------------------------------------------
1 | dist/*
--------------------------------------------------------------------------------
/root/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["important-stuff", "plugin:prettier/recommended"],
3 | "parser": "@babel/eslint-parser"
4 | }
5 |
--------------------------------------------------------------------------------
/root/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (https://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # TypeScript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 | # next.js build output
61 | .next
62 | dist
63 |
64 | # Editor directories and files
65 | .idea
66 | .vscode
67 | *.suo
68 | *.ntvs*
69 | *.njsproj
70 | *.sln
71 | *.sw?
72 | .DS_Store
73 |
--------------------------------------------------------------------------------
/root/.prettierignore:
--------------------------------------------------------------------------------
1 | .gitignore
2 | .prettierignore
3 | yarn.lock
4 | yarn-error.log
5 | package-lock.json
6 | LICENSE
7 | *.ejs
8 | dist
9 | coverage
10 | pnpm-lock.yaml
--------------------------------------------------------------------------------
/root/babel.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@babel/preset-env"],
3 | "plugins": [
4 | [
5 | "@babel/plugin-transform-runtime",
6 | {
7 | "useESModules": true,
8 | "regenerator": false
9 | }
10 | ]
11 | ],
12 | "env": {
13 | "test": {
14 | "presets": [
15 | [
16 | "@babel/preset-env",
17 | {
18 | "targets": "current node"
19 | }
20 | ]
21 | ]
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/root/src/config.js:
--------------------------------------------------------------------------------
1 | // Configure your Ushahidi deployment
2 | //
3 | // Uncomment lines below to configure your deployment
4 | // window.ushahidi = {
5 | // backendUrl : "https://ushahidi-platform-api-release.herokuapp.com",
6 | // mapboxApiKey: "",
7 | // sources: ['sms', 'twitter', 'web', 'email', 'whatsapp', 'ussd'] // remove sources you don't want from the sources array list
8 | // };
9 | window.ushahidi = {};
10 |
--------------------------------------------------------------------------------
/root/src/importmap.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {
3 | "@ushahidi/root-config": "/ushahidi-root-config.js",
4 | "@ushahidi/legacy-app": "/ushahidi-legacy-app.js",
5 | "@ushahidi/utilities": "/ushahidi-utilities.js",
6 | "@ushahidi/api": "/ushahidi-api.js",
7 | "@ushahidi/legacy-settings": "/ushahidi-settings.js",
8 | "@ushahidi/legacy-data": "/ushahidi-data.js",
9 | "@ushahidi/legacy-activity": "/ushahidi-activity.js"
10 |
11 | }
12 | }
--------------------------------------------------------------------------------
/root/src/loading.scss:
--------------------------------------------------------------------------------
1 | #bootstrap-loading {
2 | position: absolute;
3 | top: 50%;
4 | right: 0;
5 | left: 0;
6 | text-align: center;
7 | margin-top: -16px;
8 |
9 | .loading {
10 | .line {
11 | border-radius: 15px;
12 | background-color: #ffc334;
13 | display: inline-block;
14 | height: 15px;
15 | width: 15px;
16 | margin: 5px;
17 |
18 | &:nth-last-child(1) {animation: loadingBounce .6s .1s linear infinite;}
19 |
20 | &:nth-last-child(2) {animation: loadingBounce .6s .2s linear infinite;}
21 |
22 | &:nth-last-child(3) {animation: loadingBounce .6s .3s linear infinite;}
23 | }
24 | }
25 | }
26 |
27 | @keyframes loadingBounce {
28 | 0 {transform: translate(0,0);}
29 | 50% {transform: translate(0,15px);}
30 | 100% {transform: translate(0,0);}
31 | }
32 |
33 | .hidden {
34 | display: none !important;
35 | }
36 |
37 | #bootstrap-error {
38 | .alert {
39 | &.error {
40 | background-color: #fac4cb;
41 | border-left: 2px solid #b00f23;
42 | display: inline-block;
43 | font-style: italic;
44 | line-height: 1.4;
45 | padding: 8px 16px;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/root/src/microfrontend-layout.html:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
16 |
17 |
25 |
26 |
27 |
28 |
29 |
Sorry, something went wrong. Try reloading the page.
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/server/nginx-site.conf:
--------------------------------------------------------------------------------
1 | server {
2 | listen 80 default; ## listen for ipv4; this line is default and implied
3 | listen [::]:80 default ipv6only=on; ## listen for ipv6
4 |
5 | charset UTF-8;
6 | root /var/www/;
7 | index index.html;
8 |
9 | server_name ushahidi-client;
10 |
11 | add_header X-XSS-Protection "1; mode=block";
12 |
13 | location / {
14 | try_files $uri $uri/ @missing;
15 | }
16 |
17 | # Rewrite 404s back to index.html for pushState support
18 | # All routing is handled by Angular.
19 | location @missing {
20 | rewrite ^ /index.html last;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/server/rewrite.htaccess:
--------------------------------------------------------------------------------
1 | RewriteEngine on
2 | RewriteCond %{REQUEST_FILENAME} !-f
3 | RewriteRule ^.*$ /index.html [PT,L]
4 |
5 | Header set X-XSS-Protection "1; mode=block"
6 |
--------------------------------------------------------------------------------
/server/scripts/generateImportMap.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const file = './build/importmap.json';
3 | const buildFolder = './build';
4 | let importmap;
5 |
6 | const matchNames = function () {
7 | fs.readdir(buildFolder, 'utf8', (err, files) => {
8 | files = files.filter(file => file.includes('ushahidi') && file.split('.').pop() === 'js');
9 | // loop through hashed files in the build directory
10 | files.forEach(file => {
11 | // match with entries in the importmap
12 | Object.keys(importmap.imports).forEach(value => {
13 | let filename = importmap.imports[value].substring(1);
14 | filename = filename.slice(0, -3);
15 | if(file.includes(filename)) {
16 | importmap.imports[value] = "/" + file;
17 | }
18 | });
19 | });
20 | fs.writeFileSync(file, JSON.stringify(importmap));
21 | });
22 | }
23 |
24 | try {
25 | importmap = fs.readFileSync(file, 'utf8')
26 | importmap = JSON.parse(importmap)
27 | matchNames()
28 | } catch (err) {
29 | console.error(err)
30 | }
--------------------------------------------------------------------------------
/server/scripts/ready.js:
--------------------------------------------------------------------------------
1 | const address = require('address');
2 | const colors = require('colors');
3 | const PROXY_PORT = process.env.PORT || 3000;
4 | console.log("");
5 | console.log("*****************");
6 | console.log("");
7 | console.log("All clients have loaded.".green);
8 | console.log("");
9 | console.log("Ushahidi client is ready to be viewed at", `http://${address.ip()}:${PROXY_PORT}`.blue);
10 | console.log("");
11 | console.log("*****************");
12 | console.log("");
13 |
--------------------------------------------------------------------------------
/server/scripts/start.js:
--------------------------------------------------------------------------------
1 | const address = require('address');
2 | const colors = require('colors');
3 |
4 | console.log("");
5 | console.log("*****************");
6 | console.log("");
7 | console.log("Wait for all clients to load.".red);
8 | console.log("");
9 | console.log("*****************");
10 | console.log("");
11 |
--------------------------------------------------------------------------------
/single.stage.Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ushahidi/node-ci:node-10-gulp-4
2 |
3 | ARG HTTP_PORT=8080
4 |
5 | RUN apt-get update && \
6 | apt-get install --no-install-recommends -y nginx python python-pip python-setuptools python-yaml && \
7 | pip install 'jinja2-cli[yaml]==0.6.0' && \
8 | apt-get clean && \
9 | rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
10 |
11 | RUN mkdir -p /var/app
12 | WORKDIR /var/app
13 | COPY package.json .
14 | RUN npm-install-silent.sh
15 |
16 | COPY . ./
17 | RUN gulp build
18 |
19 | WORKDIR /usr/share/nginx/html
20 | RUN rsync -a --delete-after /var/app/server/www/ ./
21 | COPY app/config.js.j2 ./config.js.j2
22 | COPY app/config.json.j2 ./config.json.j2
23 | COPY docker/nginx.default.conf /etc/nginx/sites-enabled/default
24 | COPY docker/nginx.run.sh /nginx.run.sh
25 | RUN sed -i 's/$HTTP_PORT/'$HTTP_PORT'/' /etc/nginx/sites-enabled/default && \
26 | chgrp -R 0 . /var/lib/nginx /run && \
27 | chmod -R g+rwX . /var/lib/nginx /run && \
28 | ln -sf /dev/stdout /var/log/nginx/access.log && \
29 | ln -sf /dev/stderr /var/log/nginx/error.log
30 |
31 | ENV HTTP_PORT=$HTTP_PORT
32 | EXPOSE $HTTP_PORT
33 |
34 | ENTRYPOINT [ "/bin/sh", "/nginx.run.sh" ]
35 | CMD [ "/usr/sbin/nginx", "-g", "daemon off;" ]
36 |
--------------------------------------------------------------------------------
/utilities/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["important-stuff", "plugin:prettier/recommended"],
3 | "parser": "@babel/eslint-parser"
4 | }
5 |
--------------------------------------------------------------------------------
/utilities/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (https://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # TypeScript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 | # next.js build output
61 | .next
62 | dist
63 |
64 | # Editor directories and files
65 | .idea
66 | .vscode
67 | *.suo
68 | *.ntvs*
69 | *.njsproj
70 | *.sln
71 | *.sw?
72 | .DS_Store
73 |
--------------------------------------------------------------------------------
/utilities/.prettierignore:
--------------------------------------------------------------------------------
1 | .gitignore
2 | .prettierignore
3 | yarn.lock
4 | yarn-error.log
5 | package-lock.json
6 | dist
7 | coverage
8 | pnpm-lock.yaml
--------------------------------------------------------------------------------
/utilities/babel.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@babel/preset-env"],
3 | "plugins": [
4 | [
5 | "@babel/plugin-transform-runtime",
6 | {
7 | "useESModules": true,
8 | "regenerator": false
9 | }
10 | ]
11 | ],
12 | "env": {
13 | "test": {
14 | "presets": [
15 | [
16 | "@babel/preset-env",
17 | {
18 | "targets": "current node"
19 | }
20 | ]
21 | ]
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/utilities/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | transform: {
3 | "^.+\\.(j|t)sx?$": "babel-jest",
4 | },
5 | moduleNameMapper: {
6 | "\\.(css)$": "identity-obj-proxy",
7 | },
8 | };
9 |
--------------------------------------------------------------------------------
/utilities/src/ushahidi-utilities.js:
--------------------------------------------------------------------------------
1 | import { getConfig } from "@ushahidi/api";
2 |
3 | export const getPageMetadata = function () {
4 | return getConfig("site").then((config) => {
5 | return {
6 | title: config.name || "USHAHIDI",
7 | description: config.description || "",
8 | appleId: getAppleId(),
9 | };
10 | });
11 | };
12 |
13 | export const setBootstrapConfig = function () {
14 | if (window.ushahidi && window.ushahidi.backendUrl && !window.ushahidi.bootstrapConfig) {
15 | getConfig()
16 | .then(response => {
17 | return response.json();
18 | })
19 | .then(config => {
20 | // setting config
21 | window.ushahidi.bootstrapConfig = config;
22 | })
23 | .catch(err => {
24 | window.ushahidi.bootstrapConfig = {};
25 | });
26 | }
27 | }
28 |
29 | const getAppleId = function () {
30 | if (window.ushahidi && window.ushahidi.appStoreId) {
31 | return window.ushahidi.appStoreId;
32 | }
33 | return;
34 | };
35 |
--------------------------------------------------------------------------------
/utilities/webpack.config.js:
--------------------------------------------------------------------------------
1 | const { merge } = require("webpack-merge");
2 | const webpack = require("webpack");
3 | const singleSpaDefaults = require("webpack-config-single-spa");
4 |
5 | module.exports = (webpackConfigEnv, argv) => {
6 | const defaultConfig = singleSpaDefaults({
7 | orgName: "ushahidi",
8 | projectName: "utilities",
9 | webpackConfigEnv,
10 | argv
11 | });
12 |
13 | let filename = defaultConfig.mode === 'development' ? 'ushahidi-utilities.js' : 'ushahidi-utilities.[chunkhash].js';
14 | return merge(defaultConfig, {
15 | output: {
16 | filename,
17 | clean: true
18 | },
19 | plugins: [
20 | new webpack.DefinePlugin({
21 | BACKEND_URL: JSON.stringify(
22 | process.env.BACKEND_URL || "http://backend.url.undefined"
23 | ),
24 | }),
25 | ],
26 | });
27 | };
28 |
--------------------------------------------------------------------------------