├── .eslintignore ├── .eslintrc ├── .gitignore ├── .gitlab-ci.yml ├── .nginx └── nginx.conf ├── .npmignore ├── .npmrc ├── .prettierrc ├── .storybook ├── main.js └── preview.js ├── .travis.yml ├── Dockerfile ├── README.md ├── babel.config.js ├── bs-config.js ├── docs ├── README.md ├── docs │ ├── contributing.md │ ├── css │ │ └── styles.css │ ├── customization.md │ ├── develop-with-harmony.md │ ├── extensions │ │ ├── admonition.md │ │ ├── client │ │ │ ├── actions.md │ │ │ ├── api.md │ │ │ ├── base.md │ │ │ ├── cart.md │ │ │ ├── client.md │ │ │ ├── components.md │ │ │ ├── config.md │ │ │ ├── containers.md │ │ │ ├── core_components.md │ │ │ ├── development.md │ │ │ ├── error_handler.md │ │ │ ├── flow_manager.md │ │ │ ├── form_containers.md │ │ │ ├── global_spinner.md │ │ │ ├── mobile-app.md │ │ │ ├── multilingual.md │ │ │ ├── rba.md │ │ │ ├── render_mobile.md │ │ │ ├── requests.md │ │ │ ├── sagas.md │ │ │ ├── seo.md │ │ │ └── storybook.md │ │ ├── codehilite.md │ │ ├── footnotes.md │ │ ├── metadata.md │ │ ├── permalinks.md │ │ ├── pymdown.md │ │ └── server │ │ │ ├── authentication.md │ │ │ ├── config.md │ │ │ ├── generate_new_api.md │ │ │ ├── server.md │ │ │ └── websocket.md │ ├── getting-started.md │ ├── images │ │ ├── Stav.jpeg │ │ ├── favicon.ico │ │ ├── flow-manager-diagram.png │ │ ├── harmony-flow-data.png │ │ ├── harmony-logo.png │ │ ├── logos.png │ │ ├── state-machine.png │ │ └── webpack-logo.png │ ├── index.md │ ├── license.md │ ├── material-getting-started.md │ ├── release-notes.md │ ├── specimen.md │ └── team.md ├── mkdocs.yml └── site │ ├── 404.html │ ├── assets │ ├── images │ │ └── favicon.png │ ├── javascripts │ │ ├── bundle.ba57d267.min.js │ │ ├── bundle.ba57d267.min.js.map │ │ ├── lunr │ │ │ ├── min │ │ │ │ ├── lunr.ar.min.js │ │ │ │ ├── lunr.da.min.js │ │ │ │ ├── lunr.de.min.js │ │ │ │ ├── lunr.du.min.js │ │ │ │ ├── lunr.es.min.js │ │ │ │ ├── lunr.fi.min.js │ │ │ │ ├── lunr.fr.min.js │ │ │ │ ├── lunr.hu.min.js │ │ │ │ ├── lunr.it.min.js │ │ │ │ ├── lunr.ja.min.js │ │ │ │ ├── lunr.jp.min.js │ │ │ │ ├── lunr.multi.min.js │ │ │ │ ├── lunr.nl.min.js │ │ │ │ ├── lunr.no.min.js │ │ │ │ ├── lunr.pt.min.js │ │ │ │ ├── lunr.ro.min.js │ │ │ │ ├── lunr.ru.min.js │ │ │ │ ├── lunr.stemmer.support.min.js │ │ │ │ ├── lunr.sv.min.js │ │ │ │ ├── lunr.tr.min.js │ │ │ │ └── lunr.vi.min.js │ │ │ └── tinyseg.min.js │ │ ├── vendor.df0def68.min.js │ │ ├── vendor.df0def68.min.js.map │ │ └── worker │ │ │ ├── search.5eca75d3.min.js │ │ │ └── search.5eca75d3.min.js.map │ └── stylesheets │ │ ├── main.36ee6aaa.min.css │ │ ├── main.36ee6aaa.min.css.map │ │ ├── palette.83bccb1f.min.css │ │ └── palette.83bccb1f.min.css.map │ ├── contributing │ └── index.html │ ├── css │ └── styles.css │ ├── customization │ └── index.html │ ├── develop-with-harmony │ └── index.html │ ├── extensions │ ├── admonition │ │ └── index.html │ ├── client │ │ ├── actions │ │ │ └── index.html │ │ ├── api │ │ │ └── index.html │ │ ├── base │ │ │ └── index.html │ │ ├── cart │ │ │ └── index.html │ │ ├── client │ │ │ └── index.html │ │ ├── components │ │ │ └── index.html │ │ ├── config │ │ │ └── index.html │ │ ├── containers │ │ │ └── index.html │ │ ├── core_components │ │ │ └── index.html │ │ ├── development │ │ │ └── index.html │ │ ├── error_handler │ │ │ └── index.html │ │ ├── flow_manager │ │ │ └── index.html │ │ ├── form_containers │ │ │ └── index.html │ │ ├── global_spinner │ │ │ └── index.html │ │ ├── mobile-app │ │ │ └── index.html │ │ ├── multilingual │ │ │ └── index.html │ │ ├── rba │ │ │ └── index.html │ │ ├── render_mobile │ │ │ └── index.html │ │ ├── requests │ │ │ └── index.html │ │ ├── sagas │ │ │ └── index.html │ │ ├── seo │ │ │ └── index.html │ │ └── storybook │ │ │ └── index.html │ ├── codehilite │ │ └── index.html │ ├── footnotes │ │ └── index.html │ ├── metadata │ │ └── index.html │ ├── permalinks │ │ └── index.html │ ├── pymdown │ │ └── index.html │ └── server │ │ ├── authentication │ │ └── index.html │ │ ├── config │ │ └── index.html │ │ ├── generate_new_api │ │ └── index.html │ │ ├── server │ │ └── index.html │ │ └── websocket │ │ └── index.html │ ├── getting-started │ └── index.html │ ├── images │ ├── Stav.jpeg │ ├── favicon.ico │ ├── flow-manager-diagram.png │ ├── harmony-flow-data.png │ ├── harmony-logo.png │ ├── logos.png │ ├── state-machine.png │ └── webpack-logo.png │ ├── index.html │ ├── license │ └── index.html │ ├── material-getting-started │ └── index.html │ ├── release-notes │ └── index.html │ ├── search │ └── search_index.json │ ├── sitemap.xml │ ├── sitemap.xml.gz │ ├── specimen │ └── index.html │ └── team │ └── index.html ├── generator └── templates │ └── client │ ├── action-index │ ├── component-template │ ├── container-template │ ├── form-container-template │ ├── interfaces-template │ ├── manager │ ├── redux-template │ ├── saga-template │ ├── story │ └── story-container ├── gulpfile.js ├── index.d.ts ├── jest-puppeteer.config.js ├── jest.config.js ├── mobile-app ├── .gitignore ├── README.md ├── config.js ├── config.xml ├── gulpfile.js ├── harmony-plugins │ ├── configurations │ │ └── config.xml │ └── plugins │ │ ├── android.json │ │ ├── cordova-plugin-inappbrowser │ │ ├── .appveyor.yml │ │ ├── .asf.yaml │ │ ├── .eslintrc.yml │ │ ├── .gitattributes │ │ ├── .github │ │ │ ├── ISSUE_TEMPLATE.md │ │ │ ├── ISSUE_TEMPLATE │ │ │ │ ├── BUG_REPORT.md │ │ │ │ ├── FEATURE_REQUEST.md │ │ │ │ └── SUPPORT_QUESTION.md │ │ │ └── PULL_REQUEST_TEMPLATE.md │ │ ├── .gitignore │ │ ├── .npmignore │ │ ├── .travis.yml │ │ ├── CONTRIBUTING.md │ │ ├── LICENSE │ │ ├── NOTICE │ │ ├── README.md │ │ ├── RELEASENOTES.md │ │ ├── package.json │ │ ├── plugin.xml │ │ ├── src │ │ │ ├── android │ │ │ │ ├── InAppBrowser.java │ │ │ │ ├── InAppBrowserDialog.java │ │ │ │ ├── InAppChromeClient.java │ │ │ │ └── res │ │ │ │ │ ├── drawable-hdpi │ │ │ │ │ ├── ic_action_next_item.png │ │ │ │ │ ├── ic_action_previous_item.png │ │ │ │ │ └── ic_action_remove.png │ │ │ │ │ ├── drawable-mdpi │ │ │ │ │ ├── ic_action_next_item.png │ │ │ │ │ ├── ic_action_previous_item.png │ │ │ │ │ └── ic_action_remove.png │ │ │ │ │ ├── drawable-xhdpi │ │ │ │ │ ├── ic_action_next_item.png │ │ │ │ │ ├── ic_action_previous_item.png │ │ │ │ │ └── ic_action_remove.png │ │ │ │ │ └── drawable-xxhdpi │ │ │ │ │ ├── ic_action_next_item.png │ │ │ │ │ ├── ic_action_previous_item.png │ │ │ │ │ └── ic_action_remove.png │ │ │ ├── browser │ │ │ │ └── InAppBrowserProxy.js │ │ │ ├── ios │ │ │ │ ├── CDVInAppBrowserNavigationController.h │ │ │ │ ├── CDVInAppBrowserNavigationController.m │ │ │ │ ├── CDVInAppBrowserOptions.h │ │ │ │ ├── CDVInAppBrowserOptions.m │ │ │ │ ├── CDVWKInAppBrowser.h │ │ │ │ ├── CDVWKInAppBrowser.m │ │ │ │ ├── CDVWKInAppBrowserUIDelegate.h │ │ │ │ └── CDVWKInAppBrowserUIDelegate.m │ │ │ ├── osx │ │ │ │ ├── CDVInAppBrowser.h │ │ │ │ └── CDVInAppBrowser.m │ │ │ └── windows │ │ │ │ └── InAppBrowserProxy.js │ │ ├── tests │ │ │ ├── .eslintrc.yml │ │ │ ├── package.json │ │ │ ├── plugin.xml │ │ │ ├── resources │ │ │ │ ├── inject.css │ │ │ │ ├── inject.html │ │ │ │ ├── inject.js │ │ │ │ ├── local.html │ │ │ │ ├── local.pdf │ │ │ │ └── video.html │ │ │ └── tests.js │ │ ├── types │ │ │ └── index.d.ts │ │ └── www │ │ │ ├── inappbrowser.css │ │ │ └── inappbrowser.js │ │ ├── cordova-plugin-ionic-webview │ │ ├── .circleci │ │ │ └── config.yml │ │ ├── CHANGELOG.md │ │ ├── CONTRIBUTING.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── package.json │ │ ├── plugin.xml │ │ └── src │ │ │ ├── android │ │ │ └── com │ │ │ │ └── ionicframework │ │ │ │ └── cordova │ │ │ │ └── webview │ │ │ │ ├── AndroidProtocolHandler.java │ │ │ │ ├── Common.java │ │ │ │ ├── IonicWebView.java │ │ │ │ ├── IonicWebViewEngine.java │ │ │ │ ├── UriMatcher.java │ │ │ │ └── WebViewLocalServer.java │ │ │ ├── ios │ │ │ ├── CDVWKProcessPoolFactory.h │ │ │ ├── CDVWKProcessPoolFactory.m │ │ │ ├── CDVWKWebViewEngine.h │ │ │ ├── CDVWKWebViewEngine.m │ │ │ ├── CDVWKWebViewUIDelegate.h │ │ │ ├── CDVWKWebViewUIDelegate.m │ │ │ ├── IONAssetHandler.h │ │ │ ├── IONAssetHandler.m │ │ │ ├── LICENSE │ │ │ └── wk-plugin.js │ │ │ └── www │ │ │ ├── ios │ │ │ └── ios-wkwebview-exec.js │ │ │ └── util.js │ │ ├── cordova-plugin-native-spinner │ │ ├── LICENSE │ │ ├── README.md │ │ ├── package.json │ │ ├── plugin.xml │ │ ├── src │ │ │ ├── android │ │ │ │ ├── CallbackProgressDialog.java │ │ │ │ └── SpinnerDialog.java │ │ │ ├── ios │ │ │ │ ├── CDVSpinnerDialog.h │ │ │ │ └── CDVSpinnerDialog.m │ │ │ ├── windows │ │ │ │ └── SpinnerDialogProxy.js │ │ │ └── wp │ │ │ │ └── SpinnerDialog.cs │ │ └── www │ │ │ └── SpinnerDialog.js │ │ ├── cordova-plugin-splashscreen │ │ ├── .appveyor.yml │ │ ├── .asf.yaml │ │ ├── .eslintrc.yml │ │ ├── .github │ │ │ ├── ISSUE_TEMPLATE.md │ │ │ ├── ISSUE_TEMPLATE │ │ │ │ ├── BUG_REPORT.md │ │ │ │ ├── FEATURE_REQUEST.md │ │ │ │ └── SUPPORT_QUESTION.md │ │ │ └── PULL_REQUEST_TEMPLATE.md │ │ ├── .gitignore │ │ ├── .npmignore │ │ ├── .travis.yml │ │ ├── CONTRIBUTING.md │ │ ├── LICENSE │ │ ├── NOTICE │ │ ├── README.md │ │ ├── RELEASENOTES.md │ │ ├── package.json │ │ ├── plugin.xml │ │ ├── src │ │ │ ├── android │ │ │ │ └── SplashScreen.java │ │ │ ├── browser │ │ │ │ └── SplashScreenProxy.js │ │ │ └── windows │ │ │ │ └── SplashScreenProxy.js │ │ ├── tests │ │ │ ├── package.json │ │ │ ├── plugin.xml │ │ │ └── tests.js │ │ ├── types │ │ │ └── index.d.ts │ │ └── www │ │ │ └── splashscreen.js │ │ ├── cordova-plugin-statusbar │ │ ├── .jshintrc │ │ ├── CONTRIBUTING.md │ │ ├── LICENSE │ │ ├── NOTICE │ │ ├── README.md │ │ ├── RELEASENOTES.md │ │ ├── package.json │ │ ├── plugin.xml │ │ ├── src │ │ │ ├── android │ │ │ │ └── StatusBar.java │ │ │ ├── browser │ │ │ │ └── StatusBarProxy.js │ │ │ ├── ios │ │ │ │ ├── CDVStatusBar.h │ │ │ │ └── CDVStatusBar.m │ │ │ ├── windows │ │ │ │ └── StatusBarProxy.js │ │ │ └── wp │ │ │ │ └── StatusBar.cs │ │ ├── tests │ │ │ ├── package.json │ │ │ ├── plugin.xml │ │ │ └── tests.js │ │ ├── types │ │ │ └── index.d.ts │ │ └── www │ │ │ └── statusbar.js │ │ ├── cordova-plugin-whitelist │ │ ├── CONTRIBUTING.md │ │ ├── LICENSE │ │ ├── NOTICE │ │ ├── README.md │ │ ├── RELEASENOTES.md │ │ ├── package.json │ │ ├── plugin.xml │ │ ├── src │ │ │ └── android │ │ │ │ └── WhitelistPlugin.java │ │ └── tests │ │ │ ├── README.md │ │ │ ├── package.json │ │ │ ├── plugin.xml │ │ │ ├── scripts │ │ │ └── remove-access.js │ │ │ ├── src │ │ │ └── android │ │ │ │ └── WhitelistAPI.java │ │ │ ├── tests.js │ │ │ └── www │ │ │ └── whitelist.js │ │ ├── fetch.json │ │ ├── ios.json │ │ └── phonegap-plugin-contentsync │ │ ├── .bithoundrc │ │ ├── .editorconfig │ │ ├── .github │ │ ├── CONTRIBUTING.md │ │ ├── ISSUE_TEMPLATE.md │ │ └── PULL_REQUEST_TEMPLATE.md │ │ ├── .gitignore │ │ ├── .jshintrc │ │ ├── .npmignore │ │ ├── .travis.yml │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── NOTICE │ │ ├── README.md │ │ ├── package.json │ │ ├── plugin.xml │ │ ├── sample │ │ ├── css │ │ │ └── index.css │ │ ├── img │ │ │ └── logo.png │ │ ├── index.html │ │ └── js │ │ │ └── index.js │ │ ├── spec │ │ ├── helper │ │ │ └── cordova.js │ │ └── index.spec.js │ │ ├── src │ │ ├── android │ │ │ └── Sync.java │ │ ├── browser │ │ │ └── Sync.js │ │ ├── ios │ │ │ ├── ContentSync.h │ │ │ ├── ContentSync.m │ │ │ ├── SSZipArchive.h │ │ │ ├── SSZipArchive.m │ │ │ └── minizip │ │ │ │ ├── crypt.h │ │ │ │ ├── ioapi.c │ │ │ │ ├── ioapi.h │ │ │ │ ├── mztools.c │ │ │ │ ├── mztools.h │ │ │ │ ├── unzip.c │ │ │ │ ├── unzip.h │ │ │ │ ├── zip.c │ │ │ │ └── zip.h │ │ ├── windows │ │ │ ├── SyncProxy.js │ │ │ └── ZipWinProj │ │ │ │ ├── PGZipInflate.cs │ │ │ │ ├── Properties │ │ │ │ └── AssemblyInfo.cs │ │ │ │ └── ZipWinProj.csproj │ │ └── wp8 │ │ │ ├── Sync.cs │ │ │ └── Unzip.cs │ │ ├── tests │ │ ├── anyfile.txt │ │ ├── archives │ │ │ ├── www1.zip │ │ │ └── www2.zip │ │ ├── package.json │ │ ├── plugin.xml │ │ ├── scripts │ │ │ ├── start-server.sh │ │ │ └── stop-server.sh │ │ └── tests.js │ │ └── www │ │ └── index.js ├── package-lock.json ├── package.json ├── res │ ├── icons │ │ ├── android │ │ │ ├── hdpi.png │ │ │ ├── ldpi.png │ │ │ ├── mdpi.png │ │ │ ├── xhdpi.png │ │ │ ├── xxhdpi.png │ │ │ └── xxxhdpi.png │ │ └── ios │ │ │ ├── icon-1024.png │ │ │ ├── icon-167.png │ │ │ ├── icon-20.png │ │ │ ├── icon-24@2x.png │ │ │ ├── icon-29@3x.png │ │ │ ├── icon-40.png │ │ │ ├── icon-40@2x.png │ │ │ ├── icon-50.png │ │ │ ├── icon-50@2x.png │ │ │ ├── icon-60.png │ │ │ ├── icon-60@2x.png │ │ │ ├── icon-60@3x.png │ │ │ ├── icon-72.png │ │ │ ├── icon-72@2x.png │ │ │ ├── icon-76.png │ │ │ ├── icon-76@2x.png │ │ │ ├── icon-83.5@2x.png │ │ │ ├── icon-small.png │ │ │ ├── icon-small@2x.png │ │ │ ├── icon-small@3x.png │ │ │ ├── icon.png │ │ │ └── icon@2x.png │ └── screen │ │ ├── android │ │ ├── splash-land-hdpi.png │ │ ├── splash-land-ldpi.png │ │ ├── splash-land-mdpi.png │ │ ├── splash-land-xhdpi.png │ │ ├── splash-land-xxhdpi.png │ │ ├── splash-port-hdpi.png │ │ ├── splash-port-ldpi.png │ │ ├── splash-port-mdpi.png │ │ ├── splash-port-xhdpi.png │ │ └── splash-port-xxhdpi.png │ │ └── ios │ │ ├── Default@2x~universal~anyany.png │ │ ├── Default@2x~universal~comany.png │ │ ├── Default@2x~universal~comcom.png │ │ ├── Default@3x~universal~anyany.png │ │ ├── Default@3x~universal~anycom.png │ │ └── Default@3x~universal~comany.png └── webpack.config.js ├── package-lock.json ├── package.json ├── postcss.config.js ├── src ├── App.tsx ├── actions │ ├── cart │ │ ├── index.ts │ │ ├── interface.ts │ │ ├── manager.ts │ │ ├── redux.ts │ │ └── sagas.ts │ ├── catalog │ │ ├── index.ts │ │ ├── interface.ts │ │ ├── manager.ts │ │ ├── redux.ts │ │ └── sagas.ts │ ├── flowManager │ │ ├── index.ts │ │ ├── interface.ts │ │ ├── manager.ts │ │ ├── redux.ts │ │ └── sagas.ts │ ├── index.ts │ ├── localPersistData │ │ ├── index.ts │ │ ├── interface.ts │ │ ├── manager.ts │ │ ├── redux.ts │ │ └── sagas.ts │ └── sessionPersistData │ │ ├── index.ts │ │ ├── interface.ts │ │ ├── manager.ts │ │ ├── redux.ts │ │ └── sagas.ts ├── base │ └── features │ │ ├── base-api │ │ └── index.ts │ │ ├── base-cart │ │ ├── index.ts │ │ ├── interfaces.ts │ │ ├── makeActionTypes.ts │ │ ├── makeActions.ts │ │ ├── makeCart.ts │ │ └── makeReducer.ts │ │ ├── base-decorator │ │ ├── createReducerCase.ts │ │ ├── createSaga.ts │ │ ├── customRoute.tsx │ │ ├── index.ts │ │ ├── storybook.tsx │ │ ├── withField.tsx │ │ ├── withFilter.tsx │ │ ├── withSEO.tsx │ │ └── withToaster.tsx │ │ ├── base-error-handler │ │ ├── index.ts │ │ └── reducer.ts │ │ ├── base-filter │ │ ├── index.ts │ │ └── reducer.ts │ │ ├── base-flow-manager │ │ └── index.ts │ │ ├── base-global-spinner │ │ ├── index.tsx │ │ └── reducer.ts │ │ ├── base-history │ │ └── index.ts │ │ ├── base-mock-service-worker │ │ ├── browser.ts │ │ └── index.ts │ │ ├── base-rba │ │ ├── components │ │ │ └── RBAC.ts │ │ ├── consts.ts │ │ ├── index.ts │ │ ├── interfaces.ts │ │ └── reducer.ts │ │ ├── base-reducers │ │ └── index.ts │ │ ├── base-redux-react-connect │ │ └── index.ts │ │ ├── base-redux-websocket-actions │ │ └── index.ts │ │ ├── base-render-mobile │ │ └── index.ts │ │ ├── base-services │ │ ├── index.ts │ │ ├── serviceTags.ts │ │ └── storeListener.ts │ │ ├── base-store │ │ └── index.ts │ │ ├── base-translations │ │ └── index.ts │ │ └── index.ts ├── common-components │ ├── business │ │ ├── DeviceCard │ │ │ ├── DeviceCard.stories.tsx │ │ │ ├── index.tsx │ │ │ └── style.scss │ │ ├── Spinner │ │ │ ├── Spinner.stories.tsx │ │ │ ├── index.tsx │ │ │ └── style.scss │ │ └── index.ts │ └── controllers │ │ ├── FieldInput │ │ ├── FieldInput.stories.tsx │ │ └── index.tsx │ │ └── index.ts ├── config.ts ├── configurations │ ├── error.config.json │ ├── flows.conditions.ts │ └── spinner.config.json ├── containers │ ├── ErrorHandler │ │ ├── README.md │ │ ├── index.tsx │ │ └── withErrorHandler.tsx │ ├── Header │ │ ├── Header.stories.tsx │ │ ├── index.tsx │ │ └── style.scss │ ├── IFrame │ │ └── index.tsx │ └── Localization │ │ ├── Localization.stories.tsx │ │ └── index.tsx ├── index.tsx ├── pages │ ├── Checkout │ │ └── index.tsx │ ├── DevicesGallery │ │ ├── index.tsx │ │ └── style.scss │ ├── ErrorPage │ │ ├── ErrorPage.stories.tsx │ │ └── index.tsx │ └── FormExample │ │ └── index.tsx ├── public │ ├── assets │ │ └── images │ │ │ ├── Spinner.svg │ │ │ ├── favicon.ico │ │ │ ├── generic-mobile.jpg │ │ │ └── harmony-logo.png │ ├── config │ │ └── flow-manager │ │ │ ├── flows.config.json │ │ │ ├── sub.flows.config.json │ │ │ └── types.json │ ├── index.ejs │ ├── mockServiceWorker.js │ └── sass │ │ ├── mixin.scss │ │ └── style.scss ├── requests │ ├── index.ts │ └── mock-service-worker │ │ ├── apis.ts │ │ ├── blackList.ts │ │ ├── handlers.ts │ │ ├── interface.ts │ │ ├── responses │ │ └── devices │ │ │ └── get_latestDevicesWithCustomResponseCode.json │ │ └── whiteList.ts ├── routes │ ├── PageContainer.tsx │ ├── RoutesPath.ts │ └── index.tsx ├── stories │ ├── Introduction.stories.mdx │ └── assets │ │ ├── code-brackets.svg │ │ ├── colors.svg │ │ ├── comments.svg │ │ ├── direction.svg │ │ ├── flow.svg │ │ ├── plugin.svg │ │ ├── repo.svg │ │ └── stackalt.svg ├── translation │ ├── index.ts │ └── json │ │ ├── en.json │ │ └── fr.json └── utils │ ├── globalService.ts │ └── validations.ts ├── test └── tests │ └── device-gallery.ts ├── tsconfig.json └── webpack.config.js /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | npm-debug.log 3 | .DS_Store 4 | # IntelliJ 5 | *.iml 6 | /.idea 7 | /.vscode/launch.json 8 | dist 9 | storybook-static 10 | /storybook-static 11 | 12 | #mobile app 13 | mobile-app/.DS_Store 14 | 15 | #intellij 16 | mobile-app/.idea 17 | # Logs 18 | mobile-app/logs 19 | mobile-app/*.log 20 | mobile-app/npm-debug.log* 21 | 22 | # Runtime data 23 | mobile-app/pids 24 | mobile-app/*.pid 25 | mobile-app/*.seed 26 | 27 | # Directory for instrumented libs generated by jscoverage/JSCover 28 | mobile-app/lib-cov 29 | 30 | # Coverage directory used by tools like istanbul 31 | mobile-app/coverage 32 | 33 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 34 | mobile-app/.grunt 35 | 36 | # node-waf configuration 37 | mobile-app/.lock-wscript 38 | 39 | # Compiled binary addons (http://nodejs.org/api/addons.html) 40 | mobile-app/build/Release 41 | 42 | # Dependency directory 43 | mobile-app/node_modules 44 | 45 | # Optional npm cache directory 46 | mobile-app/.npm 47 | 48 | # Optional REPL history 49 | mobile-app/.node_repl_history 50 | 51 | # Cordova platforms and plugins 52 | mobile-app/plugins 53 | mobile-app/platforms 54 | 55 | # Webpack bundle 56 | mobile-app/www 57 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | image: node:latest 2 | 3 | stages: 4 | - build 5 | 6 | cache: 7 | paths: 8 | - node_modules/ 9 | 10 | install_dependencies: 11 | stage: build 12 | script: 13 | - npm install 14 | - npm run build 15 | 16 | variables: 17 | GIT_SSL_NO_VERIFY: "true" 18 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /dist 3 | npm-debug.log 4 | /.DS_Store 5 | .DS_Store 6 | 7 | # IntelliJ 8 | *.iml 9 | /.idea 10 | package-lock.json 11 | 12 | 13 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/.npmrc -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 120, 3 | "endOfLine": "auto", 4 | "singleQuote": true, 5 | "tabWidth": 4, 6 | "useTabs": true, 7 | "trailingComma": "es5" 8 | } -------------------------------------------------------------------------------- /.storybook/main.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const CopyWebpackPlugin = require('copy-webpack-plugin'); 3 | const custom = require('../webpack.config.js'); 4 | 5 | module.exports = { 6 | core: { 7 | builder: "webpack5" 8 | }, 9 | 'stories': [ 10 | '../src/**/*.stories.mdx', 11 | '../src/**/*.stories.@(js|jsx|ts|tsx)', 12 | ], 13 | 'addons': [ 14 | '@storybook/addon-links', 15 | '@storybook/addon-essentials', 16 | '@storybook/addon-postcss' 17 | ], 18 | webpackFinal: async (config) => { 19 | return { 20 | ...config, 21 | module: { 22 | rules: [ 23 | ...config.module.rules, 24 | { 25 | test: /\.(tsx|ts)?$/, 26 | loader: 'ts-loader', 27 | exclude: /node_modules/, 28 | options: { 29 | transpileOnly: true 30 | } 31 | }, 32 | { 33 | test: /\.s[ac]ss$/i, 34 | use: ["style-loader", "css-loader?url=false", "sass-loader"] 35 | } 36 | ], 37 | }, 38 | resolve: { 39 | ...config.resolve, 40 | ...custom.resolve, 41 | } 42 | }; 43 | } 44 | }; 45 | -------------------------------------------------------------------------------- /.storybook/preview.js: -------------------------------------------------------------------------------- 1 | /* -------- Load Styles --------- */ 2 | import 'bootstrap/dist/css/bootstrap.min.css'; // Can be replace with other style framework 3 | import 'public/sass/style.scss'; 4 | import BaseStorybookDecorator from '@base/features/base-decorator/storybook'; 5 | import { addDecorator } from '@storybook/react'; 6 | 7 | addDecorator(BaseStorybookDecorator); 8 | 9 | export const parameters = { 10 | actions: { argTypesRegex: "^on[A-Z].*" }, 11 | controls: { 12 | matchers: { 13 | color: /(background|color)$/i, 14 | date: /Date$/, 15 | }, 16 | }, 17 | } 18 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '10' 4 | cache: npm 5 | script: npm run build -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # 1. Build 2 | FROM node:alpine as builder 3 | 4 | WORKDIR /app 5 | COPY package.json ./ 6 | RUN npm i 7 | 8 | COPY . . 9 | RUN npm run build 10 | RUN ls 11 | # 2. Deploy our app to NGINX 12 | FROM nginx:alpine 13 | 14 | ## Replace the default nginx index page with our Angular app 15 | RUN rm -rf /usr/share/nginx/html/* 16 | COPY /dist /usr/share/nginx/html 17 | RUN ls 18 | 19 | COPY ./.nginx/nginx.conf /etc/nginx/nginx.conf 20 | 21 | ENTRYPOINT ["nginx", "-g", "daemon off;"] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Harmony Framework

2 | 3 |
4 | 5 | react boilerplate banner 6 | 7 |
8 | 9 |
10 | 11 |
Start your next react project in seconds
12 |
13 |
Harmony Boilerplate gives you the best developer experience with all the features you need for production based react redux: react routers & mobile rendering, TypeScript support, smart bundling, sagas, and more. No config needed.
14 |
15 |
16 | 17 | Documentation 18 | 19 |
20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | ["@babel/preset-env", {targets : {node: "14"}}], 4 | ["@babel/preset-react", {runtime: "automatic"}], 5 | "@babel/preset-typescript" 6 | ], 7 | plugins: [ 8 | "react-require", 9 | "react-hot-loader/babel", 10 | ["@babel/plugin-proposal-decorators" ,{legacy: true }], 11 | ["@babel/plugin-proposal-class-properties", { loose : true}], 12 | ["@babel/plugin-proposal-private-methods", { loose: true }], 13 | ["@babel/plugin-proposal-private-property-in-object", {loose: true }] 14 | ] 15 | }; 16 | -------------------------------------------------------------------------------- /bs-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | port: 3000, 3 | server: { 4 | baseDir: './dist' 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | react boilerplate banner 4 | 5 |
6 | 7 |
8 | 9 |
Harmony Documentation
10 | 11 |
12 | Created to do great things. 13 |
14 | 15 | ## Prerequisites 16 | - View [MkDocs documentation](http://www.mkdocs.org/). 17 | 18 | ## Installation 19 | In order to manually install MkDocs you'll need Python installed on your system, as well as the Python package manager, pip. 20 | 21 | - pip install mkdocs 22 | - pip install mkdocs-material 23 | - cd docs 24 | - mkdocs serve 25 | 26 | 27 | -------------------------------------------------------------------------------- /docs/docs/customization.md: -------------------------------------------------------------------------------- 1 | # Customization 2 | 3 | -------------------------------------------------------------------------------- /docs/docs/develop-with-harmony.md: -------------------------------------------------------------------------------- 1 | 2 | ## Flow Data 3 | 4 | The following diagram display basic redux architecture with few Harmony Features. 5 | You can get more information on every feature in the docs. 6 | 7 |
8 | [![Harmony Flow Data](images/harmony-flow-data.png)](images/harmony-flow-data.png) 9 |
10 |
11 | 12 | -------------------------------------------------------------------------------- /docs/docs/extensions/client/api.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/docs/docs/extensions/client/api.md -------------------------------------------------------------------------------- /docs/docs/extensions/client/base.md: -------------------------------------------------------------------------------- 1 | # Base Folder 2 | 3 | Base Folder include the core files.
4 | You can see that as Harmony framework. 5 | 6 | !!! tip "Customization" 7 | 8 | Generally yuou should not change the files in this folder
9 | unless you know what is going there and you want to custom it. 10 | See more `Contributing` section if you want to improve Harmony Base Folder :). 11 | 12 | Inside `base` you can found `Features` folder: 13 | 14 | 15 | **features** 16 | 17 | Features include all the core features that use in your application, such as error handler, global spinner logic etc .. 18 | -------------------------------------------------------------------------------- /docs/docs/extensions/client/components.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Generate Components 4 | 5 | Location: `src/components/` 6 | 7 | Components, not much to say, here your components `( components/ )` or in other words dump components, it means that the component is not connect to redux and relay only on props. 8 | 9 | We recommended to use arrow function for better performance, But you can also use React Component. 10 | 11 | ## Create Component by cli 12 | 13 | ``` sh 14 | $ gulp createComponent --name MyComponent --storyTitle Business Components/MyComponent 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/docs/extensions/client/config.md: -------------------------------------------------------------------------------- 1 | # Config 2 | 3 | Client configuration located on `client/src/config.js` 4 | 5 | ```typescript 6 | interface Config { 7 | ROOT_SERVER_URL?: string; 8 | ROOT_WS_URL?: string; 9 | USE_WS_ACTION?: boolean; 10 | COMMON_AUTHORIZATION_HEADER?: string; 11 | COMMON_URL_PARAMS?: Array<{key: string; value: string}>; 12 | appName?: string; 13 | } 14 | 15 | const initConfig = (): Config => { 16 | let appConfig: Config = {}; 17 | 18 | if (process.env.NODE_ENV === 'development') { 19 | /* ---------- Config Development --------- */ 20 | appConfig = { 21 | USE_WS_ACTION: false, 22 | ROOT_SERVER_URL: 'https://fonoapi.freshpixl.com/v1/', 23 | COMMON_AUTHORIZATION_HEADER: 'uxfauthorization', 24 | COMMON_URL_PARAMS: [{ key: 'salesChannel', value: 'retail' }], 25 | ROOT_WS_URL: 'ws://localhost:3030', 26 | }; 27 | } else if (process.env.NODE_ENV === 'production') { 28 | /* ---------- Config Production --------- */ 29 | appConfig = { 30 | USE_WS_ACTION: false, 31 | ROOT_SERVER_URL: 'https://fonoapi.freshpixl.com/v1/', 32 | COMMON_AUTHORIZATION_HEADER: 'uxfauthorization', 33 | COMMON_URL_PARAMS: [{ key: 'salesChannel', value: 'retail' }], 34 | ROOT_WS_URL: 'ws://localhost:3030' 35 | }; 36 | } 37 | 38 | return appConfig; 39 | }; 40 | 41 | export const config = initConfig(); 42 | ``` 43 | 44 | Define your root server url and root websocket url. 45 | These variables are used in app. 46 | -------------------------------------------------------------------------------- /docs/docs/extensions/client/containers.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Generate Core Components 4 | 5 | Location: `src/containers/` 6 | 7 | Containers is the components who is connected to redux. 8 | 9 | Create Container by cli 10 | ``` sh 11 | $ gulp createContainer --className myClassName 12 | ``` 13 | 14 | ## Example Code 15 | 16 | !!! warning "Harmony Connect" 17 | Any Container connected to redux with `harmonyConnect` to enjoy all of Harmony features.
18 | Read more about Harmony Connect in Base Folder Section. 19 | 20 | ``` JS 21 | import * as React from 'react'; 22 | import {baseConnect} from '@base/features/base-redux-react-connect'; 23 | 24 | interface IProps { 25 | languages: any; 26 | setActiveLanguage: Function; 27 | } 28 | 29 | class Localization extends React.Component { 30 | render() { 31 | const { languages, setActiveLanguage } = this.props; 32 | 33 | return ( 34 |
35 | Language: 36 | 43 |
44 | ); 45 | } 46 | } 47 | 48 | export default baseConnect(Localization, 49 | (/* state */) => { 50 | return {}; 51 | }, 52 | { 53 | 54 | } 55 | ); 56 | ``` -------------------------------------------------------------------------------- /docs/docs/extensions/client/render_mobile.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mobile Render 4 | 5 | ## Mobile Render Concept 6 | 7 | Webapp required us to support multiple screen sizes. 8 | Single render method in react component and detection can take effort. 9 | Harmony Provide you built-in open source library for different screens. 10 | 11 | Library Reference @artsy/fresnel 12 | 13 | ## Usage 14 | 15 | ```js 16 | class App extends React.Component { 17 | render() { 18 | const { children, pendingTasks } = this.props; 19 | const loading = pendingTasks?.length; 20 | 21 | return ( 22 | <> 23 | 24 | {(!!loading) && } 25 | 26 |
27 | 28 | {children} 29 | 30 | 31 |

This is Render Example for 0-768 screen size

32 | {children} 33 |
34 | 35 | ); 36 | } 37 | } 38 | ``` 39 | -------------------------------------------------------------------------------- /docs/docs/extensions/client/seo.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## SEO Decorator 4 | 5 | Location: `base/features/decorators/withSEO` 6 | 7 | 8 | With SEO is a Decorator that can use for any component to simplify the using and heading headers when this component on screen.
9 | Headers automatic added and removed if the component is in or out the screen. 10 | 11 | 12 | ## Using Example 13 | 14 | ```JS 15 | import { withSEO } from '@base/features/base-decorator/withSEO'; 16 | ... 17 | 18 | @withSEO({ 19 | helmet: (props: Props) => { 20 | const { device } = props; 21 | return ( 22 | [ 23 | , 24 | , 25 | , 26 | , 27 | ] 28 | ); 29 | } 30 | }) 31 | class DeviceDetailsPage extends React.Component { 32 | render() { 33 | ... 34 | } 35 | } 36 | ``` 37 | -------------------------------------------------------------------------------- /docs/docs/extensions/permalinks.md: -------------------------------------------------------------------------------- 1 | # Permalinks 2 | 3 | Permalinks are a feature of the [Table of Contents][1] extension, which is part 4 | of the standard Markdown library. The extension inserts an anchor at the end of 5 | each headline, which makes it possible to directly link to a subpart of the 6 | document. 7 | 8 | [1]: https://pythonhosted.org/Markdown/extensions/toc.html 9 | 10 | ## Installation 11 | 12 | To enable permalinks, add the following to your `mkdocs.yml`: 13 | 14 | ``` yaml 15 | markdown_extensions: 16 | - toc(permalink=true) 17 | ``` 18 | 19 | This will add a link containing the paragraph symbol `¶` at the end of each 20 | headline (exactly like on the page you're currently viewing), which the 21 | Material theme will make appear on hover. In order to change the text of the 22 | permalink, a string can be passed, e.g.: 23 | 24 | ``` markdown 25 | markdown_extensions: 26 | - toc(permalink=Link) 27 | ``` 28 | 29 | ## Usage 30 | 31 | When enabled, permalinks are inserted automatically. 32 | -------------------------------------------------------------------------------- /docs/docs/extensions/server/config.md: -------------------------------------------------------------------------------- 1 | # Config 2 | 3 | Server configuration located on `server/src/config.js` 4 | 5 | ``` js 6 | const config = { 7 | sql : { 8 | db:'seq', 9 | user:'root', 10 | pass:'' 11 | }, 12 | mongo: { 13 | dbUrl: process.env.MONGO_URL || 'mongodb://127.0.0.1:27017/db' 14 | }, 15 | useMongo:true, 16 | useSql: false, 17 | JWT_SECRET:"YOUR_SMASHING_JWT_SECRET", 18 | server:{ 19 | port: process.env.PORT || 8080 20 | }, 21 | websocket:{ 22 | port: process.env.WS_PORT || 3030 23 | }, 24 | 25 | allowedActions: [ 26 | actions.FETCH_POSTS 27 | ] 28 | 29 | 30 | }; 31 | 32 | ``` 33 | 34 | 1. You can choose whether to use Relational DB or Non Relational such as MongoDB, change `useMongo` \ `useSql` according to your decisions. 35 | 2. `JWT_SECRET` used for Authorization Token generation. 36 | 3. `websocket` contain your websocket server configuration, we are using it for broadcasting actions on client side. amazing no? 37 | 4. `allowedActions` comes with the websocket, its contain what are the actions that the websocket is allowed to broadcast to the client. 38 | -------------------------------------------------------------------------------- /docs/docs/extensions/server/server.md: -------------------------------------------------------------------------------- 1 | # Server 2 | 3 | ## Based Technologies 4 | 5 | - Express 6 | - APIDoc 7 | - Mongoose 8 | - Sequelize 9 | 10 | 11 | 12 | ## Server Folder Structure 13 | 14 | . 15 | ├── server 16 | | ├── docs 17 | | ├── src 18 | | ├── api 19 | | ├── authentication 20 | | ├── global 21 | | ├── responses 22 | | ├── posts 23 | | ├── model 24 | | ├── responses 25 | | ├── index.js 26 | | ├── posts.controller.js 27 | | ├── middleware 28 | | ├── authenticate.js 29 | | ├── authenticate-sequelize.js 30 | | ├── config.js 31 | | ├── apidoc.json 32 | | ├── server.js -------------------------------------------------------------------------------- /docs/docs/getting-started.md: -------------------------------------------------------------------------------- 1 | 2 | ## Introduction 3 | 4 | !!! tip "How to read Harmony Documentation" 5 | 6 | Harmony Documentation built by steps to make it easy for you to get started and 7 | understand the full framework.
8 | Please following the `Next` button at the bottom of the page. 9 | 10 | Harmony is a boilerplate to enable fast on-boarding when it comes to developing web applications with the focus on React Redux and NodeJS. 11 | Harmony suggest new features and improve your flexibility by adding your customized features. 12 | 13 | Harmony Boilerplate focus on performance and Best Practices to build the most updated web application 14 | 15 | ## Installation 16 | 17 | Download The Harmony project 18 | 19 | Install Harmony 20 | ``` sh 21 | $ npm install 22 | ``` 23 | 24 | Start the Project 25 | ``` sh 26 | $ npm start 27 | ``` 28 | 29 | 30 | To use project Generators ( Generate Component etc ..) please install `gulp` globally 31 | ``` sh 32 | $ npm install gulp -g 33 | ``` 34 | 35 | ### Run the Project 36 | 37 | Run for Development 38 | ``` sh 39 | $ npm start 40 | ``` 41 | 42 | Run for Production 43 | ``` sh 44 | $ npm run build 45 | ``` 46 | 47 | ### Using Docker 48 | 49 | ``` sh 50 | $ docker build --no-cache -t harmony-sample-image . 51 | ``` 52 | 53 | To run it, do the following 54 | ``` sh 55 | $ docker run -d -p 80:80 harmony-sample-image 56 | ``` 57 | 58 | ## What next ? 59 | 60 | Congratulations, you start your first Harmony web app. 61 | Now go on and explore how to develop your next webapp easily with our feathers. 62 | 63 | -------------------------------------------------------------------------------- /docs/docs/images/Stav.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/docs/docs/images/Stav.jpeg -------------------------------------------------------------------------------- /docs/docs/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/docs/docs/images/favicon.ico -------------------------------------------------------------------------------- /docs/docs/images/flow-manager-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/docs/docs/images/flow-manager-diagram.png -------------------------------------------------------------------------------- /docs/docs/images/harmony-flow-data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/docs/docs/images/harmony-flow-data.png -------------------------------------------------------------------------------- /docs/docs/images/harmony-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/docs/docs/images/harmony-logo.png -------------------------------------------------------------------------------- /docs/docs/images/logos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/docs/docs/images/logos.png -------------------------------------------------------------------------------- /docs/docs/images/state-machine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/docs/docs/images/state-machine.png -------------------------------------------------------------------------------- /docs/docs/images/webpack-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/docs/docs/images/webpack-logo.png -------------------------------------------------------------------------------- /docs/docs/license.md: -------------------------------------------------------------------------------- 1 | # License 2 | 3 | **MIT License** 4 | 5 | Copyright © 2017 - 2020 Harmony Framework 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to 9 | deal in the Software without restriction, including without limitation the 10 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 11 | sell copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 23 | IN THE SOFTWARE. 24 | 25 | * Note - the copy right thing is only if there is copy right comment block in the code, there is no need to mention us or give any attribution. -------------------------------------------------------------------------------- /docs/docs/release-notes.md: -------------------------------------------------------------------------------- 1 | # Release notes 2 | 3 | ## Upgrading 4 | 5 | To upgrade harmony-boilerplate to the latest version, use npm: 6 | 7 | ``` sh 8 | npm update generator-harmony-boilerplate -g 9 | ``` 10 | 11 | -------------------------------------------------------------------------------- /docs/docs/team.md: -------------------------------------------------------------------------------- 1 | #Harmony Team 2 | 3 | 4 |
5 |
6 |
7 |
8 |

Ofir Attia

9 |
10 |
11 |
12 |
13 |
14 |

Refael Oknin

15 |
16 |
17 |
18 |
19 |
20 |

Stav Suisa

21 |
22 |
23 |
-------------------------------------------------------------------------------- /docs/site/assets/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/docs/site/assets/images/favicon.png -------------------------------------------------------------------------------- /docs/site/assets/javascripts/lunr/min/lunr.jp.min.js: -------------------------------------------------------------------------------- 1 | module.exports=require("./lunr.ja"); -------------------------------------------------------------------------------- /docs/site/assets/javascripts/lunr/min/lunr.multi.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(e.lunr)}(this,function(){return function(e){e.multiLanguage=function(){for(var t=Array.prototype.slice.call(arguments),i=t.join("-"),r="",n=[],s=[],p=0;p/sagas'; 4 | import { <%= actionNameUppercase %>Types } from 'actions/<%= actionName %>'; 5 | 6 | /* ------------- Export Redux ------------- */ 7 | export * from 'actions/<%= actionName %>/redux'; 8 | 9 | /* ------------- Export Sagas ------------- */ 10 | function* watchMySaga() { 11 | yield takeLatest(<%= actionNameUppercase %>Types.MY_SAGA, createSaga(Sagas.mySaga)); 12 | } 13 | 14 | // TODO: Do Not Forget to Add your new saga to index file 15 | export function* <%= actionName %>Saga() { 16 | yield all([ 17 | fork(watchMySaga) 18 | ]); 19 | } 20 | -------------------------------------------------------------------------------- /generator/templates/client/component-template: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { withLocalize, LocalizeContextProps } from 'react-localize-redux'; 3 | 4 | export type Props = { 5 | 6 | }; 7 | 8 | const <%= name %>: React.FC = (props: Props& LocalizeContextProps) => { 9 | return ( 10 |
11 | write here your own core component 12 |
13 | ); 14 | }; 15 | 16 | export default withLocalize(<%= name %>); 17 | -------------------------------------------------------------------------------- /generator/templates/client/container-template: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { LocalizeContextProps } from 'react-localize-redux'; 3 | import { baseConnect } from '@base/features/base-redux-react-connect'; 4 | import { ApplicationState } from 'actions'; 5 | // import { <%= className %>Actions, <%= classNameLowerCase %>Selector } from 'actions/redux/<%= classNameLowerCase %>'; 6 | 7 | export type Props = { 8 | 9 | }; 10 | 11 | export interface OwnProps extends Props, LocalizeContextProps { 12 | 13 | } 14 | 15 | export class <%= className %> extends React.Component { 16 | render() { 17 | return ( 18 |
19 | <%= className %> New Container 20 |
21 | ); 22 | } 23 | } 24 | 25 | export default baseConnect( 26 | <%= className %>, 27 | (state: ApplicationState) => { 28 | return { 29 | 30 | }; 31 | }, 32 | { 33 | 34 | } 35 | ); 36 | -------------------------------------------------------------------------------- /generator/templates/client/form-container-template: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { LocalizeContextProps } from 'react-localize-redux'; 3 | import { InjectedFormProps, Form, getFormValues, ConfigProps } from 'redux-form'; 4 | import { baseConnectForm } from '@base/features/base-redux-react-connect'; 5 | import { ApplicationState } from 'actions'; 6 | // import { <%= className %>Actions, <%= classNameLowerCase %>Selector } from 'actions/redux/<%= classNameLowerCase %>'; 7 | 8 | export type Props = { 9 | 10 | } & ConfigProps; 11 | 12 | type FormValues = { 13 | 14 | }; 15 | 16 | export interface OwnProps extends Props, LocalizeContextProps { 17 | formValues: (formName: string) => FormValues; 18 | } 19 | 20 | export class <%= className %> extends React.Component { 21 | render() { 22 | const { handleSubmit } = this.props; 23 | return ( 24 |
25 | 26 |
27 | ); 28 | } 29 | 30 | handleSubmit(formValues: FormValues) { 31 | // handle submit here 32 | } 33 | } 34 | 35 | export default baseConnectForm( 36 | <%= className %>, 37 | (state: ApplicationState) => { 38 | return { 39 | formValues: (formName: string) => getFormValues(formName)(state) 40 | } 41 | }, 42 | { 43 | 44 | }, 45 | { 46 | 47 | } 48 | ); 49 | -------------------------------------------------------------------------------- /generator/templates/client/interfaces-template: -------------------------------------------------------------------------------- 1 | import { Action } from 'redux'; 2 | 3 | /* ------------- Define Actions and State ------------- */ 4 | export interface <%= actionNameUppercase %>State { 5 | exampleData: string; 6 | } 7 | 8 | export enum TypesNames { 9 | SET_EXAMPLE = 'SET_EXAMPLE', 10 | MY_SAGA = 'MY_SAGA' 11 | } 12 | 13 | export declare function SetExampleFunction(exampleData: string): SetExampleAction; 14 | export declare function MySagaFunction(someData: string): MySagaAction; 15 | 16 | export interface ActionCreator { 17 | setExample: typeof SetExampleFunction; 18 | mySaga: typeof MySagaFunction; 19 | } 20 | 21 | export interface SetExampleAction extends Action { 22 | exampleData: string; 23 | } 24 | 25 | export interface MySagaAction extends Action { 26 | someData: string; 27 | } 28 | 29 | /* ------------- Define Any Interfaces ------------- */ 30 | export interface ResponseExample { 31 | name: string; 32 | } 33 | -------------------------------------------------------------------------------- /generator/templates/client/manager: -------------------------------------------------------------------------------- 1 | // Here you right all the "sdk" ( managers, utils etc .. ) 2 | // actually here is a function that are not saga and should return simple values without dispatch 3 | // for example function that get a and b and return a + b 4 | -------------------------------------------------------------------------------- /generator/templates/client/saga-template: -------------------------------------------------------------------------------- 1 | import { AxiosResponse } from 'axios'; 2 | import { call, put } from 'redux-saga/effects'; 3 | import api from 'requests'; 4 | import { <%= actionNameUppercase %>Actions } from 'actions/<%= actionName %>'; 5 | import { MySagaAction, ResponseExample } from 'actions/<%= actionName %>/interface'; 6 | 7 | export function* mySaga(action: MySagaAction) { 8 | const { someData } = action; 9 | const response: AxiosResponse = yield call(api.someApi, someData); 10 | 11 | yield put(<%= actionNameUppercase %>Actions.setExample(response.data.name)); 12 | } 13 | -------------------------------------------------------------------------------- /generator/templates/client/story: -------------------------------------------------------------------------------- 1 | /* eslint-disable react/jsx-props-no-spreading */ 2 | import React from 'react'; 3 | import { ComponentStory, Meta } from '@storybook/react'; 4 | import <%= nameUppercase %>, { Props as <%= nameUppercase %>Props } from './index'; 5 | 6 | export default { 7 | title: 'Design System/<%= storyTitle %>', 8 | component: <%= nameUppercase %>, 9 | argTypes: { 10 | 11 | }, 12 | parameters: { docs: { source: { type: 'dynamic', excludeDecorators: true } } } 13 | } as Meta; 14 | 15 | // eslint-disable-next-line react/jsx-props-no-spreading 16 | const Template: ComponentStory> = (args) => <<%= nameUppercase %> {...args} />; 17 | 18 | export const Default = Template.bind({}); 19 | Default.args = { 20 | 21 | } as <%= nameUppercase %>Props; 22 | -------------------------------------------------------------------------------- /generator/templates/client/story-container: -------------------------------------------------------------------------------- 1 | /* eslint-disable react/jsx-props-no-spreading */ 2 | import React from 'react'; 3 | import { baseConnect } from '@base/features/base-redux-react-connect'; 4 | import { ComponentStory, Meta } from '@storybook/react'; 5 | import { <%= nameUppercase %>, OwnProps as <%= nameUppercase %>Props } from './index'; 6 | 7 | export default { 8 | title: 'Design System/<%= storyTitle %>', 9 | component: (props: <%= nameUppercase %>Props) => (<<%= nameUppercase %> {...props} />), 10 | argTypes: { 11 | 12 | }, 13 | parameters: { docs: { source: { type: 'dynamic', excludeDecorators: true } } } 14 | } as Meta; 15 | 16 | const Template: ComponentStory> = (args) => { 17 | const <%= nameUppercase %>Container = baseConnectProps>( 18 | <%= nameUppercase %>, 19 | () => ({ 20 | ...args 21 | }) 22 | ); 23 | 24 | return <<%= nameUppercase %>Container {...args} />; 25 | }; 26 | 27 | export const Default = Template.bind({}); 28 | Default.args = { 29 | 30 | } as <%= nameUppercase %>Props; 31 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'ws-reconnect-js'; 2 | declare module 'uuid'; 3 | declare module 'guid'; 4 | declare module '*.jpg'; 5 | declare module 'lodash'; 6 | -------------------------------------------------------------------------------- /jest-puppeteer.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | launch: { 3 | headless: false 4 | }, 5 | } -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "roots": [ 3 | "/test/tests" 4 | ], 5 | "transform": { 6 | "^.+\\.tsx?$": "ts-jest" 7 | }, 8 | "testRegex": "(.*|(\\.|/)(test|spec))\\.tsx?$", 9 | "moduleFileExtensions": [ 10 | "ts", 11 | "tsx", 12 | "js", 13 | "jsx", 14 | "json", 15 | "node" 16 | ], 17 | "preset": "jest-puppeteer" 18 | } -------------------------------------------------------------------------------- /mobile-app/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | #intellij 4 | .idea 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | 10 | # Runtime data 11 | pids 12 | *.pid 13 | *.seed 14 | 15 | # Directory for instrumented libs generated by jscoverage/JSCover 16 | lib-cov 17 | 18 | # Coverage directory used by tools like istanbul 19 | coverage 20 | 21 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 22 | .grunt 23 | 24 | # node-waf configuration 25 | .lock-wscript 26 | 27 | # Compiled binary addons (http://nodejs.org/api/addons.html) 28 | build/Release 29 | 30 | # Dependency directory 31 | node_modules 32 | 33 | # Optional npm cache directory 34 | .npm 35 | 36 | # Optional REPL history 37 | .node_repl_history 38 | 39 | # Cordova platforms and plugins 40 | /plugins 41 | /platforms 42 | 43 | # Webpack bundle 44 | /www 45 | 46 | 47 | -------------------------------------------------------------------------------- /mobile-app/config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | const path = require('path'); 5 | const et = require('elementtree'); 6 | 7 | const ENV = process.env.NODE_ENV; 8 | const src = { 9 | android: (ENV === 'development') ? 'http://10.0.2.2:8082/' : 'index.html', 10 | ios: (ENV === 'development') ? 'http://localhost:8082/' : 'index.html', 11 | }; 12 | const config = path.resolve(__dirname, "config.xml"); 13 | 14 | try { 15 | var configXML = new et.ElementTree( 16 | et.XML( 17 | fs.readFileSync(config, 'utf-8') 18 | ) 19 | ); 20 | configXML.getroot()._children.forEach(function(el) { 21 | if (el.tag === 'platform') { 22 | if (el.attrib.name === 'android' || el.attrib.name === 'ios') { 23 | el._children.forEach(function(child) { 24 | if (child.tag === 'content') { 25 | console.log('Setting ' + el.attrib.name + ' src to ' + src[el.attrib.name]) 26 | child.attrib.src = src[el.attrib.name]; 27 | } 28 | }); 29 | } 30 | } 31 | }); 32 | fs.writeFileSync(config, configXML.write({indent: 4}), 'utf-8'); 33 | 34 | } catch (err) { 35 | console.error('ERROR: Could not replace content src in: ' + config, err); 36 | process.exit(1); 37 | } 38 | -------------------------------------------------------------------------------- /mobile-app/gulpfile.js: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp'); 2 | const execShPromise = require("exec-sh").promise; 3 | const fs = require('fs'); 4 | 5 | const platform = process.env.npm_config_platform; 6 | 7 | console.log('platform ', platform); 8 | 9 | gulp.task('createApp', () => { 10 | return gulp.src(['../dist/**/*']).pipe(gulp.dest('www')); 11 | }); 12 | 13 | gulp.task('install', () => { 14 | return new Promise(async (resolve, reject) => { 15 | if (!platform) reject('Platform Argument is Missing - Did you miss to send --platform=(android/ios) ?'); 16 | 17 | const addPlatform = (platform === 'android') ? 'cordova platform add cordova-android@^9.0.0' : 'cordova platform add cordova-ios@^6.1.1'; 18 | 19 | try { 20 | if(!fs.existsSync('www')) { 21 | fs.mkdirSync('www'); 22 | } 23 | 24 | console.log('npm i cordova@~10.0.0 -g'); 25 | await execShPromise('npm i cordova@~10.0.0 -g'); 26 | 27 | console.log('npm install'); 28 | await execShPromise('npm install'); 29 | 30 | try { 31 | console.log(addPlatform); 32 | await execShPromise(addPlatform); 33 | } catch (e) { 34 | console.log(e); 35 | } 36 | 37 | console.log(`cordova build ${platform}`); 38 | await execShPromise(`cordova build ${platform}`); 39 | 40 | resolve(); 41 | } catch (e) { 42 | reject(e); 43 | } 44 | }); 45 | }); 46 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/android.json: -------------------------------------------------------------------------------- 1 | { 2 | "prepare_queue": { 3 | "installed": [], 4 | "uninstalled": [] 5 | }, 6 | "config_munge": { 7 | "files": {} 8 | }, 9 | "installed_plugins": { 10 | "cordova-plugin-ionic-webview": { 11 | "PACKAGE_NAME": "com.attia" 12 | }, 13 | "cordova-plugin-statusbar": { 14 | "PACKAGE_NAME": "com.attia" 15 | }, 16 | "cordova-plugin-whitelist": { 17 | "PACKAGE_NAME": "com.attia" 18 | } 19 | }, 20 | "dependent_plugins": {} 21 | } 22 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/.appveyor.yml: -------------------------------------------------------------------------------- 1 | # appveyor file 2 | # http://www.appveyor.com/docs/appveyor-yml 3 | 4 | max_jobs: 1 5 | 6 | shallow_clone: true 7 | 8 | init: 9 | - git config --global core.autocrlf true 10 | 11 | image: 12 | - Visual Studio 2017 13 | 14 | environment: 15 | matrix: 16 | - nodejs_version: "10" 17 | - nodejs_version: "12" 18 | 19 | platform: 20 | - x86 21 | - x64 22 | 23 | install: 24 | - ps: Install-Product node $env:nodejs_version 25 | - node --version 26 | - npm install -g cordova-paramedic@https://github.com/apache/cordova-paramedic.git 27 | - npm install -g cordova 28 | - npm install 29 | 30 | build: off 31 | 32 | test_script: 33 | - cordova-paramedic --config pr\windows-10-store --plugin . --justBuild 34 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/.asf.yaml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | notifications: 19 | commits: commits@cordova.apache.org 20 | issues: issues@cordova.apache.org 21 | pullrequests_status: issues@cordova.apache.org 22 | pullrequests_comment: issues@cordova.apache.org 23 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/.eslintrc.yml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | root: true 19 | extends: '@cordova/eslint-config/browser' 20 | 21 | overrides: 22 | - files: [tests/**/*.js] 23 | extends: '@cordova/eslint-config/node-tests' 24 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/.gitattributes: -------------------------------------------------------------------------------- 1 | * text eol=lf 2 | 3 | # 4 | ## These files are binary and should be left untouched 5 | # 6 | 7 | # (binary is a macro for -text -diff) 8 | *.png binary 9 | *.jpg binary 10 | *.jpeg binary 11 | *.gif binary 12 | *.ico binary 13 | *.mov binary 14 | *.mp4 binary 15 | *.mp3 binary 16 | *.flv binary 17 | *.fla binary 18 | *.swf binary 19 | *.gz binary 20 | *.zip binary 21 | *.7z binary 22 | *.ttf binary 23 | *.eot binary 24 | *.woff binary 25 | *.pyc binary 26 | *.pdf binary -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | ### Issue Type 7 | 8 | 9 | - [ ] Bug Report 10 | - [ ] Feature Request 11 | - [ ] Support Question 12 | 13 | ## Description 14 | 15 | ## Information 16 | 17 | 18 | ### Command or Code 19 | 20 | 21 | ### Environment, Platform, Device 22 | 23 | 24 | 25 | 26 | ### Version information 27 | 34 | 35 | 36 | 37 | ## Checklist 38 | 39 | 40 | - [ ] I searched for already existing GitHub issues about this 41 | - [ ] I updated all Cordova tooling to their most recent version 42 | - [ ] I included all the necessary information above 43 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/.github/ISSUE_TEMPLATE/BUG_REPORT.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🐛 Bug Report 3 | about: If something isn't working as expected. 4 | 5 | --- 6 | 7 | # Bug Report 8 | 9 | ## Problem 10 | 11 | ### What is expected to happen? 12 | 13 | 14 | 15 | ### What does actually happen? 16 | 17 | 18 | 19 | ## Information 20 | 21 | 22 | 23 | 24 | ### Command or Code 25 | 26 | 27 | 28 | 29 | ### Environment, Platform, Device 30 | 31 | 32 | 33 | 34 | ### Version information 35 | 42 | 43 | 44 | 45 | ## Checklist 46 | 47 | 48 | - [ ] I searched for existing GitHub issues 49 | - [ ] I updated all Cordova tooling to most recent version 50 | - [ ] I included all the necessary information above 51 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🚀 Feature Request 3 | about: A suggestion for a new functionality 4 | 5 | --- 6 | 7 | # Feature Request 8 | 9 | ## Motivation Behind Feature 10 | 11 | 12 | 13 | 14 | ## Feature Description 15 | 20 | 21 | 22 | 23 | ## Alternatives or Workarounds 24 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/.github/ISSUE_TEMPLATE/SUPPORT_QUESTION.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 💬 Support Question 3 | about: If you have a question, please check out our Slack or StackOverflow! 4 | 5 | --- 6 | 7 | 8 | 9 | Apache Cordova uses GitHub Issues as a feature request and bug tracker _only_. 10 | For usage and support questions, please check out the resources below. Thanks! 11 | 12 | --- 13 | 14 | You can get answers to your usage and support questions about **Apache Cordova** on: 15 | 16 | * Slack Community Chat: https://cordova.slack.com (you can sign-up at http://slack.cordova.io/) 17 | * StackOverflow: https://stackoverflow.com/questions/tagged/cordova using the tag `cordova` 18 | 19 | --- 20 | 21 | If you are using a tool that uses Cordova internally, like e.g. Ionic, check their support channels: 22 | 23 | * **Ionic Framework** 24 | * [Ionic Community Forum](https://forum.ionicframework.com/) 25 | * [Ionic Worldwide Slack](https://ionicworldwide.herokuapp.com/) 26 | * **PhoneGap** 27 | * [PhoneGap Developer Community](https://forums.adobe.com/community/phonegap) 28 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 8 | 9 | ### Platforms affected 10 | 11 | 12 | 13 | ### Motivation and Context 14 | 15 | 16 | 17 | 18 | 19 | ### Description 20 | 21 | 22 | 23 | 24 | ### Testing 25 | 26 | 27 | 28 | 29 | ### Checklist 30 | 31 | - [ ] I've run the tests to see all new and existing tests pass 32 | - [ ] I added automated test coverage as appropriate for this change 33 | - [ ] Commit is prefixed with `(platform)` if this change only applies to one platform (e.g. `(android)`) 34 | - [ ] If this Pull Request resolves an issue, I linked to the issue in the text above (and used the correct [keyword to close issues using keywords](https://help.github.com/articles/closing-issues-using-keywords/)) 35 | - [ ] I've updated the documentation if necessary 36 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/.gitignore: -------------------------------------------------------------------------------- 1 | #If ignorance is bliss, then somebody knock the smile off my face 2 | 3 | *.csproj.user 4 | *.suo 5 | *.cache 6 | Thumbs.db 7 | *.DS_Store 8 | 9 | *.bak 10 | *.cache 11 | *.log 12 | *.swp 13 | *.user 14 | *.idea 15 | 16 | node_modules 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/.npmignore: -------------------------------------------------------------------------------- 1 | .* 2 | appveyor.yml 3 | tests 4 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | 21 | 22 | # Contributing to Apache Cordova 23 | 24 | Anyone can contribute to Cordova. And we need your contributions. 25 | 26 | There are multiple ways to contribute: report bugs, improve the docs, and 27 | contribute code. 28 | 29 | For instructions on this, start with the 30 | [contribution overview](http://cordova.apache.org/contribute/). 31 | 32 | The details are explained there, but the important items are: 33 | - Check for Github issues that corresponds to your contribution and link or create them if necessary. 34 | - Run the tests so your patch doesn't break existing functionality. 35 | 36 | We look forward to your contributions! 37 | 38 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/NOTICE: -------------------------------------------------------------------------------- 1 | Apache Cordova 2 | Copyright 2012 The Apache Software Foundation 3 | 4 | This product includes software developed at 5 | The Apache Software Foundation (http://www.apache.org/). 6 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cordova-plugin-inappbrowser", 3 | "version": "4.1.0", 4 | "description": "Cordova InAppBrowser Plugin", 5 | "types": "./types/index.d.ts", 6 | "cordova": { 7 | "id": "cordova-plugin-inappbrowser", 8 | "platforms": [ 9 | "android", 10 | "browser", 11 | "ios", 12 | "osx", 13 | "windows" 14 | ] 15 | }, 16 | "repository": "github:apache/cordova-plugin-inappbrowser", 17 | "bugs": "https://github.com/apache/cordova-plugin-inappbrowser/issues", 18 | "keywords": [ 19 | "cordova", 20 | "in", 21 | "app", 22 | "browser", 23 | "inappbrowser", 24 | "ecosystem:cordova", 25 | "cordova-android", 26 | "cordova-browser", 27 | "cordova-ios", 28 | "cordova-osx", 29 | "cordova-windows" 30 | ], 31 | "scripts": { 32 | "test": "npm run lint", 33 | "lint": "eslint ." 34 | }, 35 | "engines": { 36 | "cordovaDependencies": { 37 | "0.2.3": { 38 | "cordova": ">=3.1.0" 39 | }, 40 | "4.0.0": { 41 | "cordova": ">=3.1.0", 42 | "cordova-ios": ">=4.0.0" 43 | }, 44 | "5.0.0": { 45 | "cordova": ">100" 46 | } 47 | } 48 | }, 49 | "author": "Apache Software Foundation", 50 | "license": "Apache-2.0", 51 | "devDependencies": { 52 | "@cordova/eslint-config": "^3.0.0" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-hdpi/ic_action_next_item.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-hdpi/ic_action_next_item.png -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-hdpi/ic_action_previous_item.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-hdpi/ic_action_previous_item.png -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-hdpi/ic_action_remove.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-hdpi/ic_action_remove.png -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-mdpi/ic_action_next_item.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-mdpi/ic_action_next_item.png -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-mdpi/ic_action_previous_item.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-mdpi/ic_action_previous_item.png -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-mdpi/ic_action_remove.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-mdpi/ic_action_remove.png -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xhdpi/ic_action_next_item.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xhdpi/ic_action_next_item.png -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xhdpi/ic_action_previous_item.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xhdpi/ic_action_previous_item.png -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xhdpi/ic_action_remove.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xhdpi/ic_action_remove.png -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xxhdpi/ic_action_next_item.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xxhdpi/ic_action_next_item.png -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xxhdpi/ic_action_previous_item.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xxhdpi/ic_action_previous_item.png -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xxhdpi/ic_action_remove.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xxhdpi/ic_action_remove.png -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowserNavigationController.h: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed to the Apache Software Foundation (ASF) under one 3 | or more contributor license agreements. See the NOTICE file 4 | distributed with this work for additional information 5 | regarding copyright ownership. The ASF licenses this file 6 | to you under the Apache License, Version 2.0 (the 7 | "License"); you may not use this file except in compliance 8 | with the License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | KIND, either express or implied. See the License for the 16 | specific language governing permissions and limitations 17 | under the License. 18 | */ 19 | 20 | #import 21 | 22 | 23 | @interface CDVInAppBrowserNavigationController : UINavigationController 24 | 25 | @property (nonatomic, weak) id orientationDelegate; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/src/ios/CDVWKInAppBrowserUIDelegate.h: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed to the Apache Software Foundation (ASF) under one 3 | or more contributor license agreements. See the NOTICE file 4 | distributed with this work for additional information 5 | regarding copyright ownership. The ASF licenses this file 6 | to you under the Apache License, Version 2.0 (the 7 | "License"); you may not use this file except in compliance 8 | with the License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | KIND, either express or implied. See the License for the 16 | specific language governing permissions and limitations 17 | under the License. 18 | */ 19 | 20 | #import 21 | 22 | @interface CDVWKInAppBrowserUIDelegate : NSObject { 23 | @private 24 | UIViewController* _viewController; 25 | } 26 | 27 | @property (nonatomic, copy) NSString* title; 28 | 29 | - (instancetype)initWithTitle:(NSString*)title; 30 | -(void) setViewController:(UIViewController*) viewController; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/src/osx/CDVInAppBrowser.h: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed to the Apache Software Foundation (ASF) under one 3 | or more contributor license agreements. See the NOTICE file 4 | distributed with this work for additional information 5 | regarding copyright ownership. The ASF licenses this file 6 | to you under the Apache License, Version 2.0 (the 7 | "License"); you may not use this file except in compliance 8 | with the License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | KIND, either express or implied. See the License for the 16 | specific language governing permissions and limitations 17 | under the License. 18 | */ 19 | 20 | #import 21 | 22 | @interface CDVInAppBrowser : CDVPlugin { 23 | } 24 | 25 | @property (nonatomic, copy) NSString* callbackId; 26 | 27 | - (void)open:(CDVInvokedUrlCommand*)command; 28 | 29 | @end 30 | 31 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/tests/.eslintrc.yml: -------------------------------------------------------------------------------- 1 | env: 2 | jasmine: true -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/tests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cordova-plugin-inappbrowser-tests", 3 | "version": "4.1.0", 4 | "description": "", 5 | "cordova": { 6 | "id": "cordova-plugin-inappbrowser-tests", 7 | "platforms": [] 8 | }, 9 | "keywords": [ 10 | "ecosystem:cordova" 11 | ], 12 | "author": "", 13 | "license": "Apache-2.0" 14 | } 15 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/tests/resources/inject.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | #style-update-file { 20 | display: block !important; 21 | } 22 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/tests/resources/inject.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | var d = document.getElementById('header'); 21 | d.innerHTML = 'Script file successfully injected'; 22 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/tests/resources/local.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/harmony-plugins/plugins/cordova-plugin-inappbrowser/tests/resources/local.pdf -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-ionic-webview/.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | aliases: 4 | - &restore-cache 5 | keys: 6 | - dependency-cache-{{ checksum "package.json" }}-1 7 | 8 | - &save-cache 9 | key: dependency-cache-{{ checksum "package.json" }}-1 10 | paths: 11 | - node_modules 12 | 13 | defaults: &defaults 14 | docker: 15 | - image: circleci/node:10 16 | working_directory: /tmp/workspace 17 | 18 | jobs: 19 | build: 20 | <<: *defaults 21 | steps: 22 | - checkout 23 | - restore_cache: *restore-cache 24 | - run: npm install 25 | - save_cache: *save-cache 26 | - persist_to_workspace: 27 | root: /tmp/workspace 28 | paths: 29 | - "*" 30 | 31 | deploy: 32 | <<: *defaults 33 | environment: 34 | GIT_AUTHOR_NAME: Ionitron 35 | GIT_AUTHOR_EMAIL: hi@ionicframework.com 36 | GIT_COMMITTER_NAME: Ionitron 37 | GIT_COMMITTER_EMAIL: hi@ionicframework.com 38 | steps: 39 | - add_ssh_keys: 40 | fingerprints: 41 | - "ae:6d:3a:f1:cf:39:e1:94:6e:22:2a:9f:54:f9:b0:1b" # ionitron user key 42 | - checkout 43 | - attach_workspace: 44 | at: /tmp/workspace 45 | - run: npx semantic-release 46 | 47 | 48 | workflows: 49 | version: 2 50 | build: 51 | jobs: 52 | - build 53 | - deploy: 54 | requires: [build] 55 | filters: 56 | branches: 57 | only: stable 58 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-ionic-webview/src/android/com/ionicframework/cordova/webview/Common.java: -------------------------------------------------------------------------------- 1 | package com.ionicframework.cordova.webview; 2 | 3 | import android.content.res.AssetManager; 4 | 5 | public class Common { 6 | public static AssetManager assetManager = null; 7 | } 8 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-ionic-webview/src/ios/CDVWKProcessPoolFactory.h: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed to the Apache Software Foundation (ASF) under one 3 | or more contributor license agreements. See the NOTICE file 4 | distributed with this work for additional information 5 | regarding copyright ownership. The ASF licenses this file 6 | to you under the Apache License, Version 2.0 (the 7 | "License"); you may not use this file except in compliance 8 | with the License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | KIND, either express or implied. See the License for the 16 | specific language governing permissions and limitations 17 | under the License. 18 | */ 19 | 20 | #import 21 | 22 | @interface CDVWKProcessPoolFactory : NSObject 23 | @property (nonatomic, retain) WKProcessPool* sharedPool; 24 | 25 | +(instancetype) sharedFactory; 26 | -(WKProcessPool*) sharedProcessPool; 27 | @end 28 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-ionic-webview/src/ios/CDVWKWebViewEngine.h: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed to the Apache Software Foundation (ASF) under one 3 | or more contributor license agreements. See the NOTICE file 4 | distributed with this work for additional information 5 | regarding copyright ownership. The ASF licenses this file 6 | to you under the Apache License, Version 2.0 (the 7 | "License"); you may not use this file except in compliance 8 | with the License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | KIND, either express or implied. See the License for the 16 | specific language governing permissions and limitations 17 | under the License. 18 | */ 19 | 20 | #import 21 | #import 22 | 23 | @interface CDVWKWebViewEngine : CDVPlugin 24 | 25 | @property (nonatomic, strong, readonly) id uiDelegate; 26 | @property (nonatomic, strong) NSString * basePath; 27 | 28 | -(void)setServerBasePath:(CDVInvokedUrlCommand*)command; 29 | -(void)getServerBasePath:(CDVInvokedUrlCommand*)command; 30 | -(void)persistServerBasePath:(CDVInvokedUrlCommand*)command; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-ionic-webview/src/ios/CDVWKWebViewUIDelegate.h: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed to the Apache Software Foundation (ASF) under one 3 | or more contributor license agreements. See the NOTICE file 4 | distributed with this work for additional information 5 | regarding copyright ownership. The ASF licenses this file 6 | to you under the Apache License, Version 2.0 (the 7 | "License"); you may not use this file except in compliance 8 | with the License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | KIND, either express or implied. See the License for the 16 | specific language governing permissions and limitations 17 | under the License. 18 | */ 19 | 20 | #import 21 | 22 | @interface CDVWKWebViewUIDelegate : NSObject 23 | 24 | @property (nonatomic, copy) NSString* title; 25 | 26 | - (instancetype)initWithTitle:(NSString*)title; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-ionic-webview/src/ios/IONAssetHandler.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface IONAssetHandler : NSObject 5 | 6 | @property (nonatomic, strong) NSString * basePath; 7 | @property (nonatomic, strong) NSString * scheme; 8 | @property (nonatomic, strong) NSString * customEntryPoint; 9 | 10 | -(void)setAssetPath:(NSString *)assetPath; 11 | -(void)updateBasePath:(NSString *)cordovaDataDirectoryUpdateDir; 12 | 13 | - (instancetype)initWithBasePath:(NSString *)basePath andScheme:(NSString *)scheme andCustomEntryPoint:(NSString *)customEntryPoint; 14 | 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-ionic-webview/src/ios/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Niklas von Hertzen 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-ionic-webview/src/ios/wk-plugin.js: -------------------------------------------------------------------------------- 1 | 2 | (function _wk_plugin() { 3 | // Check if we are running in WKWebView 4 | if (!window.webkit || !window.webkit.messageHandlers) { 5 | return; 6 | } 7 | 8 | // Initialize Ionic 9 | window.Ionic = window.Ionic || {}; 10 | 11 | var stopScrollHandler = window.webkit.messageHandlers.stopScroll; 12 | if (!stopScrollHandler) { 13 | console.error('Can not find stopScroll handler'); 14 | return; 15 | } 16 | 17 | var stopScrollFunc = null; 18 | var stopScroll = { 19 | stop: function stop(callback) { 20 | if (!stopScrollFunc) { 21 | stopScrollFunc = callback; 22 | stopScrollHandler.postMessage(''); 23 | } 24 | }, 25 | fire: function fire() { 26 | stopScrollFunc && stopScrollFunc(); 27 | stopScrollFunc = null; 28 | }, 29 | cancel: function cancel() { 30 | stopScrollFunc = null; 31 | } 32 | }; 33 | 34 | window.Ionic.StopScroll = stopScroll; 35 | // deprecated 36 | window.IonicStopScroll = stopScroll; 37 | 38 | console.debug("Ionic Stop Scroll injected!"); 39 | })(); 40 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-ionic-webview/src/www/util.js: -------------------------------------------------------------------------------- 1 | var exec = require('cordova/exec'); 2 | 3 | var WebView = { 4 | convertFileSrc: function(url) { 5 | if (!url) { 6 | return url; 7 | } 8 | if (url.indexOf('/')===0) { 9 | return window.WEBVIEW_SERVER_URL + '/_app_file_' + url; 10 | } 11 | if (url.indexOf('file://')===0) { 12 | return window.WEBVIEW_SERVER_URL + url.replace('file://', '/_app_file_'); 13 | } 14 | if (url.indexOf('content://')===0) { 15 | return window.WEBVIEW_SERVER_URL + url.replace('content:/', '/_app_content_'); 16 | } 17 | return url; 18 | }, 19 | setServerBasePath: function(path) { 20 | exec(null, null, 'IonicWebView', 'setServerBasePath', [path]); 21 | }, 22 | getServerBasePath: function(callback) { 23 | exec(callback, null, 'IonicWebView', 'getServerBasePath', []); 24 | }, 25 | persistServerBasePath: function() { 26 | exec(null, null, 'IonicWebView', 'persistServerBasePath', []); 27 | }, 28 | getUserConfiguration: function(callback) { 29 | exec(callback, null, 'IonicWebView', 'getUserConfiguration', []); 30 | } 31 | } 32 | 33 | module.exports = WebView; 34 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-native-spinner/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2016 Aleksandr Filatov aka greybax 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a 4 | copy of this software and associated documentation files (the "Software"), 5 | to deal in the Software without restriction, including without limitation 6 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | and/or sell copies of the Software, and to permit persons to whom the 8 | Software is furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 14 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 15 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 16 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 17 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 18 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 19 | THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-native-spinner/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cordova-plugin-native-spinner", 3 | "version": "1.1.3", 4 | "description": "A Cordova plugin for showing a progress indicator based on Paldom/SpinnerDialog", 5 | "author": "Aleksandr Filatov", 6 | "license": "MIT", 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/greybax/cordova-plugin-native-spinner.git" 10 | }, 11 | "cordova": { 12 | "id": "cordova-plugin-native-spinner", 13 | "platforms": [ 14 | "android", 15 | "ios", 16 | "wp8", 17 | "windows" 18 | ] 19 | }, 20 | "keywords": [ 21 | "cordova", 22 | "spinner", 23 | "dialog", 24 | "spinnerdialog", 25 | "progress", 26 | "indicator", 27 | "native", 28 | "progressindicator", 29 | "plugin", 30 | "notification", 31 | "ecosystem:cordova", 32 | "cordova-android", 33 | "cordova-ios", 34 | "cordova-wp8", 35 | "cordova-windows", 36 | "android", 37 | "ios", 38 | "wp8", 39 | "windows", 40 | "10", 41 | "8.1", 42 | "phone" 43 | ], 44 | "engines": [ 45 | { 46 | "name": "cordova", 47 | "version": ">=3.4.0" 48 | } 49 | ], 50 | "bugs": { 51 | "url": "https://github.com/greybax/cordova-plugin-native-spinner/issues" 52 | } 53 | } -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-native-spinner/src/ios/CDVSpinnerDialog.h: -------------------------------------------------------------------------------- 1 | // 2 | // CDVSpinnerDialog.h 3 | // 4 | // Created by Domonkos Pál on 2014.01.27.. 5 | // 6 | // 7 | 8 | #import 9 | 10 | @interface CDVSpinnerDialog : CDVPlugin 11 | 12 | - (void)show:(CDVInvokedUrlCommand*)command; 13 | - (void)hide:(CDVInvokedUrlCommand*)command; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-native-spinner/www/SpinnerDialog.js: -------------------------------------------------------------------------------- 1 | var exec = require('cordova/exec'); 2 | 3 | module.exports = { 4 | show: function (title, message, cancelCallback, iosOptions) { 5 | if (cancelCallback == true && typeof cancelCallback !== "function") { 6 | cancelCallback = function () { }; 7 | } 8 | var isPlatformIos = (navigator.userAgent.match(/iPad/i)) == "iPad" || (navigator.userAgent.match(/iPhone/i)) == "iPhone" ? true : false; 9 | var params = [title, message, !!cancelCallback]; 10 | if (isPlatformIos) { 11 | if (typeof iosOptions != "object") { 12 | iosOptions = { overlayOpacity: 0.35, textColorRed: 1, textColorGreen: 1, textColorBlue: 1 } 13 | } 14 | params = params.concat([(iosOptions.overlayOpacity || 0.35), (iosOptions.textColorRed || 1), (iosOptions.textColorGreen || 1), (iosOptions.textColorBlue || 1)]) 15 | } 16 | cordova.exec(cancelCallback, null, 'SpinnerDialog', 'show', params); 17 | }, 18 | hide: function (wpStatusbar, success, fail) { 19 | cordova.exec(success, fail, 'SpinnerDialog', 'hide', [wpStatusbar]); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-splashscreen/.appveyor.yml: -------------------------------------------------------------------------------- 1 | # appveyor file 2 | # http://www.appveyor.com/docs/appveyor-yml 3 | 4 | max_jobs: 1 5 | 6 | shallow_clone: true 7 | 8 | init: 9 | - git config --global core.autocrlf true 10 | 11 | image: 12 | - Visual Studio 2017 13 | 14 | environment: 15 | matrix: 16 | - nodejs_version: "10" 17 | - nodejs_version: "12" 18 | - nodejs_version: "14" 19 | 20 | platform: 21 | - x86 22 | - x64 23 | 24 | install: 25 | - ps: Install-Product node $env:nodejs_version 26 | - node --version 27 | - npm install -g cordova-paramedic@https://github.com/apache/cordova-paramedic.git 28 | - npm install -g cordova 29 | 30 | build: off 31 | 32 | test_script: 33 | - cordova-paramedic --config pr\windows-10-store --plugin . --justBuild 34 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-splashscreen/.asf.yaml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | notifications: 19 | commits: commits@cordova.apache.org 20 | issues: issues@cordova.apache.org 21 | pullrequests_status: issues@cordova.apache.org 22 | pullrequests_comment: issues@cordova.apache.org 23 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-splashscreen/.eslintrc.yml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | root: true 19 | extends: '@cordova/eslint-config/browser' 20 | 21 | overrides: 22 | - files: [tests/**/*.js] 23 | extends: '@cordova/eslint-config/node-tests' 24 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-splashscreen/.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | ### Issue Type 7 | 8 | 9 | - [ ] Bug Report 10 | - [ ] Feature Request 11 | - [ ] Support Question 12 | 13 | ## Description 14 | 15 | ## Information 16 | 17 | 18 | ### Command or Code 19 | 20 | 21 | ### Environment, Platform, Device 22 | 23 | 24 | 25 | 26 | ### Version information 27 | 34 | 35 | 36 | 37 | ## Checklist 38 | 39 | 40 | - [ ] I searched for already existing GitHub issues about this 41 | - [ ] I updated all Cordova tooling to their most recent version 42 | - [ ] I included all the necessary information above 43 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-splashscreen/.github/ISSUE_TEMPLATE/BUG_REPORT.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🐛 Bug Report 3 | about: If something isn't working as expected. 4 | 5 | --- 6 | 7 | # Bug Report 8 | 9 | ## Problem 10 | 11 | ### What is expected to happen? 12 | 13 | 14 | 15 | ### What does actually happen? 16 | 17 | 18 | 19 | ## Information 20 | 21 | 22 | 23 | 24 | ### Command or Code 25 | 26 | 27 | 28 | 29 | ### Environment, Platform, Device 30 | 31 | 32 | 33 | 34 | ### Version information 35 | 42 | 43 | 44 | 45 | ## Checklist 46 | 47 | 48 | - [ ] I searched for existing GitHub issues 49 | - [ ] I updated all Cordova tooling to most recent version 50 | - [ ] I included all the necessary information above 51 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-splashscreen/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🚀 Feature Request 3 | about: A suggestion for a new functionality 4 | 5 | --- 6 | 7 | # Feature Request 8 | 9 | ## Motivation Behind Feature 10 | 11 | 12 | 13 | 14 | ## Feature Description 15 | 20 | 21 | 22 | 23 | ## Alternatives or Workarounds 24 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-splashscreen/.github/ISSUE_TEMPLATE/SUPPORT_QUESTION.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 💬 Support Question 3 | about: If you have a question, please check out our Slack or StackOverflow! 4 | 5 | --- 6 | 7 | 8 | 9 | Apache Cordova uses GitHub Issues as a feature request and bug tracker _only_. 10 | For usage and support questions, please check out the resources below. Thanks! 11 | 12 | --- 13 | 14 | You can get answers to your usage and support questions about **Apache Cordova** on: 15 | 16 | * Slack Community Chat: https://cordova.slack.com (you can sign-up at http://slack.cordova.io/) 17 | * StackOverflow: https://stackoverflow.com/questions/tagged/cordova using the tag `cordova` 18 | 19 | --- 20 | 21 | If you are using a tool that uses Cordova internally, like e.g. Ionic, check their support channels: 22 | 23 | * **Ionic Framework** 24 | * [Ionic Community Forum](https://forum.ionicframework.com/) 25 | * [Ionic Worldwide Slack](https://ionicworldwide.herokuapp.com/) 26 | * **PhoneGap** 27 | * [PhoneGap Developer Community](https://forums.adobe.com/community/phonegap) 28 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-splashscreen/.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 8 | 9 | ### Platforms affected 10 | 11 | 12 | 13 | ### Motivation and Context 14 | 15 | 16 | 17 | 18 | 19 | ### Description 20 | 21 | 22 | 23 | 24 | ### Testing 25 | 26 | 27 | 28 | 29 | ### Checklist 30 | 31 | - [ ] I've run the tests to see all new and existing tests pass 32 | - [ ] I added automated test coverage as appropriate for this change 33 | - [ ] Commit is prefixed with `(platform)` if this change only applies to one platform (e.g. `(android)`) 34 | - [ ] If this Pull Request resolves an issue, I linked to the issue in the text above (and used the correct [keyword to close issues using keywords](https://help.github.com/articles/closing-issues-using-keywords/)) 35 | - [ ] I've updated the documentation if necessary 36 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-splashscreen/.gitignore: -------------------------------------------------------------------------------- 1 | #If ignorance is bliss, then somebody knock the smile off my face 2 | 3 | *.csproj.user 4 | *.suo 5 | *.cache 6 | Thumbs.db 7 | *.DS_Store 8 | 9 | *.bak 10 | *.cache 11 | *.log 12 | *.swp 13 | *.user 14 | 15 | node_modules 16 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-splashscreen/.npmignore: -------------------------------------------------------------------------------- 1 | .* 2 | appveyor.yml 3 | tests 4 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-splashscreen/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | 21 | 22 | # Contributing to Apache Cordova 23 | 24 | Anyone can contribute to Cordova. And we need your contributions. 25 | 26 | There are multiple ways to contribute: report bugs, improve the docs, and 27 | contribute code. 28 | 29 | For instructions on this, start with the 30 | [contribution overview](http://cordova.apache.org/contribute/). 31 | 32 | The details are explained there, but the important items are: 33 | - Check for Github issues that corresponds to your contribution and link or create them if necessary. 34 | - Run the tests so your patch doesn't break existing functionality. 35 | 36 | We look forward to your contributions! 37 | 38 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-splashscreen/NOTICE: -------------------------------------------------------------------------------- 1 | Apache Cordova 2 | Copyright 2012 The Apache Software Foundation 3 | 4 | This product includes software developed at 5 | The Apache Software Foundation (http://www.apache.org/). 6 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-splashscreen/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cordova-plugin-splashscreen", 3 | "version": "6.0.1-dev", 4 | "description": "Cordova Splashscreen Plugin", 5 | "types": "./types/index.d.ts", 6 | "cordova": { 7 | "id": "cordova-plugin-splashscreen", 8 | "platforms": [ 9 | "android", 10 | "windows", 11 | "browser" 12 | ] 13 | }, 14 | "repository": "github:apache/cordova-plugin-splashscreen", 15 | "bugs": "https://github.com/apache/cordova-plugin-splashscreen/issues", 16 | "keywords": [ 17 | "cordova", 18 | "splashscreen", 19 | "ecosystem:cordova", 20 | "cordova-android", 21 | "cordova-windows", 22 | "cordova-browser" 23 | ], 24 | "scripts": { 25 | "test": "npm run lint", 26 | "lint": "eslint ." 27 | }, 28 | "engines": { 29 | "cordovaDependencies": { 30 | "2.0.0": { 31 | "cordova-android": ">=3.6.0" 32 | }, 33 | ">=4.0.0": { 34 | "cordova-android": ">=3.6.0", 35 | "cordova-windows": ">=4.4.0" 36 | }, 37 | "7.0.0": { 38 | "cordova": ">100" 39 | } 40 | } 41 | }, 42 | "author": "Apache Software Foundation", 43 | "license": "Apache-2.0", 44 | "devDependencies": { 45 | "@cordova/eslint-config": "^3.0.0" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-splashscreen/src/windows/SplashScreenProxy.js: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Licensed to the Apache Software Foundation (ASF) under one 4 | * or more contributor license agreements. See the NOTICE file 5 | * distributed with this work for additional information 6 | * regarding copyright ownership. The ASF licenses this file 7 | * to you under the Apache License, Version 2.0 (the 8 | * "License"); you may not use this file except in compliance 9 | * with the License. You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, 14 | * software distributed under the License is distributed on an 15 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * KIND, either express or implied. See the License for the 17 | * specific language governing permissions and limitations 18 | * under the License. 19 | * 20 | */ 21 | 22 | var splash = require('cordova/splashscreen'); 23 | 24 | var SplashScreen = { 25 | show: function () { 26 | splash.show(); 27 | }, 28 | hide: function () { 29 | splash.hide(); 30 | } 31 | }; 32 | 33 | module.exports = SplashScreen; 34 | 35 | require('cordova/exec/proxy').add('SplashScreen', SplashScreen); 36 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-splashscreen/tests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cordova-plugin-splashscreen-tests", 3 | "version": "6.0.1-dev", 4 | "description": "", 5 | "cordova": { 6 | "id": "cordova-plugin-splashscreen-tests", 7 | "platforms": [] 8 | }, 9 | "keywords": [ 10 | "ecosystem:cordova" 11 | ], 12 | "author": "", 13 | "license": "Apache 2.0" 14 | } 15 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-splashscreen/tests/plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 24 | Cordova Splashscreen Plugin Tests 25 | Apache 2.0 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-splashscreen/types/index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for Apache Cordova Splashscreen plugin 2 | // Project: https://github.com/apache/cordova-plugin-splashscreen 3 | // Definitions by: Microsoft Open Technologies Inc 4 | // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped 5 | // 6 | // Copyright (c) Microsoft Open Technologies Inc 7 | // Licensed under the MIT license. 8 | 9 | interface Navigator { 10 | /** This plugin displays and hides a splash screen during application launch. */ 11 | splashscreen: { 12 | /** Dismiss the splash screen. */ 13 | hide(): void; 14 | /** Displays the splash screen. */ 15 | show(): void; 16 | } 17 | } -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-splashscreen/www/splashscreen.js: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Licensed to the Apache Software Foundation (ASF) under one 4 | * or more contributor license agreements. See the NOTICE file 5 | * distributed with this work for additional information 6 | * regarding copyright ownership. The ASF licenses this file 7 | * to you under the Apache License, Version 2.0 (the 8 | * "License"); you may not use this file except in compliance 9 | * with the License. You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, 14 | * software distributed under the License is distributed on an 15 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * KIND, either express or implied. See the License for the 17 | * specific language governing permissions and limitations 18 | * under the License. 19 | * 20 | */ 21 | 22 | var exec = require('cordova/exec'); 23 | 24 | var splashscreen = { 25 | show: function () { 26 | exec(null, null, 'SplashScreen', 'show', []); 27 | }, 28 | hide: function () { 29 | exec(null, null, 'SplashScreen', 'hide', []); 30 | } 31 | }; 32 | 33 | module.exports = splashscreen; 34 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-statusbar/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "browser": true 3 | , "devel": true 4 | , "bitwise": true 5 | , "undef": true 6 | , "trailing": true 7 | , "quotmark": false 8 | , "indent": 4 9 | , "unused": "vars" 10 | , "latedef": "nofunc" 11 | , "globals": { 12 | "module": false, 13 | "exports": false, 14 | "require": false 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-statusbar/NOTICE: -------------------------------------------------------------------------------- 1 | Apache Cordova 2 | Copyright 2012 The Apache Software Foundation 3 | 4 | This product includes software developed at 5 | The Apache Software Foundation (http://www.apache.org/). 6 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-statusbar/tests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cordova-plugin-statusbar-tests", 3 | "version": "2.4.3", 4 | "description": "", 5 | "cordova": { 6 | "id": "cordova-plugin-statusbar-tests", 7 | "platforms": [] 8 | }, 9 | "keywords": [ 10 | "ecosystem:cordova" 11 | ], 12 | "author": "", 13 | "license": "Apache 2.0" 14 | } 15 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-statusbar/tests/plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 26 | Cordova StatusBar Plugin Tests 27 | Apache 2.0 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-whitelist/NOTICE: -------------------------------------------------------------------------------- 1 | Apache Cordova 2 | Copyright 2012 The Apache Software Foundation 3 | 4 | This product includes software developed at 5 | The Apache Software Foundation (http://www.apache.org/). 6 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-whitelist/tests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cordova-plugin-whitelist-tests", 3 | "version": "1.3.4", 4 | "description": "", 5 | "cordova": { 6 | "id": "cordova-plugin-whitelist-tests", 7 | "platforms": [] 8 | }, 9 | "keywords": [ 10 | "ecosystem:cordova" 11 | ], 12 | "author": "", 13 | "license": "Apache 2.0" 14 | } 15 | 16 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-whitelist/tests/scripts/remove-access.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var path = require('path'); 3 | var rootdir = ""; 4 | var file = path.join(rootdir, "platforms/android/app/src/main/res/xml/config.xml"); 5 | 6 | fs.readFile( file, "utf8", function( err, data ) 7 | { 8 | if (err) 9 | return console.log( err ); 10 | 11 | var result = data; 12 | result = result.replace( "", "" ); 13 | 14 | fs.writeFile( file, result, "utf8", function( err ) 15 | { 16 | if (err) 17 | return console.log( err ); 18 | } ); 19 | } ); -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/cordova-plugin-whitelist/tests/www/whitelist.js: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Licensed to the Apache Software Foundation (ASF) under one 4 | * or more contributor license agreements. See the NOTICE file 5 | * distributed with this work for additional information 6 | * regarding copyright ownership. The ASF licenses this file 7 | * to you under the Apache License, Version 2.0 (the 8 | * "License"); you may not use this file except in compliance 9 | * with the License. You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, 14 | * software distributed under the License is distributed on an 15 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * KIND, either express or implied. See the License for the 17 | * specific language governing permissions and limitations 18 | * under the License. 19 | * 20 | */ 21 | 22 | var argscheck = require('cordova/argscheck'), 23 | exec = require('cordova/exec'); 24 | 25 | module.exports = { 26 | match: function(url, patterns, callback) { 27 | //argscheck.checkArgs('fF', 'Whitelist.match', arguments); 28 | exec(callback, callback, "WhitelistAPI", "URLMatchesPatterns", [url, patterns]); 29 | }, 30 | test: function(url, callback) { 31 | //argscheck.checkArgs('fF', 'Whitelist.test', arguments); 32 | exec(callback, callback, "WhitelistAPI", "URLIsAllowed", [url]); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/fetch.json: -------------------------------------------------------------------------------- 1 | { 2 | "cordova-plugin-ionic-webview": { 3 | "source": { 4 | "type": "registry", 5 | "id": "cordova-plugin-ionic-webview@latest" 6 | }, 7 | "is_top_level": true, 8 | "variables": {} 9 | }, 10 | "cordova-plugin-whitelist": { 11 | "source": { 12 | "type": "registry", 13 | "id": "cordova-plugin-whitelist@^1.3.4" 14 | }, 15 | "is_top_level": true, 16 | "variables": {} 17 | }, 18 | "cordova-plugin-statusbar": { 19 | "source": { 20 | "type": "registry", 21 | "id": "cordova-plugin-statusbar@2.4.3" 22 | }, 23 | "is_top_level": true, 24 | "variables": {} 25 | } 26 | } -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/ios.json: -------------------------------------------------------------------------------- 1 | { 2 | "prepare_queue": { 3 | "installed": [], 4 | "uninstalled": [] 5 | }, 6 | "config_munge": { 7 | "files": {} 8 | }, 9 | "installed_plugins": { 10 | "cordova-plugin-ionic-webview": { 11 | "PACKAGE_NAME": "com.attia" 12 | }, 13 | "cordova-plugin-whitelist": { 14 | "PACKAGE_NAME": "com.attia" 15 | }, 16 | "cordova-plugin-statusbar": { 17 | "PACKAGE_NAME": "com.attia" 18 | } 19 | }, 20 | "dependent_plugins": {} 21 | } 22 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/phonegap-plugin-contentsync/.bithoundrc: -------------------------------------------------------------------------------- 1 | { 2 | "ignore": [ 3 | "**/deps/**", 4 | "**/node_modules/**", 5 | "**/thirdparty/**", 6 | "**/third_party/**", 7 | "**/vendor/**", 8 | "**/**-min-**", 9 | "**/**-min.**", 10 | "**/**.min.**", 11 | "**/**jquery.?(ui|effects)-*.*.?(*).?(cs|j)s", 12 | "**/**jquery-*.*.?(*).?(cs|j)s", 13 | "**/prototype?(*).js", 14 | "**/**?(*).ts", 15 | "**/mootools*.*.*.js", 16 | "**/dojo.js", 17 | "**/MochiKit.js", 18 | "**/yahoo-*.js", 19 | "**/yui*.js", 20 | "**/ckeditor*.js", 21 | "**/tiny_mce*.js", 22 | "**/tiny_mce/?(langs|plugins|themes|utils)/**", 23 | "**/MathJax/**", 24 | "**/shBrush*.js", 25 | "**/shCore.js", 26 | "**/shLegacy.js", 27 | "**/modernizr.custom.?(*).js", 28 | "**/knockout-*.*.*.debug.js", 29 | "**/extjs/*.js", 30 | "**/extjs/*.xml", 31 | "**/extjs/*.txt", 32 | "**/extjs/*.html", 33 | "**/extjs/*.properties", 34 | "**/extjs/.sencha", 35 | "**/extjs/docs/**", 36 | "**/extjs/builds/**", 37 | "**/extjs/cmd/**", 38 | "**/extjs/examples/**", 39 | "**/extjs/locale/**", 40 | "**/extjs/packages/**", 41 | "**/extjs/plugins/**", 42 | "**/extjs/resources/**", 43 | "**/extjs/src/**", 44 | "**/extjs/welcome/**", 45 | "bower_components/**" 46 | ], 47 | "test": [ 48 | "**/test/**", 49 | "**/tests/**", 50 | "**/spec/**", 51 | "**/specs/**" 52 | ] 53 | } 54 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/phonegap-plugin-contentsync/.editorconfig: -------------------------------------------------------------------------------- 1 | # This file is for unifying the coding style of different editors and IDEs. 2 | # editorconfig.org 3 | 4 | root = true 5 | 6 | [*] 7 | charset = utf-8 8 | end_of_line = lf 9 | indent_size = 4 10 | indent_style = space 11 | insert_final_newline = true 12 | trim_trailing_whitespace = true 13 | 14 | [*.json] 15 | indent_size = 2 16 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/phonegap-plugin-contentsync/.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Expected Behaviour 2 | 3 | ### Actual Behaviour 4 | 5 | ### Reproduce Scenario (including but not limited to) 6 | 7 | #### Steps to Reproduce 8 | 9 | #### Platform and Version (eg. Android 5.0 or iOS 9.2.1) 10 | 11 | #### (Android) What device vendor (e.g. Samsung, HTC, Sony...) 12 | 13 | #### Cordova CLI version and cordova platform version 14 | 15 | cordova --version # e.g. 6.0.0 16 | cordova platform version android # e.g. 4.1.1 17 | 18 | #### Plugin version 19 | 20 | cordova plugin version | grep phonegap-plugin-contentsync # e.g. 1.5.3 21 | 22 | #### Sample Code that illustrates the problem 23 | 24 | #### Logs taken while reproducing problem 25 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/phonegap-plugin-contentsync/.gitignore: -------------------------------------------------------------------------------- 1 | # Mac 2 | .DS_Store 3 | 4 | # Node 5 | /node_modules/ 6 | npm-debug.log 7 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/phonegap-plugin-contentsync/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "asi": false, 3 | "boss": false, 4 | "camelcase": true, 5 | "curly": true, 6 | "eqeqeq": true, 7 | "eqnull": false, 8 | "es5": false, 9 | "evil": false, 10 | "expr": false, 11 | "forin": true, 12 | "funcscope": false, 13 | "jasmine": true, 14 | "immed": true, 15 | "indent": 4, 16 | "latedef": true, 17 | "loopfunc": false, 18 | "maxerr": 7, 19 | "newcap": true, 20 | "node": true, 21 | "nonew": true, 22 | "plusplus": false, 23 | "quotmark": "single", 24 | "shadow": false, 25 | "strict": false, 26 | "supernew": false, 27 | "trailing": true, 28 | "undef": true, 29 | "white": true 30 | } 31 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/phonegap-plugin-contentsync/.npmignore: -------------------------------------------------------------------------------- 1 | sample/ 2 | spec/ 3 | tests/ -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/phonegap-plugin-contentsync/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '0.10' 4 | branches: 5 | only: 6 | - master 7 | notifications: 8 | slack: 9 | secure: VcJej2eTOwkU9oh/MHXKw/efUMw+o15Fd8yzc8/vR0QVG6ubYaIPlMK9iPTI9+MgkP+DIHxvsVr84XQvM40RSr9M35N21zEJjG/P/He8slmca6MAM9v7V8XEZX9xlptshb276l8DfeJs3sF8YZNnulkqoTBeuXNii5pGUtwG7m0= 10 | email: 11 | - PhoneGapCI@adobe.com 12 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/phonegap-plugin-contentsync/NOTICE: -------------------------------------------------------------------------------- 1 | PhoneGap GUI 2 | Copyright 2013 Adobe Systems Incorporated 3 | 4 | This software is licensed under the Apache License, Version 2.0 (see 5 | LICENSE file). 6 | 7 | This software uses the following third party libraries that may have 8 | licenses differing from that of the software itself. You can find the 9 | libraries and their respective licenses below. 10 | 11 | PhoneGap is a registered trademark or trademark of Adobe Systems Incorporated. 12 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/phonegap-plugin-contentsync/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "phonegap-plugin-contentsync", 3 | "description": "Fetch and cache content for your PhoneGap app.", 4 | "version": "1.4.2", 5 | "homepage": "http://github.com/phonegap/phonegap-plugin-contentsync#readme", 6 | "repository": { 7 | "type": "git", 8 | "url": "git://github.com/phonegap/phonegap-plugin-contentsync.git" 9 | }, 10 | "bugs": { 11 | "url": "https://github.com/phonegap/phonegap-plugin-contentsync/issues" 12 | }, 13 | "cordova": { 14 | "id": "phonegap-plugin-contentsync", 15 | "platforms": [ 16 | "ios", 17 | "android", 18 | "windows8", 19 | "windows", 20 | "wp8", 21 | "browser", 22 | "osx" 23 | ] 24 | }, 25 | "keywords": [ 26 | "ecosystem:cordova", 27 | "ecosystem:phonegap", 28 | "cordova-ios", 29 | "cordova-android", 30 | "cordova-windows8", 31 | "cordova-windows", 32 | "cordova-wp8", 33 | "cordova-browser", 34 | "cordova-osx" 35 | ], 36 | "engines": [ 37 | { 38 | "name": "cordova", 39 | "version": ">=3.0.0" 40 | } 41 | ], 42 | "author": "Adobe PhoneGap Team", 43 | "license": "Apache-2.0", 44 | "scripts": { 45 | "test": "jasmine-node --color spec", 46 | "paramedic": "./tests/scripts/start-server.sh && cordova-paramedic --platform ios && ./tests/scripts/stop-server.sh" 47 | }, 48 | "devDependencies": { 49 | "jasmine-node": "1.14.5", 50 | "pluginpub": "^0.0.9" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/phonegap-plugin-contentsync/sample/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/harmony-plugins/plugins/phonegap-plugin-contentsync/sample/img/logo.png -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/phonegap-plugin-contentsync/src/browser/Sync.js: -------------------------------------------------------------------------------- 1 | function notSupported() { 2 | console.log('ContentSync is not supported on browser platform'); 3 | } 4 | 5 | var ContentSync = function() {}; 6 | ContentSync.prototype.on = function() { notSupported(); }; 7 | ContentSync.prototype.emit = function() { notSupported(); }; 8 | ContentSync.prototype.cancel = function() { notSupported(); }; 9 | 10 | function sync() { 11 | notSupported(); 12 | return new ContentSync(); 13 | } 14 | 15 | module.exports = { 16 | sync: sync, 17 | unzip: notSupported, 18 | download: notSupported, 19 | ContentSync: ContentSync 20 | }; 21 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/phonegap-plugin-contentsync/src/ios/minizip/mztools.h: -------------------------------------------------------------------------------- 1 | /* 2 | Additional tools for Minizip 3 | Code: Xavier Roche '2004 4 | License: Same as ZLIB (www.gzip.org) 5 | */ 6 | 7 | #ifndef _zip_tools_H 8 | #define _zip_tools_H 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | #ifndef _ZLIB_H 15 | #include "zlib.h" 16 | #endif 17 | 18 | #include "unzip.h" 19 | 20 | /* Repair a ZIP file (missing central directory) 21 | file: file to recover 22 | fileOut: output file after recovery 23 | fileOutTmp: temporary file name used for recovery 24 | */ 25 | extern int ZEXPORT unzRepair(const char* file, 26 | const char* fileOut, 27 | const char* fileOutTmp, 28 | uLong* nRecovered, 29 | uLong* bytesRecovered); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/phonegap-plugin-contentsync/src/windows/ZipWinProj/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Resources; 2 | using System.Reflection; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("ZipWinProj")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("ZipWinProj")] 14 | [assembly: AssemblyCopyright("Copyright © 2015")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | [assembly: NeutralResourcesLanguage("en")] 18 | 19 | // Version information for an assembly consists of the following four values: 20 | // 21 | // Major Version 22 | // Minor Version 23 | // Build Number 24 | // Revision 25 | // 26 | // You can specify all the values or you can default the Build and Revision Numbers 27 | // by using the '*' as shown below: 28 | // [assembly: AssemblyVersion("1.0.*")] 29 | [assembly: AssemblyVersion("1.0.0.0")] 30 | [assembly: AssemblyFileVersion("1.0.0.0")] 31 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/phonegap-plugin-contentsync/tests/anyfile.txt: -------------------------------------------------------------------------------- 1 | Test file that is enumerated before the directories. 2 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/phonegap-plugin-contentsync/tests/archives/www1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/harmony-plugins/plugins/phonegap-plugin-contentsync/tests/archives/www1.zip -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/phonegap-plugin-contentsync/tests/archives/www2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/harmony-plugins/plugins/phonegap-plugin-contentsync/tests/archives/www2.zip -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/phonegap-plugin-contentsync/tests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "phonegap-plugin-contentsync-tests", 3 | "version": "1.0.0", 4 | "description": "Tests for phonegap-plugin-contentsync", 5 | "main": "tests.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "Apache-2.0" 11 | } 12 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/phonegap-plugin-contentsync/tests/plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | PhoneGap Content Sync Plugin Tests 8 | Apache 2.0 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/phonegap-plugin-contentsync/tests/scripts/start-server.sh: -------------------------------------------------------------------------------- 1 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 2 | cd $DIR/../archives && python -m "SimpleHTTPServer" 4321 & 3 | -------------------------------------------------------------------------------- /mobile-app/harmony-plugins/plugins/phonegap-plugin-contentsync/tests/scripts/stop-server.sh: -------------------------------------------------------------------------------- 1 | ps aux | grep -e "python -m SimpleHTTPServer" | grep -v grep | awk '{print "kill -1 " $2}' | sh 2 | -------------------------------------------------------------------------------- /mobile-app/res/icons/android/hdpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/icons/android/hdpi.png -------------------------------------------------------------------------------- /mobile-app/res/icons/android/ldpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/icons/android/ldpi.png -------------------------------------------------------------------------------- /mobile-app/res/icons/android/mdpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/icons/android/mdpi.png -------------------------------------------------------------------------------- /mobile-app/res/icons/android/xhdpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/icons/android/xhdpi.png -------------------------------------------------------------------------------- /mobile-app/res/icons/android/xxhdpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/icons/android/xxhdpi.png -------------------------------------------------------------------------------- /mobile-app/res/icons/android/xxxhdpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/icons/android/xxxhdpi.png -------------------------------------------------------------------------------- /mobile-app/res/icons/ios/icon-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/icons/ios/icon-1024.png -------------------------------------------------------------------------------- /mobile-app/res/icons/ios/icon-167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/icons/ios/icon-167.png -------------------------------------------------------------------------------- /mobile-app/res/icons/ios/icon-20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/icons/ios/icon-20.png -------------------------------------------------------------------------------- /mobile-app/res/icons/ios/icon-24@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/icons/ios/icon-24@2x.png -------------------------------------------------------------------------------- /mobile-app/res/icons/ios/icon-29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/icons/ios/icon-29@3x.png -------------------------------------------------------------------------------- /mobile-app/res/icons/ios/icon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/icons/ios/icon-40.png -------------------------------------------------------------------------------- /mobile-app/res/icons/ios/icon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/icons/ios/icon-40@2x.png -------------------------------------------------------------------------------- /mobile-app/res/icons/ios/icon-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/icons/ios/icon-50.png -------------------------------------------------------------------------------- /mobile-app/res/icons/ios/icon-50@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/icons/ios/icon-50@2x.png -------------------------------------------------------------------------------- /mobile-app/res/icons/ios/icon-60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/icons/ios/icon-60.png -------------------------------------------------------------------------------- /mobile-app/res/icons/ios/icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/icons/ios/icon-60@2x.png -------------------------------------------------------------------------------- /mobile-app/res/icons/ios/icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/icons/ios/icon-60@3x.png -------------------------------------------------------------------------------- /mobile-app/res/icons/ios/icon-72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/icons/ios/icon-72.png -------------------------------------------------------------------------------- /mobile-app/res/icons/ios/icon-72@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/icons/ios/icon-72@2x.png -------------------------------------------------------------------------------- /mobile-app/res/icons/ios/icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/icons/ios/icon-76.png -------------------------------------------------------------------------------- /mobile-app/res/icons/ios/icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/icons/ios/icon-76@2x.png -------------------------------------------------------------------------------- /mobile-app/res/icons/ios/icon-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/icons/ios/icon-83.5@2x.png -------------------------------------------------------------------------------- /mobile-app/res/icons/ios/icon-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/icons/ios/icon-small.png -------------------------------------------------------------------------------- /mobile-app/res/icons/ios/icon-small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/icons/ios/icon-small@2x.png -------------------------------------------------------------------------------- /mobile-app/res/icons/ios/icon-small@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/icons/ios/icon-small@3x.png -------------------------------------------------------------------------------- /mobile-app/res/icons/ios/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/icons/ios/icon.png -------------------------------------------------------------------------------- /mobile-app/res/icons/ios/icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/icons/ios/icon@2x.png -------------------------------------------------------------------------------- /mobile-app/res/screen/android/splash-land-hdpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/screen/android/splash-land-hdpi.png -------------------------------------------------------------------------------- /mobile-app/res/screen/android/splash-land-ldpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/screen/android/splash-land-ldpi.png -------------------------------------------------------------------------------- /mobile-app/res/screen/android/splash-land-mdpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/screen/android/splash-land-mdpi.png -------------------------------------------------------------------------------- /mobile-app/res/screen/android/splash-land-xhdpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/screen/android/splash-land-xhdpi.png -------------------------------------------------------------------------------- /mobile-app/res/screen/android/splash-land-xxhdpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/screen/android/splash-land-xxhdpi.png -------------------------------------------------------------------------------- /mobile-app/res/screen/android/splash-port-hdpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/screen/android/splash-port-hdpi.png -------------------------------------------------------------------------------- /mobile-app/res/screen/android/splash-port-ldpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/screen/android/splash-port-ldpi.png -------------------------------------------------------------------------------- /mobile-app/res/screen/android/splash-port-mdpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/screen/android/splash-port-mdpi.png -------------------------------------------------------------------------------- /mobile-app/res/screen/android/splash-port-xhdpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/screen/android/splash-port-xhdpi.png -------------------------------------------------------------------------------- /mobile-app/res/screen/android/splash-port-xxhdpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/screen/android/splash-port-xxhdpi.png -------------------------------------------------------------------------------- /mobile-app/res/screen/ios/Default@2x~universal~anyany.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/screen/ios/Default@2x~universal~anyany.png -------------------------------------------------------------------------------- /mobile-app/res/screen/ios/Default@2x~universal~comany.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/screen/ios/Default@2x~universal~comany.png -------------------------------------------------------------------------------- /mobile-app/res/screen/ios/Default@2x~universal~comcom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/screen/ios/Default@2x~universal~comcom.png -------------------------------------------------------------------------------- /mobile-app/res/screen/ios/Default@3x~universal~anyany.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/screen/ios/Default@3x~universal~anyany.png -------------------------------------------------------------------------------- /mobile-app/res/screen/ios/Default@3x~universal~anycom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/screen/ios/Default@3x~universal~anycom.png -------------------------------------------------------------------------------- /mobile-app/res/screen/ios/Default@3x~universal~comany.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/mobile-app/res/screen/ios/Default@3x~universal~comany.png -------------------------------------------------------------------------------- /mobile-app/webpack.config.js: -------------------------------------------------------------------------------- 1 | const execSh = require("exec-sh"); 2 | const HtmlReplaceWebpackPlugin = require('html-replace-webpack-plugin'); 3 | 4 | const isProduction = process.env.NODE_ENV === "production"; 5 | const isMobileApp = process.env.BUILD_TYPE === "mobile"; 6 | const platform = process.env.npm_config_platform; 7 | 8 | const devPublicPath = (platform === "android") ? "http://10.0.2.2:8082/" : "http://localhost:8082/"; 9 | const cordovaPath = (platform === "android") ? "/mobile-app/platforms/android/app/src/main/assets/www/cordova.js" : "/mobile-app/platforms/ios/platform_www/cordova.js"; 10 | let isDone = false; 11 | 12 | if (isMobileApp && !platform) { 13 | throw Error('Did you miss --platform ? platform are mandatory. Example: npm run build --platform=android'); 14 | } 15 | 16 | const mobileConfig = { 17 | output: { 18 | publicPath: (isProduction) ? "/" : devPublicPath, 19 | }, 20 | devServer: { 21 | host: '0.0.0.0' 22 | }, 23 | plugins: [ 24 | new HtmlReplaceWebpackPlugin([{ 25 | pattern: '${cordovaPath}', 26 | replacement: (isProduction) ? '/cordova.js' : cordovaPath, 27 | }]), 28 | { 29 | apply: compiler => { 30 | compiler.hooks.done.tap('run-cordova', compilation => { 31 | if (!isDone) { 32 | isDone = true; 33 | if (process.env.NODE_ENV === 'development') { 34 | execSh(`cd ./mobile-app && cordova run ${platform}`); 35 | } else { 36 | execSh(`cd ./mobile-app && cordova build ${platform}`); 37 | } 38 | } 39 | }) 40 | } 41 | }, 42 | ] 43 | }; 44 | 45 | module.exports = (isMobileApp) ? mobileConfig : {}; 46 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [require("postcss-preset-env")] 3 | }; 4 | -------------------------------------------------------------------------------- /src/App.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { baseConnect } from '@base/features/base-redux-react-connect'; 3 | import { PendingTasks } from '@base/features/base-global-spinner/reducer'; 4 | import { Media } from '@base/features/base-render-mobile'; 5 | import ErrorHandler from 'containers/ErrorHandler'; 6 | import Localization from 'containers/Localization'; 7 | import Header from 'containers/Header'; 8 | import { ApplicationState } from 'actions'; 9 | import { Spinner } from 'common-components/business'; 10 | 11 | interface Props { 12 | children: any; 13 | pendingTasks: PendingTasks; 14 | } 15 | 16 | class App extends React.Component { 17 | render() { 18 | const { children, pendingTasks } = this.props; 19 | const loading = pendingTasks?.length; 20 | 21 | return ( 22 | <> 23 | 24 | {(!!loading) && } 25 | 26 |
27 | 28 | {children} 29 | 30 | 31 |
This is Render Example for 0-768 screen size
32 | {children} 33 |
34 | 35 | ); 36 | } 37 | } 38 | 39 | const mapStateToProps = (state: ApplicationState) => ({ 40 | pendingTasks: state.globalSpinner.pendingTasks 41 | }); 42 | 43 | export default baseConnect( 44 | App, 45 | mapStateToProps, 46 | {} 47 | ); 48 | -------------------------------------------------------------------------------- /src/actions/cart/index.ts: -------------------------------------------------------------------------------- 1 | import { all, fork, takeLatest } from 'redux-saga/effects'; 2 | import { createSaga } from '@base/features/base-decorator'; 3 | import * as Sagas from 'actions/cart/sagas'; 4 | import { CartTypes } from 'actions/cart'; 5 | 6 | /* ------------- Export Redux ------------- */ 7 | export * from 'actions/cart/redux'; 8 | 9 | /* ------------- Export Sagas ------------- */ 10 | function* watchAddSaga() { 11 | yield takeLatest(CartTypes.ADD_TO_CART, createSaga(Sagas.addSaga)); 12 | } 13 | 14 | function* watchRemoveSaga() { 15 | yield takeLatest(CartTypes.REMOVE_FROM_CART, createSaga(Sagas.removeSaga)); 16 | } 17 | 18 | function* watchClearCartSaga() { 19 | yield takeLatest(CartTypes.CLEAR_CART, createSaga(Sagas.clearSaga)); 20 | } 21 | export function* cartSaga() { 22 | yield all([ 23 | fork(watchAddSaga), 24 | fork(watchRemoveSaga), 25 | fork(watchClearCartSaga) 26 | ]); 27 | } 28 | -------------------------------------------------------------------------------- /src/actions/cart/manager.ts: -------------------------------------------------------------------------------- 1 | import { Store } from '@base/features'; 2 | import { cartSelector } from 'actions/cart'; 3 | 4 | export const isTowSamsungInCart = async () => { 5 | const cartItems = cartSelector.getCartItems(Store.getState()); 6 | 7 | const filterCart = cartItems?.filter((item) => { 8 | return item.brand.toLowerCase() === 'samsung'; 9 | }); 10 | 11 | if (filterCart?.length >= 2) { 12 | return Promise.resolve(); 13 | } 14 | 15 | return Promise.reject(); 16 | }; 17 | 18 | export const isTowXiaomiInCart = async () => { 19 | const cartItems = cartSelector.getCartItems(Store.getState()); 20 | 21 | const filterCart = cartItems?.filter((item) => { 22 | return item.brand.toLowerCase() === 'xiaomi'; 23 | }); 24 | 25 | if (filterCart?.length >= 2) { 26 | return Promise.resolve(); 27 | } 28 | 29 | return Promise.reject(); 30 | }; 31 | 32 | export const someFailedCondition = async () => { 33 | return Promise.reject(); 34 | }; 35 | 36 | export const someSuccessCondition = async () => { 37 | return Promise.resolve(); 38 | }; 39 | -------------------------------------------------------------------------------- /src/actions/cart/sagas.ts: -------------------------------------------------------------------------------- 1 | import { put, select } from 'redux-saga/effects'; 2 | import { getInstances } from '@base/features/base-cart'; 3 | import { cartSelector, CartActions } from 'actions/cart'; 4 | import { AddToCartAction, CartItem, RemoveFromCartAction } from 'actions/cart/interface'; 5 | 6 | export function* addSaga(action: AddToCartAction) { 7 | const [instance] = getInstances(); 8 | const { item } = action; 9 | const cartItems: CartItem[] = yield select(cartSelector.getCartItems); 10 | const cartId: number = yield select(cartSelector.getCartId); 11 | 12 | if (!cartId || !cartItems || !cartItems.length) { 13 | yield put(CartActions.setCartId(Math.floor((Math.random() * 10000000) + 1).toString())); 14 | } 15 | 16 | yield put(instance.actions.add(item.id, item)); 17 | } 18 | 19 | export function* removeSaga(action: RemoveFromCartAction) { 20 | const { id } = action; 21 | const [instance] = getInstances(); 22 | 23 | yield put(instance.actions.remove(id)); 24 | } 25 | 26 | export function* clearSaga() { 27 | const [instance] = getInstances(); 28 | 29 | yield put(instance.actions.clear()); 30 | } 31 | -------------------------------------------------------------------------------- /src/actions/catalog/index.ts: -------------------------------------------------------------------------------- 1 | import { all, fork, takeLatest } from 'redux-saga/effects'; 2 | import { createSaga } from '@base/features/base-decorator'; 3 | import * as Sagas from 'actions/catalog/sagas'; 4 | import { CatalogTypes } from 'actions/catalog'; 5 | 6 | /* ------------- Export Redux ------------- */ 7 | export * from 'actions/catalog/redux'; 8 | 9 | /* ------------- Export Sagas ------------- */ 10 | function* watchGetDevices() { 11 | yield takeLatest(CatalogTypes.GET_DEVICE_LIST, createSaga(Sagas.getDevices)); 12 | } 13 | 14 | export function* catalogSaga() { 15 | yield all([ 16 | fork(watchGetDevices) 17 | ]); 18 | } 19 | -------------------------------------------------------------------------------- /src/actions/catalog/interface.ts: -------------------------------------------------------------------------------- 1 | import { Action } from 'redux'; 2 | 3 | /* ------------- Define Actions and State ------------- */ 4 | export interface CatalogState { 5 | deviceList: Device[]; 6 | } 7 | 8 | export enum TypesNames { 9 | GET_DEVICE_LIST = 'GET_DEVICE_LIST', 10 | SET_DEVICE_LIST = 'SET_DEVICE_LIST' 11 | } 12 | 13 | export declare function GetDeviceListFunction(): GetDeviceListAction; 14 | export declare function SetDeviceListFunction(deviceList: Device[]): SetDeviceListAction; 15 | 16 | export interface ActionCreator { 17 | getDeviceList: typeof GetDeviceListFunction; 18 | setDeviceList: typeof SetDeviceListFunction; 19 | } 20 | 21 | export interface SetDeviceListAction extends Action { 22 | deviceList: Device[]; 23 | } 24 | 25 | export type GetDeviceListAction = Action; 26 | 27 | /* ------------- Define Any Interfaces ------------- */ 28 | export interface Device { 29 | id: number; 30 | name: string; 31 | price: number; 32 | description: string; 33 | image: string; 34 | brand: string; 35 | } 36 | -------------------------------------------------------------------------------- /src/actions/catalog/manager.ts: -------------------------------------------------------------------------------- 1 | // Here you right all the "sdk" ( managers, utils etc .. ) 2 | // actually here is a function that are not saga and should return simple values without dispatch 3 | // for example function that get a and b and return a + b 4 | -------------------------------------------------------------------------------- /src/actions/catalog/redux.ts: -------------------------------------------------------------------------------- 1 | import { createDraft, Draft } from 'immer'; 2 | import { createReducerCase } from '@base/features/base-decorator'; 3 | import { createReducer, createActions } from 'reduxsauce'; 4 | import { ApplicationState } from 'actions'; 5 | import { 6 | TypesNames, ActionCreator, CatalogState, SetDeviceListAction 7 | } from './interface'; 8 | 9 | /* ------------- Types and Action Creators ------------- */ 10 | 11 | const { Creators } = createActions({ 12 | getDeviceList: [], 13 | setDeviceList: ['deviceList'] 14 | }); 15 | 16 | export const CatalogTypes = TypesNames; 17 | export const CatalogActions = Creators; 18 | 19 | /* ------------- Initial State ------------- */ 20 | 21 | const INITIAL_STATE = createDraft({ 22 | deviceList: [] 23 | }); 24 | 25 | /* ------------- Selectors ------------- */ 26 | 27 | export const catalogSelector = { 28 | devices: (state: ApplicationState) => state.catalog.deviceList 29 | }; 30 | /* ------------- Reducers ------------- */ 31 | 32 | const setDeviceListReducer = (draft: Draft, action: SetDeviceListAction) => { 33 | const { deviceList } = action; 34 | draft.deviceList = deviceList; 35 | }; 36 | 37 | /* ------------- Hookup Reducers To Types ------------- */ 38 | 39 | export const reducer = createReducer(INITIAL_STATE, { 40 | [CatalogTypes.SET_DEVICE_LIST]: createReducerCase(setDeviceListReducer) 41 | }); 42 | -------------------------------------------------------------------------------- /src/actions/catalog/sagas.ts: -------------------------------------------------------------------------------- 1 | import { AxiosResponse } from 'axios'; 2 | import { call, put } from 'redux-saga/effects'; 3 | import api from 'requests'; 4 | import { CatalogActions } from 'actions/catalog'; 5 | import { Device } from 'actions/catalog/interface'; 6 | import { startFlow } from 'actions/flowManager/sagas'; 7 | import { TypesNames } from 'actions/flowManager/interface'; 8 | import FlowManagerConfig from 'public/config/flow-manager/types.json'; 9 | 10 | const { flowTypes, stepTypes } = FlowManagerConfig; 11 | 12 | export function* getDevices() { 13 | yield call(startFlow, { 14 | type: TypesNames.START_FLOW, 15 | flowType: flowTypes.COP, 16 | currentStep: stepTypes.DEVICE_GALLERY.name, 17 | }); 18 | 19 | // replace api with api.getDevices to point to server 20 | const response: AxiosResponse> = yield call(api.getDevices); 21 | 22 | if (response.status === 200) { 23 | yield put(CatalogActions.setDeviceList(response.data)); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/actions/flowManager/index.ts: -------------------------------------------------------------------------------- 1 | import { all, fork, takeLatest } from 'redux-saga/effects'; 2 | import { createSaga } from '@base/features/base-decorator'; 3 | import * as Sagas from 'actions/flowManager/sagas'; 4 | import { FlowManagerTypes } from 'actions/flowManager'; 5 | 6 | /* ------------- Export Redux ------------- */ 7 | export * from 'actions/flowManager/redux'; 8 | 9 | /* ------------- Export Sagas ------------- */ 10 | function* watchStartFlow() { 11 | yield takeLatest(FlowManagerTypes.START_FLOW, createSaga(Sagas.startFlow)); 12 | } 13 | 14 | function* watchMoveToNextStep() { 15 | yield takeLatest(FlowManagerTypes.MOVE_TO_NEXT_STEP, createSaga(Sagas.moveToNextStep)); 16 | } 17 | 18 | export function* flowManagerSaga() { 19 | yield all([ 20 | fork(watchStartFlow), 21 | fork(watchMoveToNextStep) 22 | ]); 23 | } 24 | -------------------------------------------------------------------------------- /src/actions/flowManager/interface.ts: -------------------------------------------------------------------------------- 1 | import { Action } from 'redux'; 2 | 3 | /* ------------- Define Actions and State ------------- */ 4 | export enum TypesNames { 5 | START_FLOW = 'START_FLOW', 6 | MOVE_TO_NEXT_STEP = 'MOVE_TO_NEXT_STEP' 7 | } 8 | 9 | export declare function StartFlowFunction(flowType: string, currentStep: string): StartFlowAction; 10 | export declare function MoveToNextStepFunction(step?: string): MoveToNextStepAction; 11 | 12 | export interface ActionCreator { 13 | startFlow: typeof StartFlowFunction; 14 | moveToNextStep: typeof MoveToNextStepFunction; 15 | } 16 | 17 | export interface StartFlowAction extends Action { 18 | flowType: string; 19 | currentStep: string; 20 | } 21 | 22 | export interface MoveToNextStepAction extends Action { 23 | step?: string; 24 | } 25 | 26 | /* ------------- Define Any Interfaces ------------- */ 27 | -------------------------------------------------------------------------------- /src/actions/flowManager/redux.ts: -------------------------------------------------------------------------------- 1 | import { createActions } from 'reduxsauce'; 2 | import { TypesNames, ActionCreator } from './interface'; 3 | 4 | /* ------------- Types and Action Creators ------------- */ 5 | 6 | const { Creators } = createActions({ 7 | startFlow: ['flowType', 'currentStep'], // handle by saga 8 | moveToNextStep: ['step'] // handle by saga 9 | }); 10 | 11 | export const FlowManagerTypes = TypesNames; 12 | export const FlowManagerActions = Creators; 13 | -------------------------------------------------------------------------------- /src/actions/flowManager/sagas.ts: -------------------------------------------------------------------------------- 1 | import { MoveToNextStepAction, StartFlowAction } from 'actions/flowManager/interface'; 2 | import { flowManager, history } from '@base/features'; 3 | import * as flowManagerManager from 'actions/flowManager/manager'; 4 | import FlowManagerConfig from 'public/config/flow-manager/types.json'; 5 | 6 | const { stepTypes } = FlowManagerConfig; 7 | 8 | export function* startFlow(action: StartFlowAction) { 9 | const { flowType, currentStep } = action; 10 | yield flowManager.startFlow(flowType, currentStep, true, 250); 11 | } 12 | 13 | export function* moveToNextStep(action: MoveToNextStepAction) { 14 | const { step } = action; 15 | const { flowType } = flowManagerManager.getFlowInformation(); 16 | 17 | if (!flowType) return; 18 | 19 | yield flowManager.updateInformation(); 20 | const isLastStep = flowManagerManager.isLastStep(); 21 | const nextStep = flowManager.nextStep(step); 22 | const pathToMove = stepTypes[nextStep]?.path; 23 | 24 | if (pathToMove && !isLastStep) { 25 | history.push(pathToMove); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/actions/index.ts: -------------------------------------------------------------------------------- 1 | import { combineReducers, Reducer } from 'redux'; 2 | import { fork, all } from 'redux-saga/effects'; 3 | import baseReducers, { BaseApplicationState } from '@base/features/base-reducers'; 4 | 5 | /* ------------- Import States ------------- */ 6 | import { CatalogState } from 'actions/catalog/interface'; 7 | import { CartState } from 'actions/cart/interface'; 8 | 9 | /* ------------- Import Sagas ------------- */ 10 | import { catalogSaga } from 'actions/catalog'; 11 | import { flowManagerSaga } from 'actions/flowManager'; 12 | import makeCart from '@base/features/base-cart'; 13 | 14 | const baseCartReducer = makeCart('cart').reducer; 15 | 16 | /* ------------- Define ApplicationState ------------- */ 17 | export interface ApplicationState extends BaseApplicationState { 18 | cart: CartState; 19 | catalog: CatalogState; 20 | } 21 | 22 | /* ------------- Export Reducers ------------- */ 23 | export const rootReducer: Reducer = combineReducers({ 24 | ...baseReducers, 25 | 26 | cart: require('./cart').reducer(baseCartReducer), 27 | catalog: require('./catalog').reducer 28 | }); 29 | 30 | /* ------------- Export Sagas ------------- */ 31 | export const rootSaga = function* () { 32 | yield all([fork(flowManagerSaga)]); 33 | yield all([fork(require('./cart').cartSaga)]); 34 | yield all([fork(catalogSaga)]); 35 | }; 36 | -------------------------------------------------------------------------------- /src/actions/localPersistData/index.ts: -------------------------------------------------------------------------------- 1 | /* ------------- Export Redux ------------- */ 2 | export * from 'actions/localPersistData/redux'; 3 | -------------------------------------------------------------------------------- /src/actions/localPersistData/interface.ts: -------------------------------------------------------------------------------- 1 | import { Action } from 'redux'; 2 | 3 | /* ------------- Define Actions and State ------------- */ 4 | export interface LocalPersistDataState { 5 | localDataExample: string; 6 | } 7 | 8 | export enum TypesNames { 9 | SET_LOCAL_DATA_EXAMPLE = 'SET_LOCAL_DATA_EXAMPLE' 10 | } 11 | 12 | export interface ActionCreator { 13 | setLocalDataExample: (localDataExample: string) => any; 14 | } 15 | 16 | export interface SetLocalDataExampleAction extends Action { 17 | localDataExample: string; 18 | } 19 | 20 | /* ------------- Define Any Interfaces ------------- */ 21 | -------------------------------------------------------------------------------- /src/actions/localPersistData/manager.ts: -------------------------------------------------------------------------------- 1 | // Here you right all the "sdk" ( managers, utils etc .. ) 2 | // actually here is a function that are not saga and should return simple values without dispatch 3 | // for example function that get a and b and return a + b 4 | -------------------------------------------------------------------------------- /src/actions/localPersistData/redux.ts: -------------------------------------------------------------------------------- 1 | import { createDraft, Draft } from 'immer'; 2 | import { createReducerCase } from '@base/features/base-decorator'; 3 | import { createReducer, createActions } from 'reduxsauce'; 4 | import { ApplicationState } from 'actions'; 5 | import { 6 | LocalPersistDataState, TypesNames, ActionCreator, SetLocalDataExampleAction 7 | } from './interface'; 8 | 9 | /* ------------- Types and Action Creators ------------- */ 10 | 11 | const { Creators } = createActions({ 12 | setLocalDataExample: ['localDataExample'] 13 | }); 14 | 15 | export const LocalPersistDataTypes = TypesNames; 16 | export const LocalPersistDataActions = Creators; 17 | 18 | /* ------------- Initial State ------------- */ 19 | 20 | const INITIAL_STATE = createDraft({ 21 | localDataExample: 'Initial Data Example' 22 | }); 23 | /* ------------- Selectors ------------- */ 24 | 25 | export const localDataSelector = { 26 | localDataExample: (state: ApplicationState) => state.localPersistData.localDataExample 27 | }; 28 | 29 | /* ------------- Reducers ------------- */ 30 | 31 | const setLocalDataExampleReducer = (draft: Draft, action: SetLocalDataExampleAction) => { 32 | const { localDataExample } = action; 33 | 34 | draft.localDataExample = localDataExample; 35 | }; 36 | 37 | /* ------------- Hookup Reducers To Types ------------- */ 38 | 39 | export const reducer = createReducer(INITIAL_STATE, { 40 | [TypesNames.SET_LOCAL_DATA_EXAMPLE]: createReducerCase(setLocalDataExampleReducer) 41 | }); 42 | -------------------------------------------------------------------------------- /src/actions/localPersistData/sagas.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/src/actions/localPersistData/sagas.ts -------------------------------------------------------------------------------- /src/actions/sessionPersistData/index.ts: -------------------------------------------------------------------------------- 1 | /* ------------- Export Redux ------------- */ 2 | export * from 'actions/sessionPersistData/redux'; 3 | -------------------------------------------------------------------------------- /src/actions/sessionPersistData/interface.ts: -------------------------------------------------------------------------------- 1 | import { Action } from 'redux'; 2 | 3 | /* ------------- Define Actions and State ------------- */ 4 | export interface SessionPersistDataState { 5 | sessionDataExample: string; 6 | } 7 | 8 | export enum TypesNames { 9 | SET_SESSION_DATA_EXAMPLE = 'SET_SESSION_DATA_EXAMPLE' 10 | } 11 | 12 | export interface ActionCreator { 13 | setSessionDataExample: (SessionDataExample: string) => any; 14 | } 15 | 16 | export interface SetSessionDataExampleAction extends Action { 17 | sessionDataExample: string; 18 | } 19 | 20 | /* ------------- Define Any Interfaces ------------- */ 21 | export interface ResponseExample { 22 | name: string; 23 | } 24 | -------------------------------------------------------------------------------- /src/actions/sessionPersistData/manager.ts: -------------------------------------------------------------------------------- 1 | // Here you right all the "sdk" ( managers, utils etc .. ) 2 | // actually here is a function that are not saga and should return simple values without dispatch 3 | // for example function that get a and b and return a + b 4 | -------------------------------------------------------------------------------- /src/actions/sessionPersistData/sagas.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/src/actions/sessionPersistData/sagas.ts -------------------------------------------------------------------------------- /src/base/features/base-cart/index.ts: -------------------------------------------------------------------------------- 1 | export { 2 | instances, 3 | getInstances, 4 | makeCart, 5 | makeCart as default 6 | } from './makeCart'; 7 | -------------------------------------------------------------------------------- /src/base/features/base-cart/interfaces.ts: -------------------------------------------------------------------------------- 1 | import { Reducer } from 'redux'; 2 | 3 | export interface BaseCartState { 4 | items: T[]; 5 | } 6 | 7 | export interface Instance { 8 | actionTypes: any; 9 | reducer: Reducer; 10 | actions: Actions; 11 | } 12 | 13 | export interface Actions { 14 | add: (id: number | string, payload: any) => any; 15 | remove: (id: number | string) => any; 16 | update: (id: number | string, payload: any) => any; 17 | clear: () => any; 18 | } 19 | -------------------------------------------------------------------------------- /src/base/features/base-cart/makeActionTypes.ts: -------------------------------------------------------------------------------- 1 | const PREFIX = '@cart'; 2 | 3 | export const makeActionTypes = (cartName: any) => ({ 4 | ADD: `${PREFIX}/${cartName}/ADD_ITEM`, 5 | REMOVE: `${PREFIX}/${cartName}/REMOVE_ITEM`, 6 | UPDATE: `${PREFIX}/${cartName}/UPDATE_ITEM`, 7 | CLEAR: `${PREFIX}/${cartName}/CLEAR_ALL_ITEMS`, 8 | }); 9 | 10 | export default makeActionTypes; 11 | -------------------------------------------------------------------------------- /src/base/features/base-cart/makeActions.ts: -------------------------------------------------------------------------------- 1 | const checkId = (id: any) => { 2 | if (!id) throw new Error('Must specify item id!'); 3 | }; 4 | 5 | const makeAction = (actionTypes: any, type: any) => { 6 | switch (type) { 7 | case actionTypes.CLEAR: 8 | return () => ({ type }); 9 | case actionTypes.REMOVE: 10 | return (id: any) => { 11 | checkId(id); 12 | return { type, id }; 13 | }; 14 | default: 15 | return (id: any, payload = {}) => { 16 | checkId(id); 17 | if ( 18 | typeof payload !== 'object' 19 | || Array.isArray(payload) 20 | ) throw new Error('Payload must be object or undefined!'); 21 | return { type, id, ...payload }; 22 | }; 23 | } 24 | }; 25 | 26 | export const makeActions = (cartName: any, actionTypes: any) => { 27 | return Object.entries(actionTypes).reduce( 28 | (r, [typeName, type]) => { 29 | return { 30 | ...r, 31 | [typeName.toLowerCase()]: makeAction(actionTypes, type), 32 | }; 33 | }, 34 | {} 35 | ); 36 | }; 37 | 38 | export default makeActions; 39 | -------------------------------------------------------------------------------- /src/base/features/base-cart/makeCart.ts: -------------------------------------------------------------------------------- 1 | import makeActionTypes from './makeActionTypes'; 2 | import makeActions from './makeActions'; 3 | import makeReducer from './makeReducer'; 4 | import { Instance, Actions } from './interfaces'; 5 | 6 | export const instances: Array = []; 7 | export const getInstances = () => instances; 8 | 9 | export const makeCart = (cartName: any) => { 10 | const actionTypes = makeActionTypes(cartName); 11 | 12 | const instance = { 13 | actionTypes: makeActionTypes(cartName), 14 | actions: makeActions(cartName, actionTypes) as Actions, 15 | reducer: makeReducer(cartName, actionTypes), 16 | }; 17 | 18 | instances.push(instance); 19 | 20 | return instance; 21 | }; 22 | 23 | export default makeCart; 24 | -------------------------------------------------------------------------------- /src/base/features/base-decorator/createReducerCase.ts: -------------------------------------------------------------------------------- 1 | import produce from 'immer'; 2 | import { Store } from '@base/features'; 3 | 4 | export default (originalReducerCase: Function, isDoneHandler = false) => { 5 | return produce((...args: any) => { 6 | const type = args?.[1]?.type; 7 | const payload = { ...args?.[1] }; 8 | 9 | const res = originalReducerCase(...args); 10 | 11 | if (type && !isDoneHandler) { 12 | // settimeout to push action to last in memory stack 13 | setTimeout(() => { 14 | Store.dispatch({ type: `${type}_DONE`, payload }); 15 | }, 0); 16 | } 17 | return res; 18 | }); 19 | }; 20 | -------------------------------------------------------------------------------- /src/base/features/base-decorator/createSaga.ts: -------------------------------------------------------------------------------- 1 | import { put } from 'redux-saga/effects'; 2 | 3 | export default (originalSaga: Function, isDoneHandler = false) => { 4 | return function* (...args: any) { 5 | const type = args?.[0]?.type; 6 | const payload = { ...args?.[0] }; 7 | 8 | const response = yield originalSaga(...args); 9 | 10 | if (type && !isDoneHandler) { 11 | yield put({ type: `${type}_DONE`, response, payload }); 12 | } 13 | 14 | return response; 15 | }; 16 | }; 17 | -------------------------------------------------------------------------------- /src/base/features/base-decorator/customRoute.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Route } from 'react-router-dom'; 3 | 4 | const CustomRoute = (pageDecorator: Function) => ({ component, step, ...rest }: any) => { 5 | const ComponentToRender = pageDecorator(component, step); 6 | 7 | return ( 8 | 13 | ); 14 | }; 15 | 16 | export default CustomRoute; 17 | -------------------------------------------------------------------------------- /src/base/features/base-decorator/index.ts: -------------------------------------------------------------------------------- 1 | export * from './withToaster'; 2 | export { default as CustomRoute } from './customRoute'; 3 | export { default as createSaga } from './createSaga'; 4 | export { default as createReducerCase } from './createReducerCase'; 5 | export { withField } from './withField'; 6 | export { default as BaseStorybookDecorator } from './storybook'; 7 | -------------------------------------------------------------------------------- /src/base/features/base-decorator/storybook.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { PersistGate } from 'redux-persist/lib/integration/react'; 3 | import { Router } from 'react-router-dom'; 4 | import { Provider } from 'react-redux'; 5 | import { LocalizeProvider } from 'react-localize-redux'; 6 | import { ToastProvider } from 'react-toast-notifications'; 7 | import { MediaContextProvider } from 'base/features/base-render-mobile'; 8 | 9 | /* -------- Harmony Features Bootstrap --------- */ 10 | import { Store, persistor, history } from 'base/features'; 11 | 12 | export default (Story: any) => { 13 | return ( 14 | 15 | 16 | 17 | 18 | 19 | 20 | {Story()} 21 | 22 | 23 | 24 | 25 | 26 | 27 | ); 28 | }; 29 | -------------------------------------------------------------------------------- /src/base/features/base-decorator/withFilter.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable react/jsx-props-no-spreading */ 2 | import * as React from 'react'; 3 | import { baseConnect } from '@base/features/base-redux-react-connect'; 4 | 5 | declare function Compare(filterValue: any, props: any): boolean; 6 | 7 | export interface Config { 8 | filterSelector: (state: any, props: any) => any; 9 | compare: typeof Compare; 10 | } 11 | 12 | interface Props { 13 | filterValue: any; 14 | } 15 | 16 | export default (config: Config): any => (WrappedComponent: any) => { 17 | class WithFilter extends React.Component { 18 | render() { 19 | const { filterValue } = this.props; 20 | 21 | const isDisplay = config.compare(filterValue, this.props); 22 | 23 | if (filterValue && !isDisplay) return null; 24 | 25 | return ; 26 | } 27 | } 28 | 29 | return baseConnect( 30 | WithFilter, 31 | (state: any, props: any) => { 32 | return { 33 | filterValue: config.filterSelector(state, props) 34 | }; 35 | }, 36 | () => ({}) 37 | ); 38 | }; 39 | -------------------------------------------------------------------------------- /src/base/features/base-decorator/withSEO.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Helmet } from 'react-helmet'; 3 | 4 | export interface WithSEOConfig { 5 | helmet: (props: any) => any; 6 | } 7 | 8 | export const withSEO = (config: WithSEOConfig) => (Component: React.ComponentType): any => { 9 | return class extends React.Component { 10 | render() { 11 | return ( 12 | <> 13 | ‍ 14 | {config.helmet(this.props)} 15 | 16 | {/* eslint-disable-next-line react/jsx-props-no-spreading */} 17 | 18 | 19 | ); 20 | } 21 | }; 22 | }; 23 | -------------------------------------------------------------------------------- /src/base/features/base-decorator/withToaster.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { withToastManager, ToastConsumerContext } from 'react-toast-notifications'; 3 | 4 | export interface ToasterManager { 5 | toastManager: ToastConsumerContext; 6 | } 7 | 8 | export function withToast(Component: React.ComponentType) { 9 | return withToastManager(Component); 10 | } 11 | -------------------------------------------------------------------------------- /src/base/features/base-error-handler/reducer.ts: -------------------------------------------------------------------------------- 1 | export enum TypesNames { 2 | ERROR_HANDLER_INVOKE = 'ERROR_HANDLER_INVOKE', 3 | ERROR_HANDLER_HANDLED = 'ERROR_HANDLER_HANDLED' 4 | } 5 | 6 | const initialState = {}; 7 | 8 | export default (state = initialState, action: any) => { 9 | switch (action.type) { 10 | case TypesNames.ERROR_HANDLER_INVOKE: 11 | return { ...state, ...action.payload }; 12 | case TypesNames.ERROR_HANDLER_HANDLED: 13 | return {}; 14 | default: 15 | return state; 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /src/base/features/base-filter/index.ts: -------------------------------------------------------------------------------- 1 | import { TypesNames } from './reducer'; 2 | import Store from '@base/features/base-store'; 3 | import { BaseApplicationState } from '@base/features/base-reducers'; 4 | 5 | export interface FilterState { 6 | [key: string]: any; 7 | } 8 | 9 | export const filterDataDispatcher = (name: string, payload: any) => { 10 | Store.dispatch({ 11 | type: TypesNames.UPDATE_FILTER_DATA, 12 | payload, 13 | name 14 | }); 15 | }; 16 | 17 | export const filterDataSelector = (name: string) => (state: BaseApplicationState) => { 18 | return state.filters[name]; 19 | }; 20 | 21 | export * from './reducer'; 22 | export { default as withFilter } from '@base/features/base-decorator/withFilter'; 23 | -------------------------------------------------------------------------------- /src/base/features/base-filter/reducer.ts: -------------------------------------------------------------------------------- 1 | export enum TypesNames { 2 | UPDATE_FILTER_DATA = '@UPDATE_FILTER_DATA' 3 | } 4 | 5 | const initialState = {}; 6 | 7 | export const reducer = (state = initialState, action: { type: string; payload: any; name: string }) => { 8 | const { name } = action; 9 | 10 | switch (action.type) { 11 | case TypesNames.UPDATE_FILTER_DATA: 12 | return { ...state, [name]: action.payload }; 13 | default: 14 | return state; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /src/base/features/base-flow-manager/index.ts: -------------------------------------------------------------------------------- 1 | import CreateFlowManager, { parseSubFlowsJSON } from 'redux-flow-manager'; 2 | import subFlowsConfig from 'public/config/flow-manager/sub.flows.config.json'; 3 | import flowsConfig from 'public/config/flow-manager/flows.config.json'; 4 | import * as flowsConditions from 'configurations/flows.conditions'; 5 | 6 | export default (Store: any) => CreateFlowManager(Store, 'flowManager', parseSubFlowsJSON(subFlowsConfig, flowsConditions), flowsConfig); 7 | -------------------------------------------------------------------------------- /src/base/features/base-global-spinner/index.tsx: -------------------------------------------------------------------------------- 1 | import * as _ from 'lodash'; 2 | import { pendingTask, begin, end } from 'react-redux-spinner'; 3 | import store from '@base/features/base-store'; 4 | import SpinnerConfig from 'configurations/spinner.config.json'; 5 | import { TypesNames } from './reducer'; 6 | 7 | const { ignoreList } = SpinnerConfig; 8 | 9 | export const startSpinner = (url = '', uuid: string) => { 10 | const matchItem = _.filter(ignoreList, (regx: RegExp) => url.match(regx)); 11 | 12 | if (store && (!matchItem || !matchItem.length)) { 13 | store.dispatch({ 14 | type: TypesNames.XHR_TASK_BEGIN, 15 | [pendingTask]: begin, 16 | payload: { 17 | uuid, 18 | url 19 | } 20 | }); 21 | } 22 | }; 23 | 24 | export const endSpinner = (url = '', uuid: string) => { 25 | const matchItem = _.filter(ignoreList, (regx: RegExp) => url.match(regx)); 26 | 27 | if (store && (!matchItem || !matchItem.length)) { 28 | store.dispatch({ 29 | type: TypesNames.XHR_TASK_END, 30 | [pendingTask]: end, 31 | payload: { 32 | uuid, 33 | url 34 | } 35 | }); 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /src/base/features/base-global-spinner/reducer.ts: -------------------------------------------------------------------------------- 1 | export enum TypesNames { 2 | XHR_TASK_BEGIN = 'XHR_TASK_BEGIN', 3 | XHR_TASK_END = 'XHR_TASK_END' 4 | } 5 | 6 | export interface Pending { 7 | uuid: string; 8 | url: string; 9 | appId: string; 10 | subAppId: string; 11 | } 12 | 13 | export type PendingTasks = Array; 14 | 15 | export interface GlobalSpinnerState { 16 | pendingTasks: PendingTasks; 17 | } 18 | 19 | const initialState = { 20 | pendingTasks: [] 21 | }; 22 | 23 | export default (state = initialState, action: any) => { 24 | const newState = { ...state }; 25 | 26 | switch (action.type) { 27 | case TypesNames.XHR_TASK_BEGIN: 28 | newState.pendingTasks = newState.pendingTasks.concat(action?.payload); 29 | 30 | return newState; 31 | case TypesNames.XHR_TASK_END: 32 | if (action?.payload?.uuid) { 33 | newState.pendingTasks = newState.pendingTasks.filter((item: Pending) => item.uuid !== action.payload.uuid); 34 | } 35 | return newState; 36 | default: 37 | return state; 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /src/base/features/base-history/index.ts: -------------------------------------------------------------------------------- 1 | import { createBrowserHistory, createHashHistory } from 'history'; 2 | 3 | const historyObject = (window.cordova) ? createHashHistory() : createBrowserHistory(); 4 | 5 | export default historyObject; 6 | -------------------------------------------------------------------------------- /src/base/features/base-mock-service-worker/browser.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-extraneous-dependencies */ 2 | import { setupWorker } from 'msw'; 3 | import { handlers } from '../../../requests/mock-service-worker/handlers'; 4 | 5 | export const worker = setupWorker(...handlers); 6 | -------------------------------------------------------------------------------- /src/base/features/base-mock-service-worker/index.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-var-requires */ 2 | import { config } from 'config'; 3 | 4 | const prepareServiceWorkerForMockAPIs = () => { 5 | // eslint-disable-next-line no-console 6 | console.log(`%c[MSW] Mocking Type: ${config.MOCK_TYPE}`, 'color:blue; font-weight: bold;'); 7 | const { worker } = require('./browser'); 8 | worker.start({ 9 | onUnhandledRequest: 'bypass', 10 | serviceWorker: { 11 | url: '/mockServiceWorker.js' 12 | } 13 | }); 14 | }; 15 | 16 | const mock = config.USE_MOCK && prepareServiceWorkerForMockAPIs(); 17 | export default mock; 18 | -------------------------------------------------------------------------------- /src/base/features/base-rba/consts.ts: -------------------------------------------------------------------------------- 1 | export enum RBAStatus { 2 | DISABLED = 'disabled', 3 | HIDDEN = 'hidden', 4 | DOM_ID = 'data-rbac-id' 5 | } 6 | -------------------------------------------------------------------------------- /src/base/features/base-rba/interfaces.ts: -------------------------------------------------------------------------------- 1 | 2 | export interface RBAState { 3 | permissions?: any; 4 | } 5 | -------------------------------------------------------------------------------- /src/base/features/base-rba/reducer.ts: -------------------------------------------------------------------------------- 1 | export enum TypesNames { 2 | SET_RBA_DATA = 'SET_RBA_DATA', 3 | LOGOUT = 'LOGOUT' 4 | } 5 | 6 | const initialState = {}; 7 | 8 | export default (state = initialState, action: any) => { 9 | switch (action.type) { 10 | case TypesNames.SET_RBA_DATA: 11 | return { 12 | ...state, 13 | permissions: action.payload 14 | }; 15 | case TypesNames.LOGOUT: 16 | return initialState; 17 | default: 18 | return state; 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /src/base/features/base-redux-react-connect/index.ts: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import { withRouter } from 'react-router-dom'; 3 | import { withLocalize } from 'react-localize-redux'; 4 | import { reduxForm } from 'redux-form'; 5 | 6 | export function baseConnect(component: any, mapStateToProps: any, propsToDispatch?: any) { 7 | const componentWithRouter = withRouter(component); 8 | return ( 9 | connect( 10 | mapStateToProps, propsToDispatch 11 | )(withLocalize(componentWithRouter)) 12 | ); 13 | } 14 | 15 | export function baseConnectForm(component: any, mapStateToProps: any, propsToDispatch: any, formConfig: any) { 16 | return connectWithReduxForm(baseConnect(component, mapStateToProps, propsToDispatch), formConfig); 17 | } 18 | 19 | function connectWithReduxForm(component: any, reduxFormConfig: any) { 20 | const defaultValidateFunction = () => undefined; 21 | 22 | // eslint-disable-next-line no-param-reassign 23 | reduxFormConfig.validate = component?.prototype?.validate || defaultValidateFunction; 24 | 25 | return reduxForm(reduxFormConfig)(component); 26 | } 27 | -------------------------------------------------------------------------------- /src/base/features/base-render-mobile/index.ts: -------------------------------------------------------------------------------- 1 | import { createMedia } from '@artsy/fresnel'; 2 | 3 | export const { Media, MediaContextProvider } = createMedia({ 4 | breakpoints: { 5 | sm: 0, 6 | md: 768, 7 | lg: 1024, 8 | xl: 1192 9 | }, 10 | }); 11 | -------------------------------------------------------------------------------- /src/base/features/base-services/index.ts: -------------------------------------------------------------------------------- 1 | import { globalStoreListener } from './storeListener'; 2 | import { STORE_ACTION_LISTENERS } from './serviceTags'; 3 | 4 | export { globalStoreListener, STORE_ACTION_LISTENERS }; 5 | -------------------------------------------------------------------------------- /src/base/features/base-services/serviceTags.ts: -------------------------------------------------------------------------------- 1 | export const STORE_ACTION_LISTENERS = 'STORE_ACTION_LISTENERS'; 2 | -------------------------------------------------------------------------------- /src/base/features/base-services/storeListener.ts: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | import { STORE_ACTION_LISTENERS } from './serviceTags'; 3 | 4 | /* --------- custom event listeners ------- */ 5 | const events = (() => { 6 | const topics = {}; 7 | const hOP = topics.hasOwnProperty; 8 | 9 | return { 10 | subscribe(topic = STORE_ACTION_LISTENERS, listener) { 11 | // Create the topic's object if not yet created 12 | if (!hOP.call(topics, topic)) topics[topic] = []; 13 | 14 | // Add the listener to queue 15 | const index = topics[topic].push(listener) - 1; 16 | 17 | // Provide handle back for removal of topic 18 | return { 19 | remove() { 20 | delete topics[topic][index]; 21 | } 22 | }; 23 | }, 24 | publish(topic = STORE_ACTION_LISTENERS, info) { 25 | // If the topic doesn't exist, or there's no listeners in queue, just leave 26 | if (!hOP.call(topics, topic)) return; 27 | 28 | // Cycle through topics queue, fire! 29 | // tslint:disable-next-line:ter-prefer-arrow-callback 30 | topics[topic].forEach((item) => { 31 | item(info !== undefined ? info : {}); 32 | }); 33 | } 34 | }; 35 | })(); 36 | 37 | export const globalStoreListener = events; 38 | 39 | if (typeof window !== 'undefined') { 40 | window.addGlobalStoreListener = (listener) => globalStoreListener.subscribe(STORE_ACTION_LISTENERS, listener); 41 | } 42 | 43 | export default globalStoreListener; 44 | -------------------------------------------------------------------------------- /src/base/features/base-store/index.ts: -------------------------------------------------------------------------------- 1 | import { createStore, applyMiddleware, compose } from 'redux'; 2 | import { persistStore } from 'redux-persist'; 3 | import createSagaMiddleware from 'redux-saga'; 4 | import { globalStoreListener, STORE_ACTION_LISTENERS } from '@base/features/base-services'; 5 | import { config } from 'config'; 6 | import { rootReducer, rootSaga } from 'actions'; 7 | 8 | /* --------- define middleware ---------- */ 9 | 10 | export const globalActionListener = (/* store */) => (next: any) => (action: any) => { 11 | const result = next(action); 12 | globalStoreListener.publish(STORE_ACTION_LISTENERS, action); 13 | return result; 14 | }; 15 | 16 | const sagaMiddleware = createSagaMiddleware(); 17 | 18 | /* -------- create the store with middleware ---------- */ 19 | let customCompose; 20 | 21 | if (window.__REDUX_DEVTOOLS_EXTENSION__) { 22 | customCompose = compose(applyMiddleware(sagaMiddleware, globalActionListener), window.__REDUX_DEVTOOLS_EXTENSION__({ name: config.appName })); 23 | } else { 24 | customCompose = compose(applyMiddleware(sagaMiddleware, globalActionListener)); 25 | } 26 | 27 | const store = createStore(rootReducer, customCompose); 28 | 29 | /* -------- run root saga ---------- */ 30 | sagaMiddleware.run(rootSaga); 31 | 32 | /* -------- expose store functionality to page level ------------- */ 33 | export const persistor = persistStore(store); 34 | export default store; 35 | -------------------------------------------------------------------------------- /src/base/features/base-translations/index.ts: -------------------------------------------------------------------------------- 1 | import { renderToStaticMarkup } from 'react-dom/server'; 2 | import { initialize } from 'react-localize-redux'; 3 | import Store from '@base/features/base-store'; 4 | import { languageTypes, translations } from 'translation'; 5 | 6 | Store.dispatch( 7 | initialize({ 8 | languages: languageTypes, 9 | translation: translations, 10 | options: { 11 | renderToStaticMarkup, 12 | defaultLanguage: 'en' 13 | } 14 | }) 15 | ); 16 | -------------------------------------------------------------------------------- /src/base/features/index.ts: -------------------------------------------------------------------------------- 1 | /* -------- Harmony Features Bootstrap --------- */ 2 | import Store, { persistor } from '@base/features/base-store'; 3 | import '@base/features/base-redux-websocket-actions'; 4 | import '@base/features/base-translations'; 5 | import '@base/features/base-global-spinner'; 6 | import history from '@base/features/base-history'; 7 | import CreateFlowManager from '@base/features/base-flow-manager'; 8 | 9 | /* ----------Load Mock Service Worker -------*/ 10 | import 'base/features/base-mock-service-worker'; 11 | 12 | const flowManager = CreateFlowManager(Store); 13 | 14 | export { 15 | Store, 16 | history, 17 | persistor, 18 | flowManager 19 | }; 20 | -------------------------------------------------------------------------------- /src/common-components/business/DeviceCard/DeviceCard.stories.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ComponentStory, Meta } from '@storybook/react'; 3 | import DeviceCard, { Props as DeviceCardProps } from './index'; 4 | 5 | export default { 6 | title: 'Design System/Business Components/Device Card', 7 | component: DeviceCard, 8 | argTypes: { 9 | quantity: { 10 | description: 'The numbers of this Item in Cart. Once bigger then 1 title become remove.' 11 | } 12 | }, 13 | parameters: { docs: { source: { type: 'dynamic', excludeDecorators: true } } } 14 | } as Meta; 15 | 16 | // eslint-disable-next-line react/jsx-props-no-spreading 17 | const Template: ComponentStory = (args: any) => ; 18 | 19 | export const Buy = Template.bind({}); 20 | Buy.args = { 21 | device: { 22 | id: 1, 23 | brand: 'Samsung', 24 | image: 'http://localhost:8082/015a419598346bdd1c95.jpg', 25 | description: 'Single SIM 5G ultra wideband (mmWave) variant of Galaxy Note 20 Ultra flagship', 26 | name: 'Samsung Canvas C2 5G', 27 | price: 400 28 | }, 29 | quantity: 0, 30 | priceTitle: 'Price', 31 | removeButtonTitle: 'Remove', 32 | buttonTitle: 'Add to Cart' 33 | } as DeviceCardProps; 34 | 35 | export const Remove = Template.bind({}); 36 | Remove.args = { 37 | ...Buy.args, 38 | quantity: 1, 39 | } as DeviceCardProps; 40 | -------------------------------------------------------------------------------- /src/common-components/business/DeviceCard/style.scss: -------------------------------------------------------------------------------- 1 | .device-card-col { 2 | 3 | } 4 | 5 | .device-card { 6 | width: 18rem; 7 | text-align: center; 8 | } 9 | 10 | .device-card-content { 11 | height: 500px; 12 | } 13 | 14 | .device-card-img { 15 | width: auto !important; 16 | max-width: 100%; 17 | height: 15vw; 18 | } 19 | -------------------------------------------------------------------------------- /src/common-components/business/Spinner/Spinner.stories.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ComponentStory, Meta } from '@storybook/react'; 3 | import Spinner from './index'; 4 | 5 | export default { 6 | title: 'Design System/Business Components/Spinner', 7 | component: Spinner, 8 | argTypes: { 9 | 10 | }, 11 | parameters: { docs: { source: { type: 'dynamic', excludeDecorators: true } } } 12 | } as Meta; 13 | 14 | // eslint-disable-next-line react/jsx-props-no-spreading 15 | const Template: ComponentStory = (args: any) => ; 16 | 17 | export const Default = Template.bind({}); 18 | Default.args = { 19 | 20 | }; 21 | -------------------------------------------------------------------------------- /src/common-components/business/Spinner/index.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import './style.scss'; 3 | 4 | const spinner: React.FC = () => { 5 | return ( 6 |
7 | globalSpinner 8 |
9 | ); 10 | }; 11 | 12 | export default spinner; 13 | -------------------------------------------------------------------------------- /src/common-components/business/Spinner/style.scss: -------------------------------------------------------------------------------- 1 | .globalSpinner { 2 | position: fixed; 3 | left: 0; 4 | top: 0; 5 | right: 0; 6 | bottom: 0; 7 | z-index: 1; 8 | background-color: hsla(0, 100%, 100%, 0.4); 9 | 10 | 11 | img { 12 | position: fixed; 13 | top: 50%; 14 | left: 50%; 15 | margin-top: -100px; 16 | margin-left: -100px; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/common-components/business/index.ts: -------------------------------------------------------------------------------- 1 | export { default as Spinner } from './Spinner'; 2 | export { default as DeviceCard } from './DeviceCard'; 3 | -------------------------------------------------------------------------------- /src/common-components/controllers/FieldInput/FieldInput.stories.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable react/jsx-props-no-spreading */ 2 | import React from 'react'; 3 | import { baseConnectForm } from '@base/features/base-redux-react-connect'; 4 | import { ComponentStory, Meta } from '@storybook/react'; 5 | import { 6 | alphaNumeric, maxLength, required 7 | } from 'utils/validations'; 8 | import FieldInput, { Props as FieldInputProps } from './index'; 9 | 10 | export default { 11 | title: 'Design System/Controllers/Inputs', 12 | component: FieldInput, 13 | argTypes: { 14 | 15 | }, 16 | parameters: { docs: { source: { type: 'dynamic', excludeDecorators: true } } } 17 | } as Meta; 18 | 19 | // eslint-disable-next-line react/jsx-props-no-spreading 20 | const Template: ComponentStory = (args) => { 21 | const form = () => { 22 | return ( 23 |
24 | 25 | 26 | ); 27 | }; 28 | 29 | const ConnectedForm = baseConnectForm( 30 | form, 31 | () => ({ 32 | ...args 33 | }), 34 | {}, 35 | { form: 'InputField' } 36 | ); 37 | 38 | return ; 39 | }; 40 | 41 | export const InputField = Template.bind({}); 42 | InputField.args = { 43 | name: 'username', 44 | placeholder: 'username', 45 | type: 'text', 46 | label: 'Username', 47 | validate: [required, maxLength], 48 | warn: alphaNumeric 49 | } as FieldInputProps; 50 | -------------------------------------------------------------------------------- /src/common-components/controllers/FieldInput/index.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable react/jsx-props-no-spreading */ 2 | import * as React from 'react'; 3 | import { Field, BaseFieldProps, WrappedFieldProps } from 'redux-form'; 4 | import { TextField, TextFieldProps } from '@mui/material'; 5 | 6 | export type Props = { 7 | 8 | } & BaseFieldProps & TextFieldProps; 9 | 10 | class FiledInput extends React.Component { 11 | renderField(fieldData: WrappedFieldProps) { 12 | const { input, meta, ...rest } = fieldData; 13 | const { touched, error, warning } = meta; 14 | const errorMessage = touched ? (warning || error) : undefined; 15 | 16 | return ( 17 | 18 | ); 19 | } 20 | 21 | render() { 22 | return ( 23 | 27 | ); 28 | } 29 | } 30 | 31 | export default FiledInput; 32 | -------------------------------------------------------------------------------- /src/common-components/controllers/index.ts: -------------------------------------------------------------------------------- 1 | export { default as FieldInput } from './FieldInput'; 2 | -------------------------------------------------------------------------------- /src/configurations/error.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "pathToErrorCode": "data.errorCode", 3 | "handlers": { 4 | "clientConsoleError_400": { 5 | "component": "toaster", 6 | "payload": { 7 | "type": "error", 8 | "header": "errors.clientConsoleErrorHeader", 9 | "body": "errors.clientConsoleErrorBody" 10 | } 11 | }, 12 | "someErrorCode_500": { 13 | "component": "toaster", 14 | "payload": { 15 | "type": "error", 16 | "header": "errors.errorHeaderExample", 17 | "body": "errors.errorBodyExample" 18 | } 19 | }, 20 | "devicesListFailed_500": { 21 | "component": "modal", 22 | "payload": { 23 | "header": "errors.errorHeaderExample", 24 | "body": "errors.errorBodyExample" 25 | } 26 | }, 27 | "devicesListFailed_206": { 28 | "level": "component", 29 | "component": "notification", 30 | "payload": { 31 | "type": "danger", 32 | "header": "errors.specificErrorHandlerToComponentHeader", 33 | "body": "errors.specificErrorHandlerToComponentBody" 34 | } 35 | }, 36 | "devicesListFailed_400": { 37 | "component": "ignore" 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/configurations/flows.conditions.ts: -------------------------------------------------------------------------------- 1 | export { 2 | isTowSamsungInCart, 3 | isTowXiaomiInCart, 4 | someFailedCondition, 5 | someSuccessCondition 6 | } from 'actions/cart/manager'; 7 | -------------------------------------------------------------------------------- /src/configurations/spinner.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "ignoreList": [ 3 | ".*/sockjs-node/.*", 4 | ".*/v1/devices" 5 | ] 6 | } -------------------------------------------------------------------------------- /src/containers/Localization/Localization.stories.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable react/jsx-props-no-spreading */ 2 | import React from 'react'; 3 | import { baseConnect } from '@base/features/base-redux-react-connect'; 4 | import { ComponentStory, Meta } from '@storybook/react'; 5 | import { Localization, Props as LocalizationProps } from './index'; 6 | 7 | export default { 8 | title: 'Design System/Containers/Localization', 9 | component: (props: LocalizationProps) => (), 10 | argTypes: { 11 | 12 | }, 13 | parameters: { docs: { source: { type: 'dynamic', excludeDecorators: true } } } 14 | } as Meta; 15 | 16 | const Template: ComponentStory = (args: any) => { 17 | const LocalizationContainer = baseConnect( 18 | Localization, 19 | () => ({ 20 | ...args 21 | }) 22 | ); 23 | 24 | return ; 25 | }; 26 | 27 | export const Default = Template.bind({}); 28 | Default.args = { 29 | 30 | } as LocalizationProps; 31 | -------------------------------------------------------------------------------- /src/containers/Localization/index.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { baseConnect } from '@base/features/base-redux-react-connect'; 3 | 4 | export interface Props { 5 | languages: any; 6 | setActiveLanguage: (languageCode: string) => void; 7 | } 8 | 9 | export const Localization: React.FC = (props: Props) => { 10 | const { languages, setActiveLanguage } = props; 11 | 12 | return ( 13 |
14 | Language: 15 | 26 |
27 | ); 28 | }; 29 | 30 | export default baseConnect( 31 | Localization, 32 | (/* state */) => ({}), 33 | {} 34 | ); 35 | -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import * as ReactDOM from 'react-dom'; 3 | import { PersistGate } from 'redux-persist/lib/integration/react'; 4 | import { Router } from 'react-router-dom'; 5 | import { Provider } from 'react-redux'; 6 | import { LocalizeProvider } from 'react-localize-redux'; 7 | import { ToastProvider } from 'react-toast-notifications'; 8 | 9 | /* -------- Load Styles --------- */ 10 | import 'bootstrap/dist/css/bootstrap.min.css'; // Can be replace with other style framework 11 | import 'public/sass/style.scss'; 12 | 13 | /* -------- Harmony Features Bootstrap --------- */ 14 | import { Store, persistor, history } from 'base/features'; 15 | import { MediaContextProvider } from 'base/features/base-render-mobile'; 16 | 17 | /* -------- Routes ---------- */ 18 | import routes from 'routes'; 19 | 20 | /* -------- render application ---------- */ 21 | ReactDOM.render( 22 | 23 | 24 | 25 | 26 | 27 | 28 | {routes} 29 | 30 | 31 | 32 | 33 | 34 | , 35 | document.getElementById('app') 36 | ); 37 | 38 | if (module.hot) { 39 | module.hot.accept((err) => { 40 | // eslint-disable-next-line no-console 41 | console.error('An error occurred while accepting new version', err); 42 | }); 43 | } 44 | -------------------------------------------------------------------------------- /src/pages/DevicesGallery/style.scss: -------------------------------------------------------------------------------- 1 | .footer-button-row { 2 | position: fixed; 3 | bottom: 30px; 4 | right: 50px; 5 | } 6 | 7 | .footer-buttons { 8 | margin-left: 20px; 9 | } 10 | -------------------------------------------------------------------------------- /src/pages/ErrorPage/ErrorPage.stories.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable react/jsx-props-no-spreading */ 2 | import React from 'react'; 3 | import { baseConnect } from '@base/features/base-redux-react-connect'; 4 | import { ComponentStory, Meta } from '@storybook/react'; 5 | import { ErrorPage, Props as ErrorPageProps } from './index'; 6 | 7 | export default { 8 | title: 'Design System/Containers/ErrorPage', 9 | component: (props: ErrorPageProps) => (), 10 | argTypes: { 11 | 12 | }, 13 | parameters: { docs: { source: { type: 'dynamic', excludeDecorators: true } } } 14 | } as Meta; 15 | 16 | const Template: ComponentStory = (args) => { 17 | const ErrorPageContainer = baseConnect( 18 | ErrorPage, 19 | () => ({ 20 | ...args 21 | }) 22 | ); 23 | 24 | return ; 25 | }; 26 | 27 | export const Default = Template.bind({}); 28 | Default.args = { 29 | 30 | } as ErrorPageProps; 31 | -------------------------------------------------------------------------------- /src/pages/ErrorPage/index.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { LocalizeContextProps } from 'react-localize-redux'; 3 | import { baseConnect } from '@base/features/base-redux-react-connect'; 4 | 5 | export type Props = { 6 | 7 | }; 8 | 9 | interface OwnProps extends Props, LocalizeContextProps { 10 | 11 | } 12 | 13 | export class ErrorPage extends React.Component { 14 | render() { 15 | return ( 16 |
17 |

Design Your Error Page Here

18 |
19 | ); 20 | } 21 | } 22 | 23 | export default baseConnect( 24 | ErrorPage, 25 | () => { 26 | return { 27 | 28 | }; 29 | }, 30 | { 31 | 32 | } 33 | ); 34 | -------------------------------------------------------------------------------- /src/public/assets/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/src/public/assets/images/favicon.ico -------------------------------------------------------------------------------- /src/public/assets/images/generic-mobile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/src/public/assets/images/generic-mobile.jpg -------------------------------------------------------------------------------- /src/public/assets/images/harmony-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/src/public/assets/images/harmony-logo.png -------------------------------------------------------------------------------- /src/public/config/flow-manager/sub.flows.config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "flowName": "onlyRunInCHQExqmple", 4 | "runInFlowTypes": ["CHQ"], 5 | "conditions": [ 6 | { 7 | "conditionName": "someFailedCondition", 8 | "onCheck": "someFailedCondition", 9 | "mandatory": false 10 | } 11 | ] 12 | }, 13 | { 14 | "flowName": "onlyDeviceFlow", 15 | "runInFlowTypes": ["COP", "CHQ"], 16 | "color": "#416071", 17 | "conditions": [ 18 | { 19 | "conditionName": "someSuccessCondition", 20 | "onCheck": "someSuccessCondition" 21 | } 22 | ] 23 | }, 24 | { 25 | "flowName": "towSamsungFlow", 26 | "runInFlowTypes": ["COP"], 27 | "color": "#01bf6e", 28 | "conditions": [ 29 | { 30 | "conditionName": "isTowSamsungInCart", 31 | "onCheck": "isTowSamsungInCart" 32 | }, 33 | { 34 | "conditionName": "someFailedCondition", 35 | "onCheck": "someFailedCondition", 36 | "mandatory": false 37 | } 38 | ] 39 | }, 40 | { 41 | "flowName": "towXiaomiFlow", 42 | "runInFlowTypes": ["COP"], 43 | "color": "#FF5546", 44 | "conditions": [ 45 | { 46 | "conditionName": "isTowXiaomiInCart", 47 | "onCheck": "isTowXiaomiInCart" 48 | } 49 | ] 50 | } 51 | ] 52 | -------------------------------------------------------------------------------- /src/public/sass/style.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harmony-framework/harmony-boilerplate/f40c0d7d92d92506cf471f1e85c7090a1e953154/src/public/sass/style.scss -------------------------------------------------------------------------------- /src/requests/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Here you add all the apis urls defenition 3 | */ 4 | 5 | import request from '@base/features/base-api'; 6 | import { AxiosResponse } from 'axios'; 7 | import { config } from 'config'; 8 | 9 | export interface Api { 10 | getDevices: () => Promise; 11 | } 12 | 13 | export const createApi = (baseURL = config.ROOT_SERVER_URL): Api => ({ 14 | getDevices: () => request.call({ 15 | baseURL: 'http://6ew7g.mocklab.io/' || baseURL, 16 | method: 'get', 17 | url: '/getlatestWithCustomResponseCode' 18 | }) 19 | }); 20 | 21 | export default createApi(); 22 | -------------------------------------------------------------------------------- /src/requests/mock-service-worker/apis.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/camelcase */ 2 | /* eslint-disable import/no-extraneous-dependencies */ 3 | import { rest } from 'msw'; 4 | import get_latestDevicesWithCustomResponseCodeResponse from './responses/devices/get_latestDevicesWithCustomResponseCode.json'; 5 | import { API_TYPES } from './interface'; 6 | 7 | const get_latestDevicesWithCustomResponseCode = rest.get('*/getlatestWithCustomResponseCode', (req, res, ctx) => { 8 | return res( 9 | ctx.status(200), 10 | ctx.json(get_latestDevicesWithCustomResponseCodeResponse), 11 | ); 12 | }); 13 | 14 | const handlersMap: { [key in API_TYPES]: any} = { 15 | get_latestDevicesWithCustomResponseCode, 16 | }; 17 | 18 | export default handlersMap; 19 | -------------------------------------------------------------------------------- /src/requests/mock-service-worker/blackList.ts: -------------------------------------------------------------------------------- 1 | 2 | import { API_TYPES } from './interface'; 3 | 4 | const handlerBlackListIds: API_TYPES[] = [ 5 | API_TYPES.GET_LATEST_DEVICES_WITH_CUSTOM_RESPONSE_CODE 6 | ]; 7 | export default handlerBlackListIds; 8 | 9 | -------------------------------------------------------------------------------- /src/requests/mock-service-worker/handlers.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/camelcase */ 2 | /* eslint-disable import/no-extraneous-dependencies */ 3 | import { config } from 'config'; 4 | import BLACK_LIST_IDs from './blackList'; 5 | import WHITE_LIST_IDs from './whiteList'; 6 | import HANDLER_MAP from './apis'; 7 | import { API_TYPES, MOCK_TYPES } from './interface'; 8 | 9 | const handlerMap = HANDLER_MAP; 10 | const mockType = config.MOCK_TYPE; 11 | 12 | const handlerIds: string[] = Object.keys(handlerMap); 13 | 14 | const handlerBlackListIds: API_TYPES[] = BLACK_LIST_IDs; 15 | const handlersWhiteListIds: API_TYPES[] = WHITE_LIST_IDs; 16 | 17 | const getHandlerList = (type: MOCK_TYPES = MOCK_TYPES.ALL) => { 18 | let handlerFunctions: Array = []; 19 | if (type === 'all_list') { 20 | handlerFunctions = Object.values(handlerMap); 21 | } if (type === 'white_list') { 22 | handlersWhiteListIds.forEach((handlerId) => { 23 | handlerFunctions.push(handlerMap[handlerId]); 24 | }); 25 | } if (type === 'black_list') { 26 | handlerIds.forEach((handlerId: API_TYPES) => { 27 | if (!handlerBlackListIds.includes(handlerId)) { 28 | handlerFunctions.push(handlerMap[handlerId]); 29 | } 30 | }); 31 | } 32 | return handlerFunctions; 33 | }; 34 | 35 | const handlerList = getHandlerList(mockType); 36 | 37 | export const handlers = [ 38 | ...handlerList 39 | ]; 40 | -------------------------------------------------------------------------------- /src/requests/mock-service-worker/interface.ts: -------------------------------------------------------------------------------- 1 | enum API_TYPES { 2 | GET_LATEST_DEVICES_WITH_CUSTOM_RESPONSE_CODE = 'get_latestDevicesWithCustomResponseCode', 3 | } 4 | 5 | enum MOCK_TYPES { 6 | ALL = 'all_list', 7 | BLACK_LIST = 'black_list', 8 | WHITE_LIST = 'white_list' 9 | } 10 | 11 | export { API_TYPES, MOCK_TYPES }; 12 | -------------------------------------------------------------------------------- /src/requests/mock-service-worker/whiteList.ts: -------------------------------------------------------------------------------- 1 | import { API_TYPES } from './interface'; 2 | 3 | const handlersWhiteListIds: API_TYPES[] = [ 4 | API_TYPES.GET_LATEST_DEVICES_WITH_CUSTOM_RESPONSE_CODE 5 | ]; 6 | export default handlersWhiteListIds; 7 | 8 | -------------------------------------------------------------------------------- /src/routes/PageContainer.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { baseConnect } from '@base/features/base-redux-react-connect'; 3 | import { CustomRoute } from '@base/features/base-decorator'; 4 | import { setCurrentStep } from 'actions/flowManager/manager'; 5 | import { Container } from '@mui/material'; 6 | 7 | const routeDecorator = (WrappedComponent: any, step?: string) => { 8 | class PageContainer extends React.Component { 9 | componentDidMount() { 10 | if (step) { 11 | setCurrentStep(step); 12 | } else { 13 | setCurrentStep('OUT_FROM_FLOW'); 14 | } 15 | } 16 | 17 | render() { 18 | return ( 19 | 20 | {/* eslint-disable-next-line react/jsx-props-no-spreading */} 21 | 22 | 23 | ); 24 | } 25 | } 26 | 27 | return baseConnect( 28 | PageContainer, 29 | (/* state: any */) => ({}), 30 | {} 31 | ); 32 | }; 33 | 34 | export default CustomRoute(routeDecorator); 35 | -------------------------------------------------------------------------------- /src/routes/RoutesPath.ts: -------------------------------------------------------------------------------- 1 | enum RoutesPath { 2 | ROOT = '/', 3 | CHECKOUT = '/checkout', 4 | FORM_EXAMPLE = '/form-example', 5 | CHECKOUT_SAMSUNG = '/checkout-samsung', 6 | CHECKOUT_XIAOMI = '/checkout-xiaomi', 7 | ERROR_PAGE = '/error-page' 8 | } 9 | 10 | export default RoutesPath; 11 | -------------------------------------------------------------------------------- /src/routes/index.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Switch } from 'react-router-dom'; 3 | import FlowManagerConfig from 'public/config/flow-manager/types.json'; 4 | import Route from './PageContainer'; 5 | 6 | /* -------------- Pages --------------- */ 7 | import App from '../App'; 8 | import ErrorPage from 'pages/ErrorPage'; 9 | import DeviceGalleryPage from 'pages/DevicesGallery'; 10 | import Checkout from 'pages/Checkout'; 11 | import FormExample from 'pages/FormExample'; 12 | 13 | /* -------------- Routes Paths --------------- */ 14 | import RoutesPath from './RoutesPath'; 15 | 16 | const { stepTypes } = FlowManagerConfig; 17 | 18 | export default ( 19 | 20 | 21 | 22 | } 26 | /> 27 |

Checkout for Samsung

} 32 | /> 33 |

Checkout for Xiaomi

} 38 | /> 39 | } /> 40 | 41 |
42 |
43 | ); 44 | -------------------------------------------------------------------------------- /src/stories/assets/code-brackets.svg: -------------------------------------------------------------------------------- 1 | illustration/code-brackets -------------------------------------------------------------------------------- /src/stories/assets/comments.svg: -------------------------------------------------------------------------------- 1 | illustration/comments -------------------------------------------------------------------------------- /src/stories/assets/direction.svg: -------------------------------------------------------------------------------- 1 | illustration/direction -------------------------------------------------------------------------------- /src/stories/assets/flow.svg: -------------------------------------------------------------------------------- 1 | illustration/flow -------------------------------------------------------------------------------- /src/translation/index.ts: -------------------------------------------------------------------------------- 1 | import * as _ from 'lodash'; 2 | import { NamedLanguage } from 'react-localize-redux'; 3 | import en from './json/en.json'; 4 | import fr from './json/fr.json'; 5 | 6 | export const languageTypes: string[] | NamedLanguage[] = ['en', 'fr']; 7 | 8 | const mapTranslations = () => { 9 | const translations = {}; 10 | _.keys(en).forEach((key: string) => { 11 | translations[key] = {}; 12 | _.each(_.keys(en[key]), (innerKey: string) => { 13 | translations[key][innerKey] = [ 14 | en[key][innerKey], 15 | fr[key][innerKey] 16 | ]; 17 | }); 18 | }); 19 | return translations; 20 | }; 21 | 22 | export const translations = mapTranslations(); 23 | 24 | -------------------------------------------------------------------------------- /src/translation/json/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "deviceGallery": { 3 | "pageTitle": "Device Gallery", 4 | "addToCartButton": "Add to Cart", 5 | "removeFromCartButton": "Remove", 6 | "priceTitle": "Price", 7 | "clearCartButton": "Clear Cart", 8 | "checkoutButton": "Checkout" 9 | }, 10 | "checkout": { 11 | "pageTitle": "Checkout", 12 | "totalPriceTitle": "Total Price" 13 | }, 14 | "errors": { 15 | "clientConsoleErrorHeader": "Console Error", 16 | "clientConsoleErrorBody": "There is Console Error on the client side, please check the console errors for more information.", 17 | "specificErrorHandlerToComponentHeader": "Component with Error", 18 | "specificErrorHandlerToComponentBody": "This is handled by error handler with component", 19 | "errorHeaderExample": "Error", 20 | "errorBodyExample": "Error Body Example" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/translation/json/fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "deviceGallery": { 3 | "pageTitle": "Galerie D'appareils", 4 | "addToCartButton": "Ajouter au Chariot", 5 | "removeFromCartButton": "Retirer", 6 | "priceTitle": "Prix", 7 | "clearCartButton": "Vider le Panier", 8 | "checkoutButton": "Check-out" 9 | }, 10 | "checkout": { 11 | "pageTitle": "Check-out", 12 | "totalPriceTitle": "Prix Total" 13 | }, 14 | "errors": { 15 | "clientConsoleErrorHeader": "Console Error", 16 | "clientConsoleErrorBody": "There is Console Error on the client side, please check the console errors for more information.", 17 | "specificErrorHandlerToComponentHeader": "Component with Error", 18 | "specificErrorHandlerToComponentBody": "This is handled by error handler with component", 19 | "errorHeaderExample": "Error", 20 | "errorBodyExample": "Error Body Example" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/utils/validations.ts: -------------------------------------------------------------------------------- 1 | export const required = (value: any) => (value || typeof value === 'number' ? undefined : 'Required'); 2 | 3 | export const maxLength = (value: any) => (value && value.length > 15 ? `Must be ${15} characters or less` : undefined); 4 | 5 | export const email = (value: any) => (value && !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(value) 6 | ? 'Invalid email address' 7 | : undefined 8 | ); 9 | 10 | export const alphaNumeric = (value: any) => (value && /[^a-zA-Z0-9 ]/i.test(value) 11 | ? 'Only alphanumeric characters' 12 | : undefined 13 | ); 14 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist/", 4 | "module": "esnext", 5 | "moduleResolution": "node", 6 | "baseUrl": "./src", 7 | "paths": { 8 | "@base/*": ["base/*"] 9 | }, 10 | "target": "es5", 11 | "lib": ["es5", "es6", "es7", "es2017", "dom", "esnext.asynciterable"], 12 | "jsx": "react", 13 | "sourceMap": true, 14 | "allowJs": false, 15 | "forceConsistentCasingInFileNames": true, 16 | "noImplicitReturns": true, 17 | "noImplicitThis": true, 18 | "noImplicitAny": true, 19 | "strictNullChecks": true, 20 | "suppressImplicitAnyIndexErrors": true, 21 | "noUnusedLocals": true, 22 | "declaration": true, 23 | "allowSyntheticDefaultImports": true, 24 | "experimentalDecorators": true, 25 | "resolveJsonModule": true, 26 | "esModuleInterop": true 27 | }, 28 | "include": [ 29 | "files", 30 | "src/", 31 | "index.d.ts", 32 | "test/" 33 | ], 34 | "exclude": ["node_modules", "generator", "dist"] 35 | } 36 | --------------------------------------------------------------------------------